Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/385.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 处理在画布上单独绘制的矩形实例的最佳方法_Javascript_Html_Canvas_Setinterval - Fatal编程技术网

Javascript 处理在画布上单独绘制的矩形实例的最佳方法

Javascript 处理在画布上单独绘制的矩形实例的最佳方法,javascript,html,canvas,setinterval,Javascript,Html,Canvas,Setinterval,首先,请原谅我对JavaScript完全缺乏了解。我正在寻找解决这个问题的最佳方法,但3天后我认为这可能是错误的 我需要编写一些代码来绘制画布中不同行中的移动矩形。在未来,我将需要检测两个矩形何时在相同的X坐标中,因此跟踪X值很重要。来自Java,我认为最好是创建一些矩形“对象”,并为每个实例创建一个draw方法 给我带来麻烦的是,我想用setInterval()调用draw函数,但每次调用函数draw时,值都不一样 这是我对矩形类的定义: 功能矩形(x、y、宽度、高度){ var x=x; 变

首先,请原谅我对JavaScript完全缺乏了解。我正在寻找解决这个问题的最佳方法,但3天后我认为这可能是错误的

我需要编写一些代码来绘制画布中不同行中的移动矩形。在未来,我将需要检测两个矩形何时在相同的X坐标中,因此跟踪X值很重要。来自Java,我认为最好是创建一些矩形“对象”,并为每个实例创建一个draw方法

给我带来麻烦的是,我想用
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);