+ MTG Gamepedia
+ Magic Set Editor
+ Changes have been made to some of the images. Card Conjurer is not endorsed by these sources. +
diff --git a/new/data/site/other/life/NoSleep.js b/new/data/site/other/life/NoSleep.js new file mode 100644 index 00000000..9453d5fe --- /dev/null +++ b/new/data/site/other/life/NoSleep.js @@ -0,0 +1,192 @@ +/*! NoSleep.js v0.9.0 - git.io/vfn01 - Rich Tibbett - MIT license */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["NoSleep"] = factory(); + else + root["NoSleep"] = factory(); + })(typeof self !== 'undefined' ? self : this, function() { + return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var _require = __webpack_require__(1), + webm = _require.webm, + mp4 = _require.mp4; + + // Detect iOS browsers < version 10 + + + var oldIOS = typeof navigator !== 'undefined' && parseFloat(('' + (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec(navigator.userAgent) || [0, ''])[1]).replace('undefined', '3_2').replace('_', '.').replace('_', '')) < 10 && !window.MSStream; + + var NoSleep = function () { + function NoSleep() { + var _this = this; + + _classCallCheck(this, NoSleep); + + if (oldIOS) { + this.noSleepTimer = null; + } else { + // Set up no sleep video element + this.noSleepVideo = document.createElement('video'); + + this.noSleepVideo.setAttribute('muted', ''); + this.noSleepVideo.setAttribute('title', 'No Sleep'); + this.noSleepVideo.setAttribute('playsinline', ''); + + this._addSourceToVideo(this.noSleepVideo, 'webm', webm); + this._addSourceToVideo(this.noSleepVideo, 'mp4', mp4); + + this.noSleepVideo.addEventListener('loadedmetadata', function () { + if (_this.noSleepVideo.duration <= 1) { + // webm source + _this.noSleepVideo.setAttribute('loop', ''); + } else { + // mp4 source + _this.noSleepVideo.addEventListener('timeupdate', function () { + if (_this.noSleepVideo.currentTime > 0.5) { + _this.noSleepVideo.currentTime = Math.random(); + } + }); + } + }); + } + } + + _createClass(NoSleep, [{ + key: '_addSourceToVideo', + value: function _addSourceToVideo(element, type, dataURI) { + var source = document.createElement('source'); + source.src = dataURI; + source.type = 'video/' + type; + element.appendChild(source); + } + }, { + key: 'enable', + value: function enable() { + if (oldIOS) { + this.disable(); + console.warn('\n NoSleep enabled for older iOS devices. This can interrupt\n active or long-running network requests from completing successfully.\n See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n '); + this.noSleepTimer = window.setInterval(function () { + if (!document.hidden) { + window.location.href = window.location.href.split('#')[0]; + window.setTimeout(window.stop, 0); + } + }, 15000); + } else { + this.noSleepVideo.play(); + } + } + }, { + key: 'disable', + value: function disable() { + if (oldIOS) { + if (this.noSleepTimer) { + console.warn('\n NoSleep now disabled for older iOS devices.\n '); + window.clearInterval(this.noSleepTimer); + this.noSleepTimer = null; + } + } else { + this.noSleepVideo.pause(); + } + } + }]); + + return NoSleep; + }(); + + ; + + module.exports = NoSleep; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + + "use strict"; + + + module.exports = { + webm: 'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA=', + mp4: 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQAD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' + }; + +/***/ }) +/******/ ]); + }); diff --git a/new/data/site/other/life/life.js b/new/data/site/other/life/life.js new file mode 100644 index 00000000..8f6e9fb5 --- /dev/null +++ b/new/data/site/other/life/life.js @@ -0,0 +1,332 @@ +//============================================// +// Card Conjurer, by Kyle Burton // +//============================================// +//define variables +var playerCount, startingLifeTotal, firstPlayerWide = false, lastPlayerWide = false, playerList = [], rowHeight = 0, columnWidth = 0, rowCount = 0, isFullscreen = true, mouseClickId = 0, noSleep = new NoSleep(), canEnableNoSleep = false +//Setup the enabler for no sleep +document.addEventListener("click", enableNoSleep, false); +function enableNoSleep() { + if (canEnableNoSleep) { + document.removeEventListener("click", enableNoSleep, false); + noSleep.enable(); + } +} +//This function sets everything up +function fullscreen() { + //Full screen! + grid = document.getElementById("gridShell") + if (grid.requestFullscreen) { + grid.requestFullscreen() + } else if (grid.mozRequestFullScreen) { + grid.mozRequestFullScreen() + } else if (grid.webkitRequestFullscreen) { + grid.webkitRequestFullscreen() + } else if (grid.msRequestFullscreen) { + grid.msRequestFullscreen() + } else { + isFullscreen = false + document.getElementById("return").classList.add("permaHidden") + document.getElementById("gridShell").classList.add("fullscreenUnavailable") + } +} +function startGame() { + canEnableNoSleep = document.getElementById("inputWakeLock").checked + fullscreen() + document.getElementById("return").classList.remove("hidden") + //hide the settings and grab player count and starting life total + document.getElementById("settings").classList.add("hidden") + playerCount = parseInt(document.getElementById("inputPlayerCount").value) + startingLifeTotal = parseInt(document.getElementById("inputStartingLife").value) + //determine the layout based on player count + if (playerCount % 2 == 0) { + if (playerCount >= 6) { + firstPlayerWide = true + lastPlayerWide = true + } + } else { + lastPlayerWide = true + } + //Make all the player boxes + for (var i = 1; i <= playerCount; i ++) { + //determine if the current box is rotated or widened + var rotation, wide = false + var orientationIndexAdjust = 0 + if (firstPlayerWide) { + orientationIndexAdjust += 1 + } + if (i == 1 && firstPlayerWide) { + rotation = 180 + } else if (i == playerCount && lastPlayerWide) { + rotation = 0 + } else if ((i + orientationIndexAdjust) % 2 == 0) { + rotation = 270 + } else { + rotation = 90 + } + if ((i == 1 && firstPlayerWide) || (i == playerCount && lastPlayerWide)) {wide = true} + playerList[i - 1] = new playerBox(i, rotation, wide) + document.getElementById("inputPlayer").innerHTML += "" + } + //Determine the grid size + if (isFullscreen) { + columnWidth = screen.width / 2 - 2 + } else { + columnWidth = window.innerWidth / 2 - 2 + } + rowCount = (playerCount - playerCount % 2) / 2 + 1 + if (playerCount == 2 || playerCount == 4) { + rowCount -= 1 + } + if (isFullscreen) { + rowHeight = screen.height / rowCount - 2 + } else { + rowHeight = window.innerHeight / rowCount - 2 + } + //Now that all the player boxes are made, they must be configured + for (var i = 1; i <= playerCount; i++) { + configurePlayerBox(i) + } + drawAllPlayerBoxes() +} +function playerBox(playerBoxID, canvasRotation, wide) { + //Actually needed vars + this.id = playerBoxID + this.rotation = canvasRotation + this.life = startingLifeTotal + this.canvas = document.createElement("canvas") + this.direction = 0 + this.holdTime = 0 + this.touchId = 0.5 + this.color = "#222222" + this.textColor = "#ffffff" + this.image = new Image() + this.image.customVarID = playerBoxID + this.image.onload = function() {drawPlayerBox(this.customVarID)} + //vars to make navigation easier + this.canvas.customVarID = playerBoxID + this.canvas.customVarContext = this.canvas.getContext("2d") + this.canvas.customVarContext.customVarCanvas = this.canvas + //css classes + this.canvas.classList.add("playerBox") + if (wide) { + this.canvas.classList.add("widePlayerBox") + } + //add it to the html + document.getElementById("mainGrid").appendChild(this.canvas) +} +function configurePlayerBox(playerBoxID) { + //All of this configures the size/shape/orientation of the player boxes + var currentPlayer = playerList[playerBoxID - 1] + var context = currentPlayer.canvas.customVarContext + currentPlayer.canvas.width = columnWidth + if (playerList[playerBoxID - 1].canvas.classList.contains("widePlayerBox")) { + currentPlayer.canvas.width = columnWidth * 2 + 2 + } + currentPlayer.canvas.height = rowHeight + context.translate(currentPlayer.canvas.width / 2, currentPlayer.canvas.height / 2) + context.rotate(Math.PI / 180 * currentPlayer.rotation) +} + +function resetLife() { + for (var i = 1; i <= playerCount; i++) { + playerList[i - 1].life = startingLifeTotal + } + document.getElementById('menu').classList.add('hidden') + drawAllPlayerBoxes() +} +function updateColorSelector() { + document.getElementById("inputPlayerColor").value = playerList[parseInt(document.getElementById("inputPlayer").value) - 1].color + document.getElementById("inputTextColor").value = playerList[parseInt(document.getElementById("inputPlayer").value) - 1].textColor +} +function updateBackgroundColor(color) { + playerList[parseInt(document.getElementById("inputPlayer").value) - 1].color = color + drawPlayerBox(parseInt(document.getElementById("inputPlayer").value)) +} +function updateTextColor(color) { + playerList[parseInt(document.getElementById("inputPlayer").value) - 1].textColor = color + drawPlayerBox(parseInt(document.getElementById("inputPlayer").value)) +} +function loadImage(event, destination) { + var input = event.target + var reader = new FileReader() + reader.onload = function() { + var dataURL = reader.result + destination.src = dataURL + } + reader.readAsDataURL(input.files[0]) +} +var savedArtList = [], cardArtUrlList = [], cardArtArtistList = [] +function inputCardArtName(cardArtNameInput) { + var xhttp = new XMLHttpRequest() + xhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + savedArtList = this.responseText.split('"art_crop":"') + savedArtList.splice(0, 1) + document.getElementById("inputCardArtNameNumber").max = savedArtList.length + document.getElementById("inputCardArtNameNumber").value = 1 + for (i = 0; i < savedArtList.length; i ++) { + cardArtUrlList[i] = savedArtList[i].split('","border_crop":')[0] + } + for (i = 0; i < savedArtList.length; i ++) { + cardArtArtistList[i] = savedArtList[i].slice(savedArtList[i].indexOf('"artist":"') + 10, savedArtList[i].indexOf('","border_color":')) + } + inputCardArtNameNumber(1) + } + } + xhttp.open("GET", "https://api.scryfall.com/cards/search?order=released&unique=art&q=name%3D" + cardArtNameInput.replace(/ /g, "_"), true) + xhttp.send() +} +function inputCardArtNameNumber(cardArtNameNumberInput) { + playerList[parseInt(document.getElementById('inputPlayer').value) - 1].image.src = cardArtUrlList[cardArtNameNumberInput - 1] +} +document.getElementById("mainGrid").addEventListener("touchmove", function(event) { + event.preventDefault() +}, false) +function rollRNG() { + document.getElementById("rngOutput").innerHTML = Math.floor(Math.random() * (parseInt(document.getElementById("inputRNGMax").value) - parseInt(document.getElementById("inputRNGMin").value) + 1) + parseInt(document.getElementById("inputRNGMin").value)) +} +function drawPlayerBox(playerBoxID) { + var currentPlayerBox = playerList[playerBoxID - 1] + var context = currentPlayerBox.canvas.customVarContext + context.textBaseline = "middle" + var tempFontSize = 100 + context.font = "100pt belerenbsc" + context.fillStyle = currentPlayerBox.color + var tempCanvasHeight = currentPlayerBox.canvas.height, tempCanvasWidth = currentPlayerBox.canvas.width + if (playerList[playerBoxID - 1].rotation == 90 || playerList[playerBoxID - 1].rotation == 270) { + tempCanvasHeight = tempCanvasWidth + tempCanvasWidth = currentPlayerBox.canvas.height + } + context.fillRect(tempCanvasWidth / -2, tempCanvasHeight / -2, tempCanvasWidth, tempCanvasHeight) + if (currentPlayerBox.image.src != "") { + var imageToDraw = currentPlayerBox.image + if (imageToDraw.width / imageToDraw.height > tempCanvasWidth / tempCanvasHeight) { + //The image is wider and should be fitted to its height + context.drawImage(imageToDraw, tempCanvasHeight / imageToDraw.height * imageToDraw.width / -2, tempCanvasHeight / -2, tempCanvasHeight / imageToDraw.height * imageToDraw.width, tempCanvasHeight) + } else { + //The image is taller and should be fitted to its width + context.drawImage(imageToDraw, tempCanvasWidth / -2, tempCanvasWidth / imageToDraw.width * imageToDraw.height / -2, tempCanvasWidth, tempCanvasWidth / imageToDraw.width * imageToDraw.height) + } + } + if (currentPlayerBox.life < 1) { + context.fillStyle = "#0008" + context.fillRect(tempCanvasWidth / -2, tempCanvasHeight / -2, tempCanvasWidth, tempCanvasHeight) + context.fillStyle = "#800" + } else { + context.fillStyle = playerList[playerBoxID - 1].textColor + } + while (context.measureText(currentPlayerBox.life).width >= tempCanvasWidth) { + tempFontSize -= 1 + context.font = tempFontSize + "pt belerenbsc" + } + var horizontalShift = -1 * parseInt(context.measureText(currentPlayerBox.life).width) / 2 + context.strokeStyle = "black" + context.lineWidth = 5 + context.strokeText(currentPlayerBox.life, horizontalShift, 0) + context.fillText(currentPlayerBox.life, horizontalShift, 0) +} +function drawAllPlayerBoxes() { + for (var i = 1; i <= playerList.length; i ++) { + drawPlayerBox(i) + } +} +//Event Listener magic! (always records mouse/touch positions so the loop can work without events) +var touchX = [], touchY = [] +document.getElementById("mainGrid").addEventListener("mousedown", startMouseCoordinates, true) +window.addEventListener("mousemove", updateMouseCoordinates, true) +window.addEventListener("mouseup", endMouseCoordinates, true) +function startMouseCoordinates() { + mouseClickId += 1 + playerList[event.target.customVarID - 1].touchId = mouseClickId + singleTap(event.target) +} +function updateMouseCoordinates() { + touchX[0] = event.clientX + touchY[0] = event.clientY} +function endMouseCoordinates() { + for (var i = 1; i <= playerList.length; i++) { + playerList[i - 1].touchId = 0.5 + } +} +window.addEventListener("touchstart", switchToTouchEvents, true) +function switchToTouchEvents() { + window.removeEventListener("touchstart", switchToTouchEvents, true) + document.getElementById("mainGrid").removeEventListener("mousedown", startMouseCoordinates, true) + window.removeEventListener("mousemove", updateMouseCoordinates, true) + window.removeEventListener("mouseup", endMouseCoordinates, true) + document.getElementById("mainGrid").addEventListener("touchstart", startTouch, true) + window.addEventListener("touchmove", moveTouch, true) + window.addEventListener("touchend", endTouch, true) +} +function startTouch() { + playerList[event.changedTouches[0].target.customVarID - 1].touchId = event.changedTouches[0].identifier + moveTouch() + singleTap(event.changedTouches[0].target) +} +function moveTouch() { + touchX = [], touchY = [] + for (var i = 0; i < event.touches.length; i ++) { + touchX[i] = event.touches[i].clientX + touchY[i] = event.touches[i].clientY + } +} +function endTouch() { + for (var i = 1; i <= playerList.length; i++) { + if (playerList[i - 1].touchId == event.changedTouches[0].identifier) { + playerList[i - 1].touchId = 0.5 + } + } + moveTouch() +} +//Tap (and click) functions +function singleTap(targetPlayerBox) { + var playerBoxBounds = targetPlayerBox.getBoundingClientRect() + var tappedPlayerBox = playerList[targetPlayerBox.customVarID - 1] + var lifeAdjust = 0 + if (tappedPlayerBox.rotation == 0 || tappedPlayerBox.rotation == 180) { + if (touchX[touchX.length - 1] > playerBoxBounds.width / 2 + playerBoxBounds.x) { + lifeAdjust = 1 + } else { + lifeAdjust = -1 + } + } else { + if (touchY[touchY.length - 1] > playerBoxBounds.height / 2 + playerBoxBounds.y) { + lifeAdjust = 1 + } else { + lifeAdjust = -1 + } + } + if (tappedPlayerBox.rotation == 180 || tappedPlayerBox.rotation == 270) { + lifeAdjust *= -1 + } + tappedPlayerBox.direction = lifeAdjust + tappedPlayerBox.life += lifeAdjust + drawPlayerBox(tappedPlayerBox.id) + setTimeout(clockCheck.bind(null, tappedPlayerBox, tappedPlayerBox.touchId), 500) +} +function clockCheck(tappedPlayerBox, lastTapID) { + if (tappedPlayerBox.touchId == lastTapID) { + tappedPlayerBox.life += tappedPlayerBox.direction + drawPlayerBox(tappedPlayerBox.id) + if (tappedPlayerBox.holdTime >= 150) { + setTimeout(clockCheck.bind(null, tappedPlayerBox, tappedPlayerBox.touchId), 10) + } else if (tappedPlayerBox.holdTime >= 50) { + setTimeout(clockCheck.bind(null, tappedPlayerBox, tappedPlayerBox.touchId), 50) + } else { + setTimeout(clockCheck.bind(null, tappedPlayerBox, tappedPlayerBox.touchId), 100) + } + tappedPlayerBox.holdTime += 1 + } else { + tappedPlayerBox.holdTime = 0 + } +} +//Hopefully stops the pesky double-tap zoom: +var doubleTouchStartTimestamp = 0 +document.getElementById("mainGrid").addEventListener("touchstart", function() { + var now = +(new Date()) + if (doubleTouchStartTimestamp + 500 > now){ + event.preventDefault() + } + doubleTouchStartTimestamp = now +}) +//Updated :D diff --git a/new/data/site/other/life/menuButton.png b/new/data/site/other/life/menuButton.png new file mode 100644 index 00000000..012267b9 Binary files /dev/null and b/new/data/site/other/life/menuButton.png differ diff --git a/new/data/site/other/life/menuExitButton.png b/new/data/site/other/life/menuExitButton.png new file mode 100644 index 00000000..707a98c2 Binary files /dev/null and b/new/data/site/other/life/menuExitButton.png differ diff --git a/new/data/site/styles.css b/new/data/site/styles.css index 507b7c2d..41a97e6f 100644 --- a/new/data/site/styles.css +++ b/new/data/site/styles.css @@ -43,8 +43,8 @@ } footer { background-color: var(--dark-color); - padding: 25pt; - font: 13pt gothammedium; + padding: 2.5em; + font: 1.3em gothammedium; color: var(--light-color); } body { @@ -61,63 +61,44 @@ html { -moz-user-select: none; -ms-user-select: none; user-select: none; + font-size: 6pt; } canvas { - width: calc(100% - 10pt); + width: calc(100%); height: auto; + max-width: 750px; + max-height: 1050px; } .canvasContainer { text-align: center; } .mainGrid { - padding: 5pt; + padding: 0.3em; display: grid; - grid-gap: 25pt; + grid-gap: 1.5em; grid-template-columns: auto; - font: 16pt mplantin; + font: 1.6em mplantin; } .imageGrid { display: grid; - grid-template-columns: auto 143pt; - min-height: 200pt; -} -.layer { - padding: 50pt; - color: black; - font: 24pt belerenbsc; - text-align: center; -} -.layer:nth-child(even) { - background-color: var(--light-color); - background-image: url(images/layerBackground.png); - background-position: center; - background-repeat: no-repeat; + grid-template-columns: auto 9em; + min-height: 12.5em; } .imgPreview { width: 100%; } -@media screen and (min-width: 306pt) { - .imgPreview { - max-width: 143pt; - max-height: 200pt; - } -} -.cardMenu > div { - /*border: 1px solid red;*/ - /*margin-bottom: 5pt;*/ -} .bar { background-image: url(../images/manaSymbols/63.png); background-position: center; background-repeat: no-repeat; background-size: 100% 2px; width: 100%; - height: 20pt; + height: 1em; } .cardMenu > div > div:nth-child(1) { /*border: 1px solid blue;*/ text-align: center; - font: 24pt belerenbsc; + font: 1.5em belerenbsc; } .twoGrid { display: grid; @@ -149,30 +130,6 @@ canvas { .input.file { padding: 0px; } -@media screen and (min-width: 994pt) { - .mainGrid { - padding: 25pt; - grid-template-columns: calc(750px + 2px) auto; - } -} -@media screen and (min-width: calc(750px + 30pt)) { - canvas { - width: 750px; - height: 1050px; - } -} -@media screen and (min-width: 1024px) { - .tooltip:hover .tooltiptext { - visibility: visible; - opacity: 1; - } -} -@media screen and (max-width: 1023px) { - .tooltip:focus .tooltiptext, div.tooltip > input:focus + .tooltiptext, div.tooltip > textarea:focus + .tooltiptext { - visibility: visible; - opacity: 1; - } -} .tooltip { position: relative; } @@ -215,10 +172,90 @@ a { a:hover { color: var(--dark-color); } +footer a { + color: white; +} +footer a:hover { + color: var(--shifting-color-1-light); +} .hidden { display: none; } .footerGrid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(0px, 1fr)); + grid-template-columns: auto; + grid-gap: 2em; +} +.layer { + padding: 2em 2em; + color: black; + font-size: 2em; + text-align: center; +} +.layer:nth-child(even) { + background-color: var(--light-color); + background-image: url(images/layerBackground.png); + background-position: center; + background-repeat: no-repeat; +} +.title { + font: 1.5em belerenbsc; +} +.pageTitle { + font: 5em belerenbsc; + text-align: center; + padding-top: 0.3em; +} +.paragraph { + font: 1em mplantin; + text-align: left; +} +.indent { + text-indent: 2em; +} +.leftMargin { + margin-left: 2em; +} + +/*Controls the area taken by the canvas*/ +@media screen and (min-width: 888pt) { + /*Makes room for the canvas and controls to be side by side*/ + .mainGrid { + padding: 1.5em; + grid-template-columns: calc(750px + 2px) auto; + } +} +@media screen and (min-width: calc(750px + 2em)) { + /*The canvas can be full size and doesn't have to scale anymore*/ + canvas { + width: 750px; + height: 1050px; + } +} +/*The screen is big enough (larger than phone, likely) to use a larger font*/ +@media screen and (min-width: 263pt) { + html { + font-size: 10pt; + } +} +/*These control tooltips for mobile devices vs. desktops/laptops*/ +@media screen and (min-width: 1024px) { + .tooltip:hover .tooltiptext { + visibility: visible; + opacity: 1; + } +} +@media screen and (max-width: 1023px) { + .tooltip:focus .tooltiptext, div.tooltip > input:focus + .tooltiptext, div.tooltip > textarea:focus + .tooltiptext { + visibility: visible; + opacity: 1; + } +} +/*The footer can now fit horizontally!*/ +@media screen and (min-width: 375pt) { + .footerGrid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(0px, 1fr)); + grid-gap: 1em; + } } \ No newline at end of file diff --git a/new/disclaimer.html b/new/disclaimer.html new file mode 100644 index 00000000..a09ec98f --- /dev/null +++ b/new/disclaimer.html @@ -0,0 +1,57 @@ + + +
+