HTML5 Canvas 图像渐变转场效果

借助现代浏览器强力的JavaScript引擎和HTML5 Canvas的图像处理能力,完成以往不容易直接用网页完成的转场效果.

过渡效果的原理见此文章:RGB颜色插值渐变原理及算法.

也可修改animation函数完成更复杂的过渡效果.

在线DEMO(位于Google Drive,可能无法访问,示例载入的图片较大,请耐心等待).

示例代码:

<!DOCTYPE html>  
<html>  
<head>  
    <title>Image transition transition effects</title>
</head>  
<body>  
    <canvas width='850' height='240'></canvas>
    <script>
        var imgList=['nav_event.png',
                     'nav_twitter.png',
                     'nav_banner.png',
                     'nav_drama06.png',
                     'nav_sound.png',
                     'nav_movie.png',
                     'nav_leaflet.png',
                     'nav_trial.png',
                     'nav_count12.png'];

        function loaded(){
            var canvas=document.querySelector('canvas'),
                ctx=canvas.getContext('2d');
            var width=canvas.width,
                height=canvas.height;

            var tempCanvas=document.createElement('canvas'),
                tempCtx=tempCanvas.getContext('2d');
                tempCanvas.width=width;
                tempCanvas.height=height*2;
                tempWidth=tempCanvas.width,
                tempHeight=tempCanvas.height;

            function animation(img1,img2,callback){
                tempCtx.drawImage(img1,0,0);
                var img1Data=tempCtx.getImageData(0,0,tempWidth,tempHeight).data;

                tempCtx.clearRect(0,0,tempWidth,height);

                tempCtx.drawImage(img2,0,0);
                var img2Data=tempCtx.getImageData(0,0,tempWidth,tempHeight).data;

                var times=30;

                var length=img1Data.length>img2Data.length?img1Data.length:img2Data.length;

                var iData=new Float32Array(length);
                    tempData=new Float32Array(length);
                for(var i=length;i--;){
                    iData[i]=(img2Data[i]-img1Data[i])/times;
                    tempData[i]=img1Data[i];
                }

                tempCtx.drawImage(img1,0,0);
                var draw=tempCtx.getImageData(0,0,tempWidth,tempHeight);
                var drawData=draw.data;
                var drawDataLength=drawData.length;

                function doit(i){
                    drawData[i]=tempData[i]+=iData[i];
                }

                tempCtx.clearRect(0,0,width,height);

                (function(){
                    if(!times){
                        callback();
                        return;
                    }
                    for(var i=drawDataLength;i--;){
                        doit(i);
                    }
                    ctx.putImageData(draw,0,-height);
                    times--;
                    setTimeout(arguments.callee,1000/30);
                })();
            }

            var i=0;
            (function(){
                animation(imgList[i],imgList[i+=1]||imgList[i=0],arguments.callee);
            })();
        }

        var imgLoaded=0;
        var onload=function(){
            imgLoaded++;
            if(imgLoaded==imgList.length){
                loaded();
            };
        }
        for(var i=imgList.length;i--;){
            var img=new Image();
            img.addEventListener('load',onload)
            img.src=imgList[i];
            imgList[i]=img;
        }
    </script>
</body>  
</html>  

另一种实现:HTML5 Canvas 图像渐变转场效果(低资源占用)