下面的脚本在屏幕左侧绘制图像,在右侧绘制一个选择框。然后,它会尝试通过使imageID
依赖于选择来重新定义右侧选择框中每个新选择上左侧绘制的图像。但是,正如您在下面看到的那样,无论您在右侧选择哪个数字,图像都保持不变(1
),因为虽然可能会重新绘制,但在选择时不会重新定义。我想要发生的是,在右侧框中的选择中,图像中的数字随选择框而变化,使得它始终与选择相关联。换句话说,当您单击2时,图像将更改为images
中的第二个图像。我找到了两种方法,但它们都存在缺陷:
1:在img
的{{1}}函数中定义paint
。这可以工作,但它使一切运行非常缓慢,并且图像上的悬停动画停止按预期工作。
2:在render
函数中定义img
。这也有效,但如果这样做,悬停动画将完全停止工作。
我为长代码道歉但我无法再浓缩它。为了简洁起见,我只包括1和1之间数字的图像。任何帮助都将不胜感激。
makeSelectionInfo
var c=document.getElementById('game'),
canvasX=c.offsetLeft,
canvasY=c.offsetTop,
ctx=c.getContext('2d');
images=['https://i.stack.imgur.com/KfN4z.jpg',
'https://i.stack.imgur.com/MyQS1.png',
'https://i.stack.imgur.com/3Vlfj.jpg',
'https://i.stack.imgur.com/u3NLH.jpg',
'https://i.stack.imgur.com/XnLwl.png'];
var curvedRect = function(text, x, y, w, h) {
this.text = text;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.hovered = false;
this.clicked = false;
}
curvedRect.prototype.makeCurvedRect = function() {
var delta=0, theta=0, yRotation=this.y;
if (this.hovered) {
delta = 3;
shadowColor = '#000000';
shadowBlur = 20;
shadowOffsetX = 5;
shadowOffsetY = 5;
theta = -0.01;
} else {
delta = 0;
theta = 0;
shadowColor = '#9F3A9B';
shadowBlur = 0;
shadowOffsetX = 0;
shadowOffsetY = 0;
}
var x = this.x-delta;
var y = yRotation-delta;
var w = this.w+(2*delta);
var h = this.h+(2*delta);
var img=new Image();
img.src=images[this.text];
ctx.rotate(theta);
ctx.beginPath();
ctx.lineWidth='8';
ctx.strokeStyle='white';
ctx.moveTo(x+10, y);
ctx.lineTo(x+w-10, y);
ctx.quadraticCurveTo(x+w, y, x+w, y+10);
ctx.lineTo(x+w, y+h-10);
ctx.quadraticCurveTo(x+w, y+h, x+w-10, y+h);
ctx.lineTo(x+10, y+h);
ctx.quadraticCurveTo(x, y+h, x, y+h-10);
ctx.lineTo(x, y+10);
ctx.quadraticCurveTo(x, y, x+10, y);
ctx.shadowColor = shadowColor;
ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetX = shadowOffsetX;
ctx.shadowOffsetY = shadowOffsetY;
ctx.stroke();
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.drawImage(img, x+2.5, y+2.5, w-5, h-5);
ctx.rotate(-theta);
}
curvedRect.prototype.hitTest = function(x, y) {
return (x >= this.x) && (x <= (this.w+this.x)) && (y >= this.y) && (y <= (this.h+this.y));
}
var selectionForMenu = function(id, text, y) {
this.id = id;
this.text = text;
this.y = y;
this.hovered = false;
this.clicked = false;
this.lastClicked = false;
}
function makeTextForSelected(text, y) {
ctx.font='bold 12px Noto Sans';
ctx.fillStyle='white';
ctx.textAlign='center';
ctx.fillText(text, 200, y);
}
function makeSelectionInfo(text) {
makeTextForSelected(text, 375);
}
selectionForMenu.prototype.makeSelection = function() {
var fillColor='#A84FA5';
if (this.hovered) {
if (this.clicked) {
if (this.lastClicked) {
fillColor='#E4C7E2';
} else {
fillColor='#D5A9D3';
}
} else if (this.lastClicked) {
fillColor='#D3A4D0';
makeSelectionInfo(this.text);
} else {
fillColor='#BA74B7';
}
} else if (this.lastClicked) {
fillColor='#C78DC5';
makeSelectionInfo(this.text);
} else {
fillColor='#A84FA5';
}
ctx.beginPath();
ctx.fillStyle=fillColor;
ctx.fillRect(400, this.y, 350, 30)
ctx.stroke();
ctx.font='10px Noto Sans';
ctx.fillStyle='white';
ctx.textAlign='left';
ctx.fillText(this.text, 410, this.y+19);
}
selectionForMenu.prototype.hitTest = function(x, y) {
return (x >= 400) && (x <= (750)) && (y >= this.y) && (y <= (this.y+30)) && !((x >= 400) && (y > 450));
}
var Paint = function(element) {
this.element = element;
this.shapes = [];
}
Paint.prototype.addShape = function(shape) {
this.shapes.push(shape);
}
Paint.prototype.render = function() {
ctx.clearRect(0, 0, this.element.width, this.element.height);
for (var i=0; i<this.shapes.length; i++) {
try {
this.shapes[i].makeSelection();
}
catch(err) {}
try {
this.shapes[i].makeCurvedRect();
}
catch(err) {}
}
ctx.beginPath();
ctx.fillStyle='white';
ctx.fillRect(0, 0, 750, 25);
ctx.stroke();
for (var i=0; i<this.shapes.length; i++) {
try {
this.shapes[i].makeBox();
}
catch(err) {}
}
ctx.beginPath();
ctx.fillStyle='#BC77BA';
ctx.fillRect(0, 450, 750, 50);
ctx.stroke();
ctx.font='bold 10px Noto Sans';
ctx.fillStyle='#9F3A9B';
ctx.textAlign='center';
ctx.fillText('Phrase Practice', 365, 17);
for (var i=0; i<this.shapes.length; i++) {
try {
this.shapes[i].makeInteractiveButton();
}
catch(err) {}
}
}
Paint.prototype.setHovered = function(shape) {
for (var i=0; i<this.shapes.length; i++) {
this.shapes[i].hovered = this.shapes[i] == shape;
}
this.render();
}
Paint.prototype.setClicked = function(shape) {
for (var i=0; i<this.shapes.length; i++) {
this.shapes[i].clicked = this.shapes[i] == shape;
}
this.render();
}
Paint.prototype.setUnclicked = function(shape) {
for (var i=0; i<this.shapes.length; i++) {
if (shape.constructor.name==this.shapes[i].constructor.name) {
this.shapes[i].clicked = false;
if (shape instanceof selectionForMenu) {
this.shapes[i].lastClicked = this.shapes[i] == shape;
}
}
}
this.render();
}
Paint.prototype.select = function(x, y) {
for (var i=this.shapes.length-1; i >= 0; i--) {
if (this.shapes[i].hitTest(x, y)) {
return this.shapes[i];
}
}
return null
}
imageID = 0;
var paint = new Paint(c);
var img = new curvedRect(imageID, 112.5, 100, 175, 175);
var selection = [];
for (i=0; i<=30; i++) {
selection.push(new selectionForMenu(i, i, 25+(i*30)));
}
paint.addShape(img);
for (i=0; i<30; i++) {
paint.addShape(selection[i])
}
paint.render();
var clickedShape=0;
var i=0;
function mouseDown(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
var shape = paint.select(x, y);
if (shape instanceof selectionForMenu) {
imageTextID = shape.id;
if (i==0) {
clickedShape=shape;
i=1;
} else if (i==1) {
i=0;
}
}
paint.setClicked(shape);
}
function mouseUp(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
var shape = paint.select(x, y);
if (clickedShape instanceof selectionForMenu) {
if (x>400 && y>25 && y<450) {
paint.setUnclicked(shape);
} else if (shape && !(shape instanceof selectionForMenu)) {
paint.setUnclicked(shape);
}
}
}
function mouseMove(event) {
var x = event.x - canvasX;
var y = event.y - canvasY;
var shape = paint.select(x, y);
paint.setHovered(shape);
}
c.addEventListener('mousedown', mouseDown);
c.addEventListener('mouseup', mouseUp);
c.addEventListener('mousemove', mouseMove);
canvas {
z-index: -1;
margin: 1em auto;
border: 1px solid black;
display: block;
background: #9F3A9B;
}
答案 0 :(得分:1)
修复了您的代码https://jsfiddle.net/0wq0hked/2/
你可以看看我改变了什么,但基本上你没有初始化并将多个curvedRect
添加到Paint.shapes
数组。我还将图像添加为curvedRect
的属性。
我还必须在您的形状中添加visible
参数,因为鼠标悬停Paint.select
功能无法正常运行。你的工作方式,共享相同(x,y)的形状不允许其他形状徘徊,即使它们不可见。因此,占据左侧图像区域的多个形状阻止了悬停的正常工作。我想你可以在绘制时保留你的Paint.select
和实例/删除形状,但据我所知,你没有形状去除功能。
此外,您在每个事件上调用渲染,这是一个坏主意。看看requestAnimationFrame
并尝试以屏幕刷新率而不是用户输入进行绘制。