下面是一个脚本,它定义了两个分别绘制4个矩形按钮和1个圆形按钮的功能。我正在尝试在按钮中实现特定的Hover和Click功能(如脚本警报中所述),但我对如何执行此操作感到有些不知所措。我尝试在每次单击时调用makeInteractiveButton()函数,但这会导致很多奇数重叠和延迟。我希望脚本执行以下操作:
如果圆形按钮悬停,我希望它的fillColour可以更改,如果单击它,我希望它再次更改为代码中描述的颜色(#FFC77E用于悬停,#FFDDB0用于单击)。这应该在悬停或点击期间仅发生。
HTML:
<html lang="en">
<body>
<canvas id="game" width = "750" height = "500"></canvas>
<script type='text/javascript' src='stack.js'></script>
</body>
</html>
JavaScript的:
var c=document.getElementById('game'),
canvasX=c.offsetLeft,
canvasY=c.offsetTop,
ctx=c.getContext('2d')
elements = [];
c.style.background = 'grey';
function makeInteractiveButton(x, strokeColor, fillColor) {
ctx.strokeStyle=strokeColor;
ctx.fillStyle=fillColor;
ctx.beginPath();
ctx.lineWidth=6;
ctx.arc(x, 475, 20, 0, 2*Math.PI);
ctx.closePath();
ctx.stroke();
ctx.fill();
elements.push({
arcX: x,
arcY: 475,
arcRadius: 20
});
}
b1 = makeInteractiveButton(235, '#FFFCF8', '#FFB85D');
c.addEventListener('mousemove', function(event) {
x=event.pageX-canvasX; // cursor location
y=event.pageY-canvasY;
elements.forEach(function(element) {
if (x > element.left && x < element.left + element.width &&
y > element.top && y < element.top + element.height) { // if cursor in rect
alert('Rectangle should undergo 5 degree rotation and 105% scale');
}
else if (Math.pow(x-element.arcX, 2) + Math.pow(y-element.arcY, 2) <
Math.pow(element.arcRadius, 2)) { // if cursor in circle
alert('Set b1 fillColour to #FFC77E.');
}
});
}, false);
c.addEventListener('click', function(event) {
x=event.pageX-canvasX; // cursor location
y=event.pageY-canvasY;
elements.forEach(function(element) {
if (x > element.left && x < element.left + element.width &&
y > element.top && y < element.top + element.height) { // if rect clicked
alert('Move all cards to centre simultaneously.');
}
else if (Math.pow(x-element.arcX, 2) + Math.pow(y-element.arcY, 2) <
Math.pow(element.arcRadius, 2)) { // if circle clicked
alert('Set b1 fillColour to #FFDDB0.');
}
});
}, false);
答案 0 :(得分:1)
一种方法是保留所有元素数据并编写一个hitTest(x,y)函数,但是当你有很多复杂的形状时,最好使用辅助画布来渲染元素的ID而不是它们的颜色和第二个画布中的x,y的颜色是hitted元素的ID,我应该提到第二个画布是可见的,它只是一个用于获取hitted元素的gelper。
https://siamandmaroufi.github.io/CanvasElement/
var Rectangle = function(id,x,y,width,height,color){
this.id = id;
this.x=x;
this.y=y;
this.width = width;
this.height = height;
this.color = color || '#7cf';
this.selected = false;
}
Rectangle.prototype.draw = function(ctx){
ctx.fillStyle = this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
if(this.selected){
ctx.strokeStyle='red';
ctx.setLineDash([5,5]);
ctx.lineWidth = 5;
ctx.strokeRect(this.x,this.y,this.width,this.height);
}
}
Rectangle.prototype.hitTest=function(x,y){
return (x >= this.x) && (x <= (this.width+this.x)) &&
(y >= this.y) && (y <= (this.height+this.y));
}
var Paint = function(el) {
this.element = el;
this.shapes = [];
}
Paint.prototype.addShape = function(shape){
this.shapes.push(shape);
}
Paint.prototype.render = function(){
//clear the canvas
this.element.width = this.element.width;
var ctx = this.element.getContext('2d');
for(var i=0;i<this.shapes.length;i++){
this.shapes[i].draw(ctx);
}
}
Paint.prototype.setSelected = function(shape){
for(var i=0;i<this.shapes.length;i++){
this.shapes[i].selected = 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;
}
var el = document.getElementById('panel');
var paint = new Paint(el);
var rectA = new Rectangle('A',10,10,150,90,'yellow');
var rectB = new Rectangle('B',150,90,140,100,'green');
var rectC = new Rectangle('C',70,85,200,70,'rgba(0,0,0,.5)');
paint.addShape(rectA);
paint.addShape(rectB);
paint.addShape(rectC);
paint.render();
function panel_mouseUp(evt){
var p = document.getElementById('panel');
var x = evt.x - p.offsetLeft;
var y = evt.y - p.offsetTop;
var shape = paint.select(x,y);
if(shape){
alert(shape.id);
}
//console.log('selected shape :',shape);
}
function panel_mouseMove(evt){
var p = document.getElementById('panel');
var x = evt.x - p.offsetLeft;
var y = evt.y - p.offsetTop;
var shape = paint.select(x,y);
paint.setSelected(shape);
}
el.addEventListener('mouseup',panel_mouseUp);
el.addEventListener('mousemove',panel_mouseMove);
&#13;
body {background:#e6e6e6;}
#panel {
border:solid thin #ccc;
background:#fff;
margin:0 auto;
display:block;
}
&#13;
<canvas id="panel" width="400px" height="200px" >
</canvas>
&#13;
只需点击或移动形状
即可