首页 > 解决方案 > 无法让着色器功能在蚀刻草图上正常工作 - JavaScript

问题描述

我目前正在做 Odin 项目并试图让蚀刻草图工作。一直没问题,直到我遇到着色器类型的画笔..出于某种原因,它只是在左上角着色,即。我在网格中创建的第一个 div。

https://chealkin.github.io/etchasketch/etcha.html

代码如下;

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

/*  END OF RESET */

body {
  background-color: #DEDEDE;
}

#mainContainer {
  width: 720px;
  height: 720px;
  background-color: black;
  position: absolute;
  left: 50%;
  top: 50%;
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  font-size: 0;
  border: 5px #CDCDCD solid;
}
button {
  height: 36px;
  line-height: 27px;
  -moz-border-radius: 2px;
  -moz-user-select: none;
  background-color: #f2f2f2;
  border: 1px solid #f2f2f2;
  border-radius: 17px;
  color: #5F6368;
  cursor: pointer;
  font-family: arial,sans-serif;
  font-size: 14px;
  margin: 11px 4px;
  min-width: 54px;
  padding: 0 16px;
  margin-top: 25px;
  text-align: center;
  box-shadow: 0 1px 1px rgba(0,0,0,0.1);
}
button:hover {
  background-image: -moz-linear-gradient(bottom, #fff, #e8e8e8);
  background-image: -webkit-linear-gradient(bottom, #fff, #e8e8e8);
  color: #222;
  box-shadow: 0 1px 1px rgba(0,0,0,0.1);
}
#black {
  position: absolute;
  left: 30%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#shader {
  position: absolute;
  left: 36%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#rgb {
  position: absolute;
  left: 43%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#erase {
  position: absolute;
  left: 50%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#reset {
  position: absolute;
  left: 57%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Etchasketch</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>

<body>

  <button id="black">Black</button>
  <button id="rgb">Random</button>
  <button id="erase">Eraser</button>
  <button id="reset">Reset</button>
  <button id="shader">Shader</button>
  <div id="mainContainer"></div>


  <script>
    let blackBrush = document.querySelector('#black');
    let rgbBrush = document.querySelector('#rgb');
    let eraseBrush = document.querySelector('#erase');
    let resetButton = document.querySelector('#reset');
    let shaderBrush = document.querySelector('#shader');
    var currentBrush = 'rgb';

    blackBrush.addEventListener('click', () => {
      currentBrush = 'black';
    });
    rgbBrush.addEventListener('click', () => {
      currentBrush = 'rgb';
    });
    eraseBrush.addEventListener('click', () => {
      currentBrush = 'erase';
    });
    shaderBrush.addEventListener('click', () => {
      currentBrush = 'shade';
    });
    resetButton.addEventListener('click', () => {
      let x = prompt('How many sections would you like in each row?')
      resetGrid(x);
    })

    function createGrid(number) {
      //      size = (size < 4) ? 4 : (size > 64) ? 64 : size;
      let gridSize = number;

      for (let i = 0; i < gridSize ** 2; i++) {
        const container = document.querySelector('#mainContainer');
        const row = document.createElement('div');
        container.appendChild(row);
        row.id = 'grids';
        row.style.backgroundColor = 'white';
        row.style.opacity = '1';
        row.style.width = getSize(gridSize);
        row.style.height = getSize(gridSize);
        row.verticalAlign = 'top';
        row.style.display = 'inline-block';
        row.onmouseover = function() {
          return row.style.backgroundColor = getColor();
        };
      }

    }

    function getSize(x) {
      let size = (720 / parseInt(x));
      return size + 'px';
    }

    function resetGrid(x) {
      let container = document.getElementById('mainContainer');
      while (container.firstChild) {
        container.removeChild(container.firstChild);
      }
      createGrid(x);
    }

    function getColor() {
      if (currentBrush === 'black') {
        return 'black';
      } else if (currentBrush === 'rgb') {
        return randomBrush();
      } else if (currentBrush === 'erase') {
        return 'white';
      } else if (currentBrush === 'shade') {
        getShade();
      }
    }

    function getShade() {
      var row = document.querySelector('#grids');
      if (row.style.backgroundColor === 'black') {
        return;
      } else if (row.style.opacity === 0) {
        row.style.backgroundColor === 'black';
      } else {
        row.style.opacity -= 0.1;
      }
    }

    function randomBrush() {
      var r = Math.floor((Math.random() * 255));
      var g = Math.floor((Math.random() * 255));
      var b = Math.floor((Math.random() * 255));
      return 'rgb(' + r + ', ' + g + ', ' + b + ')';
    }

    createGrid(16);
  </script>
</body>

</html>

如果有人可以帮助指出我做错了什么,将不胜感激!TIA

标签: javascriptcss

解决方案


不幸的是,您的代码在片段中表现不佳,(当然,除非您使用片段全屏显示)但关键是您的所有“像素”都具有相同的 ID,因此document.querySelector('#grids')总是指第一个

相反,将鼠标悬停在事件目标上的元素传递给代码

代替

row.onmouseover = function() {
    row.style.backgroundColor = getColor();
} 

利用

row.addEventListener('mouseover', function(e) {
    row.style.backgroundColor = getColor(e.target);
});

然后 in getColor,接受一个参数传递给getShade

  function getColor(grid) {
     ....
      } else if (currentBrush === 'shade') {
        getShade(grid);
      }
  }

然后getShade用作row参数名称,并使用它

  function getShade(row) {
      ....
  }

let blackBrush = document.querySelector ('#black');
      let rgbBrush = document.querySelector ('#rgb');
      let eraseBrush = document.querySelector ('#erase');
      let resetButton = document.querySelector ('#reset');
      let shaderBrush = document.querySelector ('#shader');
      var currentBrush = 'rgb';

      blackBrush.addEventListener('click', () => { currentBrush = 'black'; });
      rgbBrush.addEventListener('click', () => { currentBrush = 'rgb'; });
      eraseBrush.addEventListener('click', () => { currentBrush = 'erase'; });
      shaderBrush.addEventListener('click', () => { currentBrush = 'shade'; });
      resetButton.addEventListener('click', () => {
        let x = prompt('How many sections would you like in each row?')
        resetGrid(x);
      })
      
      function createGrid(number) {
//      size = (size < 4) ? 4 : (size > 64) ? 64 : size;
        let gridSize = number;
        
        for (let i = 0; i < gridSize ** 2; i++) {
          const container = document.querySelector('#mainContainer');
          const row = document.createElement('div');
          container.appendChild(row);
          // row.id = 'grids'; //id not needed
          row.style.backgroundColor = 'white';
          row.style.opacity = '1';
          row.style.width = getSize(gridSize);
          row.style.height = getSize(gridSize);
          row.verticalAlign = 'top';
          row.style.display = 'inline-block';
          row.addEventListener('mouseover', function(e) {
            return row.style.backgroundColor = getColor(e.target);
          });
        }

      }

      function getSize(x) {
        let size = (720 / parseInt(x));
        return size + 'px';
      }

      function resetGrid(x) {
        let container = document.getElementById('mainContainer');
        while (container.firstChild) {
          container.removeChild (container.firstChild);
        }
        createGrid(x);
      }

      function getColor(grid) {
        if (currentBrush === 'black') {
            return 'black';
          } else if (currentBrush === 'rgb') {
            return randomBrush();
          } else if (currentBrush === 'erase') {
            return 'white';
          } else if (currentBrush === 'shade') {
            getShade(grid);
          }
      }

      function getShade(row) {
        if (row.style.backgroundColor === 'black') {
          return;
        } else if (row.style.opacity === 0) {
          row.style.backgroundColor === 'black';
          } else {
            row.style.opacity -= 0.1;
            }
      }

      function randomBrush() {
        var r = Math.floor((Math.random() * 255));
        var g = Math.floor((Math.random() * 255));
        var b = Math.floor((Math.random() * 255));
        return 'rgb('+ r + ', '+ g + ', ' + b + ')';
      }

      createGrid(16);
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
	font: inherit;
	vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}

