更改画布中每个矩形的颜色

时间:2018-11-15 11:38:31

标签: javascript canvas html5-canvas

我为6个矩形创建6个按钮。当单击按钮时,它将在数组中的颜色之后更改/随机显示该矩形的颜色。我该怎么办?

var colorArray = [
  '#CEF19E',
  '#A7DDA7',
  '#78BE97',
  '#398689',
  '#0B476D'
];

var c = canvas.getContext('2d');
c.fillRect(500, 100, 100, 100);
c.fillRect(250, 100, 100, 100);
c.fillRect(500, 500, 100, 100);
c.fillRect(700, 600, 100, 100);
c.fillRect(800, 100, 100, 100);

function changeColor() {
    //????
}

3 个答案:

答案 0 :(得分:1)

这个简短的示例有帮助吗?您可以复制按钮并调用相同的功能,也可以使用别名。 运行代码段。

var c = document.getElementById("myCanvas");
var ctx = c.getContext('2d');
var colorArray = [
  '#CEF19E',
  '#A7DDA7',
  '#78BE97',
  '#398689',
  '#0B476D'
];

var fillCombo = [
  [10, 10, 150, 80],
  [20, 20, 150, 80],
  [10, 10, 150, 80],
  [20, 20, 150, 80],
  [10, 10, 150, 80]
];


function changeColor() {
  var randomFill = fillCombo[Math.floor(Math.random() * fillCombo.length)];
  var randomColor = colorArray[Math.floor(Math.random() * colorArray.length)];
  ctx.beginPath();  
  ctx.rect(randomFill[0], randomFill[1], randomFill[2], randomFill[3]);
  ctx.fillStyle = randomColor;
  ctx.fill();
}
<!DOCTYPE HTML>
<html>

<head>
  <TITLE>Canvas Example</TITLE>
  <META http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</head>

<body>
  <canvas id="myCanvas" width="200" height="100" style="border:1px solid #000000;"></canvas>
  <button onclick="changeColor()">Click Me!!</button>
</body>

</html>

答案 1 :(得分:1)

我正在使用方法isPointInPath检测鼠标是否在当前矩形中,如果是,则将rects数组中的颜色从白色更改为颜色c

const canvas = document.getElementById("canvas");
const c = canvas.getContext("2d");
let cw = canvas.width = 700,
  cx = cw / 2;
let ch = canvas.height = 700,
  cy = ch / 2;
c.translate(-200,0);
c.fillStyle = "white";

let mouse = {}


let rects = [
  {c:'#CEF19E',data:[500, 100, 100, 100]},
  {c:'#A7DDA7',data:[250, 100, 100, 100]},
  {c:'#78BE97',data:[500, 500, 100, 100]},
  {c:'#398689',data:[700, 600, 100, 100]},
  {c:'#0B476D',data:[800, 100, 100, 100]}
]



rects.forEach(r=>{
  c.fillRect(...r.data);
})

canvas.addEventListener("mousemove",(evt)=>{
  // clear the canvas
  c.clearRect(200,0,cw,ch);
  mouse = oMousePos(canvas, evt);
  //for each rect in the rects array
  rects.forEach((r,i)=>{
  c.beginPath();
  // draw the rect
  c.rect(...r.data);
  // if thr mouse is inside the rect
  if(c.isPointInPath(mouse.x,mouse.y)){
  // fill the rect with the color in the rects array 
  c.fillStyle = r.c;//color
  
  // fill the rect
  c.beginPath();
  c.fillRect(...r.data);
  }else{
  
  // if the mouse is not in the rects array let it be white
  c.fillStyle = "white";
  c.fillRect(...r.data); 
  }
  })
})

// a function to detect the mouse position on the canvas
function oMousePos(canvas, evt) {
  var ClientRect = canvas.getBoundingClientRect();
	return { //objeto
	x: Math.round(evt.clientX - ClientRect.left),
	y: Math.round(evt.clientY - ClientRect.top)
}
}
body {
  background-color: #222;
}
canvas {
  background-color: #000;
  display: block;
  margin: 0 auto;
  margin:calc(50vh - 250px - 5em) auto;
}
<canvas id="canvas"></canvas>

