【问题标题】:Fading a loaded image into Canvas with drawImage使用 drawImage 将加载的图像淡入 Canvas
【发布时间】:2014-02-27 13:23:37
【问题描述】:

这个关于crossfading images 的问题已经给出了Canvas 中交叉淡入淡出解决方案的答案。我正在尝试做同样的事情,唯一的区别是我试图淡化在运行时加载的图像。

图像已正确加载,但看不到淡入淡出。由于加载的图像,这不起作用吗?谢谢。

HTML

 <div id="wrapper">
     <canvas id="bg1"></canvas>
     <canvas id="bg2"></canvas>
 </div>

JS

var toggle = true;

var canvas         = document.getElementById('bg1');
    canvas.width   = $(document).width();
    canvas.height  = $(document).height();
var ctx            = canvas.getContext('2d');

var canvas2        = document.getElementById('bg2');
    canvas2.width  = $(document).width();
    canvas2.height = $(document).height();

var ctx2           = canvas2.getContext('2d');

var image = new Image();
image.src = 'download1.jpg';

var image2 = new Image();
image2.src = 'download2.jpg';

image.onload = function() {
    ctx.drawImage(image, 0, 0, 200, 100);
    ctx2.drawImage(image2, 0, 0, 200, 100);
};

$('#wrapper').click(function () {
    if (toggle)
    {
        $('#bg2').fadeIn();
        $('#bg1').fadeOut();
    }
    else
    {
        $('#bg1').fadeIn();
        $('#bg2').fadeOut();
    }

    toggle = !toggle;
});

【问题讨论】:

    标签: javascript jquery html canvas drawimage


    【解决方案1】:

    是的,您需要给图像加载时间。

    而且,jQuery 不能在画布元素上进行淡入/淡出,因此您必须手动进行。

    演示:http://jsfiddle.net/m1erickson/zw9S4/

    代码:

    <!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(){
    
    $("#fade").hide();
    
    var imageURLs=[];  // put the paths to your images here
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-2.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg");
    loadAllImages();
    //
    function loadAllImages(){
        for (var i=0; i<imageURLs.length; i++) {
            var img = new Image();
            imgs.push(img);
            img.onload = function(){ 
                imagesOK++; 
                if (imagesOK>=imageURLs.length ) {
                    $("#fade").show();
                    ctx.drawImage(imgs[0],0,0);
                }
            };
            img.onerror=function(){alert("image load failed");} 
            img.crossOrigin="anonymous";
            img.src = imageURLs[i];
        }      
    }
    
    
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
    
        var fadeOutIndex=imgs.length-1;
        var fadeInIndex=0;
        var fadePct=0;
    
        function animateFade(){
            if(fadePct>100){return;}
            requestAnimationFrame(animateFade);
            ctx.clearRect(0,0,canvas.width,canvas.height);
            draw(imgs[fadeInIndex],fadePct/100);
            draw(imgs[fadeOutIndex],(1-fadePct/100));
            fadePct++;
        }
    
        function draw(img,opacity){
            ctx.save();
            ctx.globalAlpha=opacity;
            ctx.drawImage(img,0,0);
            ctx.restore();
        }
    
        $("#fade").click(function(){
            fadePct=0;
            if(++fadeOutIndex == imgs.length){fadeOutIndex=0;}
            if(++fadeInIndex == imgs.length){fadeInIndex=0;}
            animateFade();
        });
    
    }); // end $(function(){});
    </script>
    </head>
    <body>
        <button id="fade">Fade to next Image</button><br>
        <canvas id="canvas" width=204 height=204></canvas><br>
    </body>
    </html>
    

    【讨论】:

    • 您好,markE,感谢您的回答。图像确实被正确加载。我也试过你的答案。在这两种情况下,我都会看到图像,并且当我单击它们时它们会切换。在浏览器的检查器视图中,我看到了不透明度的变化。但没有可见的褪色。点击后需要淡入淡出时间,之后图像会立即更改而不会淡出。
    • 啊,我明白了问题...jQuery 不能淡化画布。有关如何进行淡入淡出的信息,请参阅我的更新答案。
    • 这很好,但你知道如何改变从一张图像到另一张图像的过渡速度吗?
    【解决方案2】:

    尝试直接在画布上淡入/淡出图像,而不是淡入和淡出画布元素(或者使用画布实际上没有任何意义,因为您可以使用图像元素代替)。

    首先,当然是等待图片加载:

    var isBusy = false,       /// for fade loop
        count = 2;            /// number of images to load
        image = new Image();
        image2 = new Image();
    
    /// setup load handler
    image.onload = image2.onload = handleLoad;
    image.src = 'download1.jpg';
    image2.src = 'download2.jpg';
    
    function handleLoad() {
        count--;
        if (count === 0) {
    
            /// when loaded draw a single image onto canvas
            ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);
        }
    };
    

    现在我们可以稍微改变一下点击处理程序,只使用画布来淡入下一张图片:

    $('#wrapper').click(function () {
    
        var img,         /// current image to fade in
            opacity = 0; /// current globalAlpha of canvas
    
        /// if we're in a fade exit until done    
        if (isBusy) return;
        isBusy = true;
    
        /// what image to use    
        img = toggle ? image2 : image;
    
        /// fade in
        (function fadeIn() {
            /// set alpha
            ctx.globalAlpha = opacity;
    
            /// draw image with current alpha
            ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
    
            /// increase alpha to 1, then exit resetting isBusy flag
            opacity += 0.02;
            if (opacity < 1)
                requestAnimationFrame(fadeIn);
            else
                isBusy = false;
        })();
    
        toggle = !toggle;
    });
    

    Online demo

    希望这会有所帮助。

    【讨论】:

    • 好东西,非常感谢!我做了类似的事情,但忘记了 isBusy 布尔值。认为这破坏了我的代码
    猜你喜欢
    • 2014-06-13
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 2022-11-27
    相关资源
    最近更新 更多