/*  END OF RESET */

body {
  background-color: #DEDEDE;
}

#mainContainer {
  width: 720px;
  height: 720px;
  background-color: black;
  position: absolute;
  left: 50%;
  top: 50%;
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  font-size: 0;
  border: 5px #CDCDCD solid;
}
button {
  height: 36px;
  line-height: 27px;
  -moz-border-radius: 2px;
  -moz-user-select: none;
  background-color: #f2f2f2;
  border: 1px solid #f2f2f2;
  border-radius: 17px;
  color: #5F6368;
  cursor: pointer;
  font-family: arial,sans-serif;
  font-size: 14px;
  margin: 11px 4px;
  min-width: 54px;
  padding: 0 16px;
  margin-top: 25px;
  text-align: center;
  box-shadow: 0 1px 1px rgba(0,0,0,0.1);
}
button:hover {
  background-image: -moz-linear-gradient(bottom, #fff, #e8e8e8);
  background-image: -webkit-linear-gradient(bottom, #fff, #e8e8e8);
  color: #222;
  box-shadow: 0 1px 1px rgba(0,0,0,0.1);
}
#black {
  position: absolute;
  left: 30%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#shader {
  position: absolute;
  left: 36%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#rgb {
  position: absolute;
  left: 43%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#erase {
  position: absolute;
  left: 50%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
#reset {
  position: absolute;
  left: 57%;
  top: 3%;
  -ms-transform: translate(10%, 5%);
  transform: translate(10%, 5%);
}
<button id = "black">Black</button>
    <button id = "rgb">Random</button>
    <button id = "erase">Eraser</button>
    <button id = "reset">Reset</button>
    <button id = "shader">Shader</button>
    <div id = "mainContainer"></div>


    <script>
    </script>


推荐阅读