繁体   English   中英

从底部平滑地在画布上为图像制作动画

[英]animate images smoothly up the canvas from the bottom

我试图将图像添加到画布上,然后慢慢将其滑出屏幕。 我已经设置好了,因此图像不断添加,并且它们沿着屏幕向上移动。 我希望在单击时在画布上添加新图像,然后该图像缓慢滑出屏幕。

这是我在下面的尝试。 它将图像添加到画布上,然后它们在屏幕上向上移动,但是令人眼前一亮,而不是所需的行为。

 var windowHeight = window.innerHeight; var windowWidth = window.innerWidth; var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); canvas.width = windowWidth; canvas.height = windowHeight; var x = windowHeight; function newImage() { var images = [ 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg', 'http://www.convoy.me/image/landing/Scratcher.png', 'http://www.convoy.me/image/landing/push_harder_0006.png', 'http://www.convoy.me/image/landing/Scratcher.png', 'http://www.convoy.me/image/landing/Screen-Shot-2015-12-04-at-17.14.41.jpg' ]; var randomImage = parseInt(Math.random() * images.length); var randomPosition = parseInt(Math.random() * 1200); var imageObj = new Image(); imageObj.onload = function() { ctx.drawImage(imageObj, randomPosition, x, 200, 200); }; imageObj.src = images[randomImage]; } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); x--; newImage(); } setInterval(draw, 50); canvas.addEventListener("click", draw, false); 
 <canvas id="canvas"></canvas> 

希望这段代码对您有所帮助。

 var windowHeight = window.innerHeight; var windowWidth = window.innerWidth; var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); canvas.width = windowWidth; canvas.height = windowHeight; function newImage() { var randomPosition = parseInt(Math.random() * 1200); var images = [ 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg', 'http://www.convoy.me/image/landing/Scratcher.png', 'http://www.convoy.me/image/landing/push_harder_0006.png', 'http://www.convoy.me/image/landing/Scratcher.png', 'http://www.convoy.me/image/landing/Screen-Shot-2015-12-04-at-17.14.41.jpg' ]; var y = windowHeight; var randomImage = parseInt(Math.random() * images.length); (function draw() { var imageObj = new Image(); imageObj.onload = function () { ctx.clearRect(randomPosition - imageObj.width, y, imageObj.width,imageObj.height); y-=5; ctx.drawImage(imageObj, randomPosition - imageObj.width, y, imageObj.width,imageObj.height ); if (y > -imageObj.height){ requestAnimationFrame(draw) } }; imageObj.src = images[randomImage]; })(); } canvas.addEventListener("click", newImage, false); 
 <canvas id="canvas"></canvas> 

您需要将加载与绘图功能分开。

我假设您希望它是一个无限的图像列表(实际上尽可能接近无限)

您将需要维护图像的“队列”,有多少将取决于您希望用户单击的频率以及图像的大小。

在对队列进行编程时,是具有其同名功能的数组。 先进先出,新项目位于末尾,旧项目从一开始就被删除。 (只要采用先进先出的规则,这无关紧要)

为此,队列将允许图像预加载并在需要时准备显示。

图像队列。

// the images
var imageURLs = ["img1.jpg","img2.jpg","img3.jpg",...,"img_n.jpg"];
var imageQueue = []; // empty.

function addImageToQueue(URL){
    var img = new Image();
    img.src = URL;
    img.onload = function(){
        this.ready = true;  // mark the image as loaded and ready
    }
    img.onerror = function(){
        this.ready = true; // is ready
        this.error = true; // but can not be displayed
    }
    imageQueue.push(img);
}

// get an image if ready from the queue
// return undefined if nothing is ready
// removes errored images and returns first non error if ready
function  getNextImage(){
    if(imageQueue.length > 0){
       if(imageQueue[0].ready && !imageQueue[0].error){ // is image ready and no error
           return imageQueue.shift(); // remove from the list and return
       }else{
           while(imageQueue.length > 0 && imageQueue[0].ready && !imageQueue[0].error){
                // remove bad images
                imageQueue.shift();
           }
           // no need to check error just did that
           if(imageQueue.length > 0 && imageQueue[0].ready){// if any left and ready
               return imageQueue.shift(); // remove from the list and return
           }
     }
}

不,您没有设置图像队列让我们处理动画。 这是一种标准的动画方法。

function update(time){ // time is supplied by browser
      ctx.clearRect(0,0,ctx.width,ctx.height);  // clear
      manageImageQueue();
      drawImages();
      requestAnimationFrame(update);
}
requestAnimationFrame(update);

两个函数manageImageQueuedrawImages的名称相同

设置这些功能

const queueLen = 5; // number of images to keep in the queue
var displayImages = [];  // current displayed images
var nextImage = true; // if true get a loaded image and add to display list
function manageImageQueue(){
    while(imageQueue.length < queueLen && imageURLs.length > 0){
         addImageToQueue(imageURLs.shift()); // add an image
    }
    if(nextImage){
         var image = getNextImage();
         if(image !== undefined){

              // not sure where you want image to start so I put it bottom center
              // all existing image increase the speed so that they move of canvas
              displayImages.forEach(function(img){ img.yStep += -1; }); 
              displayImages.push({
                 image : img,
                 x : ctx.canvas.width / 2 - image.width / 2,
                 y : ctx.canvas.height - image.height,
                 yStep : 0, // dont move
              });
              nextImage = false;
         }
     }
}
function drawImages(){
     for(var i = 0; i < displayImages.length; i ++){
         var img = displayImages[i]; // get image
         img.y += img.yStep; // move image
         if(img.y + img.image.height < 0){ // if off screen
              displayImages.splice(i,1); // remove image
              i-= 1; // step back so we dont skip the next image if there is one
         }else{
              ctx.drawImage(img.image,img.x,img.y); // draw the image
         }
    }
}

现在,我们需要的是启动所有操作的用户事件。

function nextImage(){ // you add this to what ever event
    nextimage = true; // flag that a new image is needed.
}

就是这样。

这将预加载图像,并在标志nextImage为true时向画布添加图像(如果可用)。 如果没有可用的图像,它将等到有图像后再添加。 添加新图像时,画布上的所有图像都将被设置为向上移动。

它将执行此操作,直到imageURLs数组中没有更多图像为止。

打算添加演示,但我看到有人已经帮助了您,所以就这样吧。 答案中有一些错别字。如果使用此代码但有问题,请添加注释。

:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM