简体   繁体   English

多个图像未加载到画布上

[英]Multiple images not load on canvas

I have created Circle using arc like following way. 我使用arc创建了Circle,如下所示。

 var startAngle = 0; var arc = Math.PI / 6; var ctx; var leftValue=275; var topValue=300; var wheelImg = ["http://i.stack.imgur.com/wwXlF.png","http://i.stack.imgur.com/wwXlF.png","cat.png","cock.png", "croco.png","dog.png","eagle.png","elephant.png","lion.png", "monkey.png","rabbit.png","sheep.png"]; function drawWheelImg() { var canvas = document.getElementById("canvas"); if(canvas.getContext) { var outsideRadius = 260; var textRadius = 217; var insideRadius = 202; ctx = canvas.getContext("2d"); for(var i = 0; i < 12; i++) { var angle = startAngle + i * arc; ctx.beginPath(); ctx.arc(leftValue, topValue, outsideRadius, angle, angle + arc, false); ctx.arc(leftValue, topValue, insideRadius, angle + arc, angle, true); ctx.fill(); ctx.closePath(); ctx.beginPath(); ctx.arc(leftValue, topValue, outsideRadius, angle, angle + arc, false); ctx.shadowBlur=3; ctx.shadowColor="#A47C15"; ctx.stroke(); ctx.closePath(); ctx.save(); ctx.translate(leftValue + Math.cos(angle + arc / 2) * textRadius, topValue + Math.sin(angle + arc / 2) * textRadius); ctx.rotate(angle + arc / 2 + Math.PI / 2); var img = new Image(); img.src = wheelImg[i]; ctx.drawImage(img,-44, -25,50,40); ctx.restore(); } } } function spin() { drawWheelImg(); } drawWheelImg(); 
 <button class="btnSpin" onclick="spin();">Spin</button> <canvas id="canvas" width="550" height="580"></canvas> 

Problem is that it will not load when first page load. 问题是第一页加载时不会加载。 But when i click on spin button it will load all images. 但是,当我点击旋转按钮时,它将加载所有图像。

Don't know what is the issue. 不知道是什么问题。 Any help is greatly appreciated. 任何帮助是极大的赞赏。

Note: Here in the question same issue is solve by img.onload function but that for only single image. 注意: 在这个问题中,同样的问题是通过img.onload函数解决的,但仅适用于单个图像。 If there is number of multiple images in array then it's not working. 如果阵列中有多个图像,那么它就无法正常工作。

You want to preload the images. 您想要预加载图像。

To do this you can start the loading at the bottom of the page just before the closing </dody> tag. 为此,您可以在结束</dody>标记之前的页面底部开始加载。

<script>
    // an array of image URLs
    var imageNames = ["image1.png", "image2.jpg", ...moreImageNames];
    // an array of images 
    var images = [];
    // for each image name create the image and put it into the images array
    imageNames.forEach(function(name){
        image = new Image();   // create image
        image.src = name;      // set the src
        images.push(image);    // push it onto the image array
    });
</script>         

In the code that uses the images you just need to check if they have loaded yet. 在使用图像的代码中,您只需要检查它们是否已加载。 To do this just check the image complete attribute. 为此,只需检查图像complete属性。

// draw the first image in the array
if(images[0].complete){  // has it loaded
    ctx.drawImage(images[0],0,0);  // yes so draw it
}

Note that complete does not mean loaded. 请注意complete并不意味着加载。 If you proved a bad URL or there is another error the complete flag will still be true. 如果您证明网址错误或存在其他错误,则完整标记仍然为真。 Complete means the browser has finished dealing with the image. 完成意味着浏览器已完成处理图像。 You will have to add an onload event if there is a chance that images may fail. 如果图像可能会失败,则必须添加onload事件。

Handling Errors 处理错误

If you are unsure that an image will not load you will have to devise a strategy to deal with the missing content. 如果您不确定图像是否无法加载,则必须制定策略来处理缺少的内容。 You will need to answer questions like, Can my app function without the image? 你需要回答一些问题,我的应用程序可以在没有图像的情况下运行吗? Are there alternative sources to get the image from? 是否有替代来源来获取图像? Is there a way to determine how often this is likely to happen? 有没有办法确定这可能发生的频率? How do I stop this from happening? 我如何阻止这种情况发生?

