revision:
(Click to paint or erase. Left mouse button for multi-tile action)
<div class="squares-bg"> <div class="header flyItIn"> <h3>pixel art maker</h3> </div> <div class="gridContainer"> <div class="gridControl"> <h4>Choose grid size</h4> <form id="sizePicker" name="gridSize"> <span class="gridSizeLabel">grid height:</span><span id="gridHeightDisplay"> 15</span> <input type="range" id="inputHeight" class="slider" title="Set grid height" name="height" min="1" max= "50" value="15"> <br> <span class="gridSizeLabel">grid width:</span><span id="gridWidthDisplay"> 15</span> <input type="range" id="inputWidth" class="slider" title="Set grid width" name="width" min="1" max="50" value="15"> <br> <div class="gridCreateClear"> <input class="button" type="submit" id="createGrid" value="Create grid" name="submitGrid" title="Makes a grid of tiles using the values above"> <button class="button" type="button" id="clearGrid" value="Clear" title="Clears the colors from the grid so you can start over"> Clear </button> </div> </form> <h4>Pick a color: </h4> <input type="color" id="colorPicker" value="#ff0000" title="Set PAINT color"> <br> <h4>Mode: </h4><span id="modeDisplay" class="paintOrErase"> PAINT</span> <br> <div id="mode"> <button id="paintBtn" class="button paint" title="Set mode to PAINT" type="button"> <i class="fas fa-paint-brush paint"></i> </button> <button id="eraseBtn" class="button erase" title="Set mode to ERASE" type="button"> <i class="fas fa-eraser erase"></i> </button> </div> <!--end mode div: for mode button listener --> </div> <!-- end gridControl --> <div id="gridCanvas" class="gridCanvas rotationTime"> <h4>Design Canvas</h4> <table id="pixelCanvas" class="flyItIn2"></table> <p id ="legend" class="noLegend"><em>(Click to paint or erase. Left mouse button for multi-tile action)</em></p> </div> <!-- end gridCanvas --> </div> <!-- end cssGirdcontainer --> </div> <style> .squares-bg { width: 100%; height: 100%; color: white;} .squares-bg::before, .squares-bg::after {content: ""; width: 100%; height: 100%; position: relative; top: 0; left: 0; pointer-events: none; z-index: -1;} .squares-bg::before {background-image: linear-gradient(black 50%, transparent 50%), linear-gradient(to right, grey 50%, black 50%); background-size: 2vw 2vw;} .squares-bg::after {background-image: linear-gradient(black, transparent);} /* The grid classes are used for css grid layout.*/ .gridContainer { display:grid; grid-template-areas: 'control canvas'; grid-template-columns: minmax(22vw, 22vw) minmax(50vw, 1fr); grid-template-rows: auto; grid-gap: 1vw;} .gridControl {grid-area: control; height: 30vw; background: rgba(105, 105, 105, 0.85); border-radius: 0.7vw; margin: 0 1.5vw 2vw 1.5vw; box-shadow: 0.2vw 0.2vw 0.5vw rgba(77, 77, 77, 0.8);} .gridCanvas {grid-area: canvas; background: rgba(105, 105, 105, 0.85); border-radius: 0.7vw; margin: 0 1.5vw 2vw 1.5vw; box-shadow: 0.2vw 0.2vw 0.5vw rgba(77, 77, 77, 0.8);} h3 {font-family: 'Press Start 2P';font-size: 2vw; color: dimgrey; padding-top:1vw; text-shadow: 0.2vw 0.2vw 0.5vw red; margin: 0.5vw 0 0.75vw 0;} h4 {margin: 0.5vw 0 0.5vw;} h4:nth-of-type(2) {display: inline;} h4:nth-of-type(3) {display: inline; } table, tr, td {border: 0.1vw solid black; cursor: pointer;} table { border-collapse: collapse; background-color: white; margin: 0 auto; box-shadow: .2vw .2vw .4vw red;} tr {height: 2vw;} td {width: 2vw;} p {margin: 1vw 0 1vw; } .noLegend { display: none;} .legend {display: block;} .gridSizeLabel {font-size: 1.2vw;} .button {display: inline-block;margin-top: 0.5vw; padding: 0.7vw 2vw; background: transparent; font-size: 1.1vw; cursor: pointer; text-align: center; text-shadow: 0.2vw .2vw .4vw #000000; outline: none; color: white; background-color: grey; border: none; border-radius: .5vw; box-shadow: 0 .3vw red;} .button:hover {background-color: dimgrey;} .button:active { background-color: dimgrey; box-shadow: 0 .3vw lightcoral; transform: translateY(0.3vw);} #createGrid, #paintBtn { margin-right: 0.6vw;} input[type=color] { margin: 1.5vw 0 1vw 0.25vw; border: 0.1vw solid darkgray; background-color: grey; cursor: pointer;} /* Range input thumb and track styling: browser specific */ input[type=range] {-webkit-appearance: none; width: 95%; margin: 1.6vw 0; padding: 0;} input[type=range]:focus {outline: none;} input[type=range]::-webkit-slider-runnable-track {width: 100%; height: 1vw; cursor: pointer; animate: 0.2s; box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d; background: red; border-radius: .2vw; border: 0.05vw solid #010101;} input[type=range]::-webkit-slider-thumb {box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d; border: .1vw solid black; height: 2vw; width: 0.7vw; border-radius: 0.3vw; background: grey; cursor: pointer; -webkit-appearance: none; margin-top: -0.6vw;} input[type=range]:hover::-webkit-slider-thumb {background: dimgrey;} input[type=range]:focus::-webkit-slider-runnable-track { background: red;} input[type=range]::-moz-range-track { width: 95%; height: 1vw; cursor: pointer; animate: 0.2s; box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d; background: red; border-radius: 0.1vw; border: 0.02vw solid #010101;} input[type=range]::-moz-range-thumb {box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d; border: .1vw solid black; height: 2vw; width: 0.7vw; border-radius: 0.3vw; background: grey; cursor: pointer;} input[type=range]:hover::-moz-range-thumb {background: dimgrey;} input[type=range]::-ms-track {width: 100%; height: 1vw; cursor: pointer; animate: 0.2s; background: transparent; border-color: transparent; border-width: 1vw; color: transparent; margin: -0.4vw;} input[type=range]::-ms-fill-lower {background: red; border: 0.02vw solid #010101; border-radius: 0.26vw; box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d;} input[type=range]::-ms-fill-upper {background: red; border: 0.02vw solid #010101; border-radius: 0.26vw; box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d;} input[type=range]::-ms-thumb {box-shadow: .1vw .1vw .1vw black, 0vw 0vw .1vw #0d0d0d; border: .1vw solid black; height: 2vw; width: 0.7vw; border-radius: 0.3vw; background: grey; cursor: pointer; margin: 0;} input[type=range]:focus::-ms-fill-lower {background: red;} input[type=range]::-ms-tooltip {display: none;} input[type=range]:focus::-ms-fill-upper {background: red;} input[type=range]:hover::-ms-thumb {background: dimgrey;} /* text fly in effect */ .flyItIn {animation: flyin 1s ease forwards; opacity: 0; transform: scale(2);filter: blur(0.4vw); } @keyframes flyin { to { filter: blur(0); transform: scale(1); opacity: 1;} } .flyItIn2 {animation: flyin2 1s ease forwards; opacity: 0;transform: scale(2); filter: blur(0.4vw);} @keyframes flyin2 { to {filter: blur(0); transform: scale(1); opacity: 1;} } /* rotates the Design Canvas div */ .rotationTime {-webkit-transition: all 4s linear; -moz-transition: all 4s linear; -ms-transition: all 4s linear; -o-transition: all 4s linear; transition: all 4s linear;} .rotateCanvas { -webkit-transform: rotateX(360deg) rotateY(360deg); -moz-transform: rotateX(360deg) rotateY(360deg); -ms-transform: rotateX(360deg) rotateY(360deg); -o-transform: rotateX(360deg) rotateY(360deg); transform: rotateX(360deg) rotateY(360deg); } /* make adjustments for smaller devices */ @media (max-width: 700px) { .gridContainer {grid-template-areas:'control' 'canvas'; grid-template-columns: 1fr;} .squares-bg::before {background-size: 2vw 2vw;} h3 {font-size: 1vw;} .gridControl {margin: 0 1vw 1.5vw 1vw;} .gridCanvas {margin: 0 1vw 1.5vw 1vw;} } </style> <script> // Create a grid that a user can color with clicks - allows grid size entry and color selection // When size is submitted by the user, call makeGrid() // Set the inital 'paint' changes happen in click event const PAINT = 'PAINT'; const ERASE = 'ERASE'; const theGridSize = document.forms.gridSize; const userColor = document.getElementById('colorPicker'); const tileMode = document.getElementById('modeDisplay'); const displayHeight = document.getElementById('gridHeightDisplay'); const displayWidth = document.getElementById('gridWidthDisplay'); const userHeight = document.getElementById('inputHeight'); const userWidth = document.getElementById('inputWidth'); const grid = document.getElementById('pixelCanvas'); const gridCanvas = document.getElementById('gridCanvas'); let gridTileMode = PAINT; theGridSize.submitGrid.onclick = function makeGrid(event) { event.preventDefault(); let mouseIsDown = false; const rows = userHeight.value; const columns = userWidth.value; while (grid.hasChildNodes()) { grid.removeChild(grid.lastChild); } //Build the grid row by row and then append to the table - project rubrics requires use of for and while loops let tableRows = ''; let r = 1; while (r <= rows) { tableRows += '<tr>'; for (let c=1; c <= columns; c++) { tableRows += '<td></td>'; } tableRows += '</tr>'; r += 1; } grid.insertAdjacentHTML('afterbegin', tableRows); document.getElementById('legend').className = "legend"; grid.classList.toggle('flyItIn'); grid.classList.toggle('flyItIn2'); grid.addEventListener("click", function(event) { event.preventDefault(); paintEraseTiles(event.target); }); grid.addEventListener('mousedown', function(event) { event.preventDefault(); mouseIsDown = event.which === 1 ? true : false; }); document.addEventListener('mouseup', function(event) { event.preventDefault(); mouseIsDown = false; }); grid.addEventListener('mouseover', function(event) { event.preventDefault(); if (mouseIsDown) {paintEraseTiles(event.target);} }); }; function paintEraseTiles(targetCell) { if (targetCell.nodeName === 'TD') { targetCell.style.backgroundColor = gridTileMode === PAINT ? userColor.value : 'transparent'; } else { console.log("Nice try: " + targetCell.nodeName + " talk to the hand!"); } } theGridSize.height.oninput = function (){ displayHeight.innerHTML = ' ' + theGridSize.height.value; }; theGridSize.width.oninput = function (){ displayWidth.innerHTML = ' ' + theGridSize.width.value; // }); }; userColor.oninput = function (event){ gridTileMode = PAINT; tileMode.innerHTML = ' ' + gridTileMode; }; document.getElementById('clearGrid').addEventListener('click', function() { gridCanvas.classList.toggle('rotateCanvas'); // rotate the Design Canvas div let tiles = grid.getElementsByTagName('td'); // grid.children().children().removeAttr("style"); for(let i = 0; i <= tiles.length; i++) { tiles[i].style.backgroundColor = 'transparent'; } }); document.getElementById('mode').addEventListener('click', function(event) { gridTileMode = event.target.className.indexOf('paint') >=0 ? PAINT : ERASE; // $('.paintOrErase').text(' ' + gridTileMode); tileMode.innerHTML = ' ' + gridTileMode; }); </script>