Javascript 处理在画布上单独绘制的矩形实例的最佳方法
首先,请原谅我对JavaScript完全缺乏了解。我正在寻找解决这个问题的最佳方法,但3天后我认为这可能是错误的 我需要编写一些代码来绘制画布中不同行中的移动矩形。在未来,我将需要检测两个矩形何时在相同的X坐标中,因此跟踪X值很重要。来自Java,我认为最好是创建一些矩形“对象”,并为每个实例创建一个draw方法 给我带来麻烦的是,我想用Javascript 处理在画布上单独绘制的矩形实例的最佳方法,javascript,html,canvas,setinterval,Javascript,Html,Canvas,Setinterval,首先,请原谅我对JavaScript完全缺乏了解。我正在寻找解决这个问题的最佳方法,但3天后我认为这可能是错误的 我需要编写一些代码来绘制画布中不同行中的移动矩形。在未来,我将需要检测两个矩形何时在相同的X坐标中,因此跟踪X值很重要。来自Java,我认为最好是创建一些矩形“对象”,并为每个实例创建一个draw方法 给我带来麻烦的是,我想用setInterval()调用draw函数,但每次调用函数draw时,值都不一样 这是我对矩形类的定义: 功能矩形(x、y、宽度、高度){ var x=x; 变
setInterval()
调用draw函数,但每次调用函数draw时,值都不一样
这是我对矩形类的定义:
功能矩形(x、y、宽度、高度){
var x=x;
变量y=y;
变量宽度=宽度;
var高度=高度;
this.getX=函数(){
返回x;
}
this.setX=函数(值){
x=值;
}
this.getY=函数(){
返回y;
}
this.setY=函数(值){
y=值;
}
this.getWidth=函数(){
返回宽度;
}
this.setWidth=函数(值){
宽度=值;
}
this.getHeight=函数(){
返回高度;
}
this.setHeight=函数(值){
高度=数值;
}
this.draw=函数(){
如果(this.getX()问题是setInterval(myRectangle.draw(),speed);
没有做您认为它能做的事情。您调用draw一次,然后interval调用draw的结果。您将需要类似以下内容:
interval = setInterval(function() {
myRectangle.draw();
}, speed);
您会注意到,我将setInterval
的返回值设置为一个变量,因为这就是以后清除间隔的方式
clearInterval(interval);
我不知道这是否能解决你所有的问题,但至少你应该得到一些能给你更多信息的东西。演示:
创建矩形对象以定义在画布上绘制的内容的本能确实是常见的标准
与Java不同,JavaScript没有真正的类,但您可以像在问题中所做的那样创建一个伪类
最简单的情况是,矩形“类”需要以下属性:
- x、 y
- 宽度、高度
如果要在画布上设置这些矩形的动画,可以添加:
- 速度,方向
- 速度,方向
这些新属性允许您按如下方式移动矩形:
this.x += this.directionX * this.velocityX;
this.y += this.directionY * this.velocityY;
// draw this rect on the canvas
Rectangle.prototype.render=function(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
return(this);
}
提示:Html5现在有一个优秀的动画处理程序:requestAnimationFrame。您可能希望使用它而不是setInterval或setTimeout,因为它通过将自身与浏览器的刷新周期集成在一起提供更好的性能
提示:JavaScript是一种原型语言,因此您可以使用方法扩展“类”。将方法添加到“类”的最佳方法是将它们添加到类原型中。这样,方法创建一次并由类的所有实例共享,而不是在每个实例上重新创建每个方法
因此,允许矩形实例将自身绘制到画布的方法可能如下所示:
this.x += this.directionX * this.velocityX;
this.y += this.directionY * this.velocityY;
// draw this rect on the canvas
Rectangle.prototype.render=function(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
return(this);
}
提示:JavaScript“类”方法可以链接,如果您总是返回(这)。链接的一个好用法可能是在实例上调用move
方法,然后在render
方法上链接
rectangle1.move().render();
关于javascript“类”,有很多东西需要学习
以下是带注释的代码:
祝你的项目好运
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// an array to hold all rectangle objects
var rectangles=[];
// a rectangle pseudo-class (javascript does not have actual classes)
function Rectangle(stdProperties) {
addProperties(this,stdProperties);
this.color=randomColor();
};
//
// Add methods that apply to all instance rectangles
// to Rectangle.prototype so those methods are
// created once for all instances instead of
// repeatedly for every instance.
//
// set x,y,width,height of this rectangle
Rectangle.prototype.init=function(x,y,width,height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
return(this);
};
// move this rectangle by its preset delta-x and delta-y
Rectangle.prototype.move=function(){
var maxRight=canvas.width-this.width;
var maxBottom=canvas.height-this.height;
this.x+=this.directionX*this.velocityX;
if(this.x<0){ this.x=0; this.directionX*=-1}
if(this.x>maxRight){ this.x=maxRight; this.directionX*=-1}
this.y+=this.directionY*this.velocityY;
if(this.y<0){ this.y=0; this.directionY*=-1}
if(this.y>maxBottom){ this.y=maxBottom; this.directionY*=-1}
return(this);
};
// draw this rect on the canvas
Rectangle.prototype.render=function(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
return(this);
}
// create a new rectangle object from the Rectangle "class"
function newRect(x,y,width,height){
// define default properties for Rectangle
var DefaultRectangleProperties={
x:0,y:0,width:10,height:10,
velocityX:1,velocityY:1,directionX:1,directionY:1,
color:"black",
}
// new-up a Rectangle
var rect = new Rectangle(DefaultRectangleProperties);
// set the x,y,width,height & draw it on the canvas
rect.init(x,y,width,height).render();
// return(this) to allow chaining
return(rect);
}
// TESTING
// create 5 rectangles with some randomness
for(var i=0;i<5;i++){
var rect=newRect(Math.random()*200,Math.random()*200,40,50);
rect.velocityX=Math.random()*2;
rect.velocityY=Math.random()*3;
rectangles.push(rect);
}
// animate the rectangles using requestAnimationFrame
animate();
// the animation loop
function animate(t){
// request another animation frame
requestAnimationFrame(animate);
// clear the canvas
// move all the rectangles by their preset distance
// redraw all the rectangles
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<rectangles.length;i++){
rectangles[i].move().render();
}
}
///////////////////////////////////
// Utilities
///////////////////////////////////
// create getters/setters on the specified object
// using the supplied properties object
//
function addProperties(object,properties){
for (var i in properties) {
(function(i) {
Object.defineProperty(object, i, {
get: function(){ return properties[i]; },
set: function(val){ properties[i] = val; }
})
})(i);
}
}
// generate a random color
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
正文{背景色:象牙;}
画布{边框:1px纯红;}
$(函数(){
//画布相关变量
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
//用于容纳所有矩形对象的数组
var矩形=[];
//矩形伪类(javascript没有实际的类)
函数矩形(stdProperties){
addProperties(这是stdProperties);
this.color=randomColor();
};
//
//添加应用于所有实例矩形的方法
//到Rectangle.prototype,所以这些方法是
//为所有实例创建一次,而不是
//对每一个例子都重复。
//
//设置此矩形的x、y、宽度和高度
Rectangle.prototype.init=函数(x,y,宽度,高度){
这个.x=x;
这个。y=y;
这个。宽度=宽度;
这个。高度=高度;
返回(本);
};
//按预设的delta-x和delta-y移动此矩形
Rectangle.prototype.move=function(){
var maxRight=canvas.width-this.width;
var maxBottom=canvas.height-this.height;
this.x+=this.directionX*this.velocityX;
如果(this.xmaxRight){this.x=maxRight;this.directionX*=-1}
this.y+=this.directionY*this.velocityY;
如果(this.ymaxBottom){this.y=maxBottom;this.directionY*=-1}
返回(本);
};
//在画布上绘制此矩形
Rectangle.prototype.render=function(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.width,this.height);
返回(本);
}
//从矩形“类”创建一个新的矩形对象
函数newRect(x,y,宽度,高度){
//定义矩形的默认属性
var DefaultRectangleProperties={
x:0,y:0,宽度:10,高度:10,
速度X:1,速度Y:1,方向X:1,方向Y:1,
颜色:“黑色”,
}
//新建一个矩形
var rect=新矩形(DefaultRectangleProperties);
//设置x、y、宽度、高度并在画布上绘制
init(x,y,宽度,高度).render();
//返回(此)以允许链接
返回(rect);
}
//测试
//创建5个随机的矩形
对于
var x = arguments[0]; // x declared internally, no need to manually declare it
var y = arguments[1]; // y declared too, etc.
...
function Rectangle() {
var x = arguments[0]; // legal but not recommended (in most cases)
var y = arguments[1];
...
function Rectangle(x,y,width,height) {
// no x,y, width and height decl. here - they're declared by signature
this.getX = function(){
return x;
}
...
setInterval(myRectangle.draw, speed); // only a reference, no parenthesis
var timerID; // global scope
...
timerID = setInterval(myRectangle.draw, speed);
clearInterval(timerID);