On the simplest level you can flag an image as loaded by adding your own semaphore to the image object during the onload event 在最简单的级别上,您可以通过在onload事件期间将自己的信号量添加到图像对象来将图像标记为已加载

    // an array of image URLs
    var imageNames = ["image1.png", "image2.jpg", ...moreImageNames];
    // an array of images 
    var images = [];
    // function to flag image as loaded
    function loaded(){
        this.loaded = true;
    }
    // for each image name create the image and put it into the images array
    imageNames.forEach(function(name){
        image = new Image();   // create image
        image.src = name;      // set the src
        image.onload = loaded; // add the image on load event
        images.push(image);    // push it onto the image array
    });

Then in code you will check for the loaded semaphore before using the image. 然后在代码中,您将在使用图像之前检查加载的信号量。

// draw the first image in the array
if(images[0].loaded){  // has it loaded
    ctx.drawImage(images[0],0,0);  // yes so draw it
}

Critical content 关键内容

If you have images that are required for you app to function then you should redirect to an error page if there is a problem loading the image. 如果您有应用程序运行所需的图像,那么如果加载图像时出现问题,您应该重定向到错误页面。 You may have several servers so you can also try the different sources before giving up. 您可能有多台服务器,因此您可以在放弃之前尝试不同的来源。

If you need to stop the app or try an alternative URL you will have to intercept the onerror image event. 如果您需要停止应用程序或尝试另一种URL,你将不得不拦截onerror图像事件。

To simplify your use of the images (100% sure the images are loaded when that app runs) you should start the parts that use the images only when all the images are loaded. 为了简化您对图像的使用(100%确保在该应用程序运行时加载图像),您应该仅在加载所有图像时启动使用图像的部分。 One way to do this is to count all the images that are being loaded, and count down as the images load. 一种方法是计算所有正在加载的图像,并在图像加载时倒计时。 When the counter reaches zero you know all the images have loaded and you can then call you app. 当计数器达到零时,您知道所有图像都已加载,然后您可以调用您的应用程序。

The following will load images, if they fail it will try another server (source) until there are no more options at which point you should redirect to the appropriate error page to inform the client that a monkey has put a spanner in the works. 以下将加载图像,如果它们失败,它将尝试另一个服务器(源),直到没有更多的选项,您应该重定向到相应的错误页面,以通知客户端猴子已经将扳手投入工作。 It counts the loading images and when all the images have loaded then it will start the app running, sure in the knowledge that all the image content is safe to use. 它计算加载图像,当所有图像都已加载时,它将启动应用程序运行,确保知道所有图像内容都可以安全使用。

    // Server list in order of preferance
    var servers = ["https://fakesiteABC.com/", "http://boogusplace.com/", "http://foobarpoo.com.au/"];

    // an array of image URLs
    var imageNames = ["image1.png", "image2.jpg", ...moreImageNames];
    // an array of images 
    var images = [];
    // loading count tracks the number of images that are being loaded
    var loadingImageCount = 0;
    // function to track loaded images
    function loaded(){
        loadingImageCount -= 1;
        if(loadingImageCount === 0){
              // call your application start all images have loaded
              appStart();
        }
    }
    // function to deal with error
    function loadError(){  // the keyword "this" references the image that generated the event.
        if(this.retry === undefined){  // is this the first error
            this.retry = 1;   // point to the second server
        }else{
            this.retry += 1;  // on each error keep trying servers (locations)
        }
        // are the any other sources to try?
        if(this.retry >= servers.length){  // no 11
            // redirect to error page.
            return;
        }
        // try a new server by setting the source and stripping the 
        // last server name from the previous src URL
        this.src = servers[this.retry] + this.src.replace( servers[ this.retry - 1],"");
        // now wait for load or error
    }


    // for each image name create the image and put it into the images array
    imageNames.forEach(function(name){
        image = new Image();   // create image
        image.src = servers[0] + name;      // set the src from the first server
        image.onload = loaded; // add the image on load event
        image.onerror = loadError; // add the image error handler
        images.push(image);    // push it onto the image array
        loadingImageCount += 1; // count the images being loaded.
    });

There are many other strategies for dealing with missing content. 处理缺失内容还有许多其他策略。 This just shows some of the mechanism used and does not define a perfect solution (there is none) 这只是展示了一些使用的机制,并没有定义一个完美的解决方案(没有)

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

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