Javascript 在画布中设置3个图像的动画

Javascript 在画布中设置3个图像的动画,javascript,html,animation,html5-canvas,Javascript,Html,Animation,Html5 Canvas,我需要在画布上设置3个云的动画,它们应该在X轴上移动,一旦它们在右侧消失,它们应该在左侧重新出现。每个云应该位于不同的X轴和Y轴起始位置,并且它们应该以不同的速度移动 首先,我尝试只创建1个云动画,这就是我想到的: var canvas, context, docWidth, docHeight; window.onload = function(){ docWidth = window.innerWidth; docHeight = window.innerHeight

我需要在画布上设置3个云的动画,它们应该在X轴上移动,一旦它们在右侧消失,它们应该在左侧重新出现。每个云应该位于不同的X轴和Y轴起始位置,并且它们应该以不同的速度移动

首先,我尝试只创建1个云动画,这就是我想到的:

var canvas, context, docWidth, docHeight;

window.onload = function(){
    docWidth = window.innerWidth;
    docHeight =  window.innerHeight
    canvas = document.getElementById('canvas');
    context = canvas.getContext('2d')
    resizeCanvas(docWidth, docHeight);
    drawCloud(0, 0, docWidth, docHeight);
}

function resizeCanvas(width, height){
    canvas.width = docWidth;
    canvas.height = docHeight;
}

function drawCloud(x,y,width, height){
    var img = new Image();
    img.src = 'images/cloud1.png';

    img.onload = function(){
        context.save();
        context.clearRect(0,0,width,height);
        imageWidth = img.naturalWidth;
        imageHeight = img.naturalHeight;
        context.drawImage(img,x-imageWidth,10);
        context.restore();

        if(x >= width+imageWidth){
            x=0-imageWidth/2;
        } else {
            x += 3;
        }
        var loopTimer = setTimeout('drawCloud('+x+','+y+','+width+','+height+')',24);
    }
}
这很好,我看到了云动画,它在右侧消失,在左侧重新出现。现在有了3张图片,事情就变得复杂了。我尝试了一种面向对象的方法:

首先,在Canvas元素中,我尝试预加载图像:

<canvas id="canvas" width="0px" height="0px">
<script type="text/javascript">
    <!--//--><![CDATA[//><!--
        var images = new Array()
        function preload() {
            for (i = 0; i < preload.arguments.length; i++) {
                images[i] = new Image()
                images[i].src = preload.arguments[i]
            }
        }
        preload(
            "images/cloud1.png",
            "images/cloud2.png",
            "images/cloud3.png"
        )
    //--><!]]>
</script>
</canvas>
然后此绘图功能:

function drawCloud(clouds, width, height){
    var img;
    var arrLength = clouds.length;

        context.save();
        context.clearRect(0,0,width,height);
        for(var i=0; i<arrLength; i++){
            var Cloud = clouds[i];
            img = new Image();
            img.src = Cloud.getFilename();
            imageWidth = img.naturalWidth;
            imageHeight = img.naturalHeight;
            context.drawImage(img, Cloud.getX()-imageWidth, Cloud.getY());
            clouds[i].moveCloud(imageWidth);
        }

        context.restore();

        var loopTimer = setTimeout('drawCloud('+clouds+', '+width+', '+height+')',24);

}

现在我甚至看不到画布上的云图像,更不用说它们的动画了。你知道如何让它工作吗?

我改进了你的fiddel,让它工作了:

有几件事我必须解决,你可以将你的原始来源与我的进行比较,但最重要的是:

  • setTimeOut应该获取一个函数,而不是带有参数的内置字符串
  • 您在内部作用域中重新定义了
    Cloud
    ,不确定这是否会导致任何问题,但这是一种不好的做法
  • canvas
    元素中有javascript
  • JSFIDLE被配置为在onload事件中包含代码,并且您自己声明了该事件,因此您的window.onload没有运行

  • 创建一个JSFIDLE会很好,因为太多的代码无法使用read@Variant我试图创建JSFIDLE,但它甚至没有向我显示画布元素:太好了,它可以工作了,非常感谢!还有2个问题:1)在
    canvas
    元素中的代码应该在图像输出到canvas之前预加载图像;虽然我可以在没有代码的情况下工作,但是,在将图像输出到画布之前,我不需要预加载图像吗?2) 当你说你在一个内部范围内重新定义了云时,你是指这一行:
    constructor:Cloud
    还是其他什么?我是JS OOP新手,在一些教程中阅读了这篇文章,因此我很高兴能有一些解释。您不必预加载图像,如果您希望稍后开始初始绘图,并且有时间进行预加载,那么这样做是一个很好的做法。至于重新定义,我说的是:
    var Cloud=clouds[i]明白了!关于重定义-是的,我的错,无意中把它写成了类而不是变量。再次感谢大家!谢谢你!
    
    function drawCloud(clouds, width, height){
        var img;
        var arrLength = clouds.length;
    
            context.save();
            context.clearRect(0,0,width,height);
            for(var i=0; i<arrLength; i++){
                var Cloud = clouds[i];
                img = new Image();
                img.src = Cloud.getFilename();
                imageWidth = img.naturalWidth;
                imageHeight = img.naturalHeight;
                context.drawImage(img, Cloud.getX()-imageWidth, Cloud.getY());
                clouds[i].moveCloud(imageWidth);
            }
    
            context.restore();
    
            var loopTimer = setTimeout('drawCloud('+clouds+', '+width+', '+height+')',24);
    
    }
    
    var canvas, context, docWidth, docHeight;
    
    window.onload = function(){
        docWidth = window.innerWidth;
        docHeight =  window.innerHeight
        canvas = document.getElementById('canvas');
        context = canvas.getContext('2d')
        resizeCanvas(docWidth, docHeight);
    
        var cloud1 = new Cloud(0, 10, docWidth, docHeight, 'images/cloud1.png', 3, 24);
        var cloud2 = new Cloud(400, 10, docWidth, docHeight, 'images/cloud2.png', 5, 24);
        var cloud3 = new Cloud(160, 10, docWidth, docHeight, 'images/cloud3.png', 1, 24);
        var clouds = [cloud1, cloud2, cloud3];
        drawCloud(clouds, docWidth, docHeight);
    }