【问题标题】:HTML Canvas & JavaScript - Scale Object on HoverHTML Canvas & JavaScript - 悬停时缩放对象
【发布时间】:2017-05-04 16:15:16
【问题描述】:

下面的脚本绘制了 4 个弯曲的矩形,并使用 mouseupmousemove 事件侦听器检测它们是否被悬停或点击。当其中一个矩形悬停在上方时,我希望它在一秒钟内略微增长 - 然后当光标移出矩形时它应该缩小。

我遇到的问题是,我能想到的唯一方法是在 if (this.selected) { 子句中编写一个函数,该函数为持续一秒的动画中的每一帧绘制一个新版本的矩形,但是这个子句位于绘制矩形本身的新版本的函数内部!那么,如何在curvedRect.prototype.makeCurvedRect 之外编写一个仅在光标位于其中一个矩形上时运行的函数?任何帮助将不胜感激。

var c=document.getElementById('game'),
		canvasX=c.offsetLeft,
		canvasY=c.offsetTop,
		ctx=c.getContext('2d');

var curvedRect = function(id, x, y, w, h) {
	this.id = id;
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.selected = false;
}

curvedRect.prototype.makeCurvedRect = function() {
	ctx.beginPath();
	ctx.lineWidth='8';
	ctx.strokeStyle='white';
	ctx.moveTo(this.x+10, this.y);
	ctx.lineTo(this.x+this.w-10, this.y);
	ctx.quadraticCurveTo(this.x+this.w, this.y, this.x+this.w, this.y+10);
	ctx.lineTo(this.x+this.w, this.y+this.h-10);
	ctx.quadraticCurveTo(this.x+this.w, this.y+this.h, this.x+this.w-10, this.y+this.h);
	ctx.lineTo(this.x+10, this.y+this.h);
	ctx.quadraticCurveTo(this.x, this.y+this.h, this.x, this.y+this.h-10);
	ctx.lineTo(this.x, this.y+10);
	ctx.quadraticCurveTo(this.x, this.y, this.x+10, this.y);
	ctx.stroke();
	if (this.selected) {
        // BM67 edit By Blindman67 removed annoying alert and replaced it with console.log 
        // As I did not want to add elsewhere to the code to declare hoverMessageShown is safely declared here to stop the console repeating the message.
        if(window["hoverMessageShown"] === undefined){
           window["hoverMessageShown"] = true; 
  		   console.log('When hovered over, I would like this box to grow slightly over a short period of time (say a second). When the mouse is removed I would like it to shrink back.')
        }
        // BM67 end.
	}
}

curvedRect.prototype.hitTest = function(x, y) {
	return (x >= this.x) && (x <= (this.w+this.x)) && (y >= this.y) && (y <= (this.h+this.y));
}

var Paint = function(element) {
	this.element = element;
	this.shapes = [];
}

Paint.prototype.addShape = function(shape) {
	this.shapes.push(shape);
}

Paint.prototype.render = function() {
	this.element.w = this.element.w;
	for (var i=0; i<this.shapes.length; i++) {
		this.shapes[i].makeCurvedRect();
	}
}

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 paint = new Paint(c);
var img1 = new curvedRect('1', 200, 55, 150, 150);
var img2 = new curvedRect('2', 375, 55, 150, 150);
var img3 = new curvedRect('3', 200, 230, 150, 150);
var img4 = new curvedRect('4', 375, 230, 150, 150);

paint.addShape(img1);
paint.addShape(img2);
paint.addShape(img3);
paint.addShape(img4);

paint.render();

function mouseUp(event) {
	var x = event.x - canvasX;
	var y = event.y - canvasY;
	var shape = paint.select(x, y);
	if (shape) {
		alert(shape.id);
	}
	// console.log('selected shape: ', shape);
}

function mouseMove(event) {
	var x = event.x - canvasX;
	var y = event.y - canvasY;
	var shape = paint.select(x, y);

	paint.setSelected(shape);
}

c.addEventListener('mouseup', mouseUp);
c.addEventListener('mousemove', mouseMove);
canvas {
  display: block;
  margin: 1em auto;
  border: 1px solid black;
  background: #FF9900;
}
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>uTalk Demo</title>
	<link rel='stylesheet' type='text/css' href='game.css' media='screen'></style>
</head>
<body>
	<canvas id="game" width = "750" height = "500"></canvas>
</body>
</html>

【问题讨论】:

  • 我编辑了您的代码以将警报更改为控制台输出。我认为大多数人更喜欢当您只是将鼠标移过而不打算进行交互时不会弹出警报。正如您在问题中已经解释的那样,我个人认为不需要该消息。

标签: javascript html object canvas


【解决方案1】:

把 makeCurvedRect 方法改成这样:

var c=document.getElementById('game'),
		canvasX=c.offsetLeft,
		canvasY=c.offsetTop,
		ctx=c.getContext('2d');

var curvedRect = function(id, x, y, w, h) {
	this.id = id;
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.selected = false;
}

curvedRect.prototype.makeCurvedRect = function() { 
    var delta = this.selected?10:0 ;
    var x = this.x - delta;
    var y = this.y - delta;
    var w  = this.w + (2*delta);
    var h = this.h + (2*delta);
	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.stroke();
	 
}

curvedRect.prototype.hitTest = function(x, y) {
	return (x >= this.x) && (x <= (this.w+this.x)) && (y >= this.y) && (y <= (this.h+this.y));
}

var Paint = function(element) {
	this.element = element;
	this.shapes = [];
}

Paint.prototype.addShape = function(shape) {
	this.shapes.push(shape);
}

Paint.prototype.render = function() {
	this.element.width = this.element.width;
	for (var i=0; i<this.shapes.length; i++) {
		this.shapes[i].makeCurvedRect();
	}
}

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 paint = new Paint(c);
var img1 = new curvedRect('1', 200, 55, 150, 150);
var img2 = new curvedRect('2', 375, 55, 150, 150);
var img3 = new curvedRect('3', 200, 230, 150, 150);
var img4 = new curvedRect('4', 375, 230, 150, 150);

paint.addShape(img1);
paint.addShape(img2);
paint.addShape(img3);
paint.addShape(img4);

paint.render();

function mouseUp(event) {
	var x = event.x - canvasX;
	var y = event.y - canvasY;
	var shape = paint.select(x, y);
	if (shape) {
		alert(shape.id);
	}
	// console.log('selected shape: ', shape);
}

function mouseMove(event) {
	var x = event.x - canvasX;
	var y = event.y - canvasY;
	var shape = paint.select(x, y);

	paint.setSelected(shape);
}

c.addEventListener('mouseup', mouseUp);
c.addEventListener('mousemove', mouseMove);
canvas {
  display: block;
  margin: 1em auto;
  border: 1px solid black;
  background: #FF9900;
}
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>uTalk Demo</title>
	<link rel='stylesheet' type='text/css' href='game.css' media='screen'></style>
</head>
<body>
	<canvas id="game" width = "750" height = "500"></canvas>
</body>
</html>

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 2012-06-14
  • 2015-06-01
  • 1970-01-01
  • 2011-12-18
相关资源
最近更新 更多