我为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() {
//????
}
答案 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>