我希望这会有所帮助。

答案 2 :(得分:0)

不要!鼠标事件时渲染!

我要添加此答案,因为 enxaneta 给出的answer是从鼠标事件进行渲染方面的不良做法示例。

鼠标事件(取决于设备配置和鼠标类型)可以每秒触发多达1000次。如果您通过鼠标事件进行渲染,这可能意味着您强制进行完整渲染,其速率要比可以显示的速率高出许多倍(每秒最多60倍)。这样做会无缘无故迅速耗尽笔记本电脑的电池。

解耦鼠标侦听器和渲染。

鼠标事件应始终与渲染分离。使用事件侦听器仅记录鼠标状态。

无论何时向DOM呈现任何内容,都应该始终通过框架请求来进行。这样可以确保您不会呈现与显示硬件不同步的新上下文,也不会在页面上添加其他看不见的不必要的渲染和DOM复合循环。

示例渲染和鼠标事件处理。

在下面的示例中,我使用通过requestAnimationFrame调用的更新循环来检查鼠标的状态并根据需要进行更改。

为确保没有不必要的渲染,必须将全局信号量redraw设置为true才能绘制画布内容。这意味着在下面的示例中,唯一的渲染是第一个渲染,并且矩形更改了颜色。

requestAnimationFrame(update); // will start the update loop when ready.
const ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 260;
var redraw = true; // When this is true the whole scene is rendered in time for the next display referesh


const colors = (() => {
    // Warning: MUST have more than one colour.
    //          At least one colour MUST be different than others.
    const cols = ["#CEF19E","#A7DDA7","#78BE97","#398689","#0B476D"];  
    return {
        get random() { return cols[Math.random() * cols.length | 0] },
        get default() { return "#DDD" },
    };
})();
const rectPos = [[10,10], [150, 10], [290, 10], [10, 150], [150, 150], [290, 150]];    
const rectSize = 100;
const rectangle = (x, y, w = rectSize, h= rectSize, style = colors.default) => ({x, y, w, h, style});
const rects = Object.assign(rectPos.map(rect => rectangle(...rect)), {
        getUnder(x, y) { return this.find(r => x >= r.x && x < r.x + r.w && y >= r.y && y < r.y + r.h) },
        draw() {
            for (const r of this) {
                ctx.fillStyle = r.style;
                ctx.fillRect(r.x, r.y, r.w, r.h);
            }
        },
    }
);

const mouse = {x: 0, y: 0, button: 0, over: false, changed : true};
function mouseEvents(e) {
    const bounds = canvas.getBoundingClientRect();
    const x = mouse.x = e.pageX - bounds.left - scrollX;
    const y = mouse.y = e.pageY - bounds.top - scrollY;
    mouse.over = x >= 0 && x < bounds.width && y >= 0 && y < bounds.height;
    mouse.button = e.type === "mousedown" ? true : e.type === "mouseup" ? false : mouse.button;
    mouse.changed = true;
}
["down","up","move"].forEach(name => document.addEventListener("mouse" + name, mouseEvents));

function update() {
    var cursor = "default";
    if (mouse.changed) {
        if (mouse.over) {
            const rectUnderMouse = rects.getUnder(mouse.x, mouse.y);
            if (rectUnderMouse) {
                if (mouse.button) {
                    var newCol = colors.random;
                    while (newCol === rectUnderMouse.style) { newCol = colors.random };
                    rectUnderMouse.style = newCol;
                    mouse.button = false;
                    redraw = true;
                } else {
                    cursor = "pointer";
                }
            }
        }
    }
    if (redraw) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        rects.draw();
        redraw = false;
    }
    canvas.style.cursor = cursor;
    requestAnimationFrame(update);
}
canvas { position : absolute; top : 0px; left : 0px; }
<canvas id="canvas"></canvas>