canvas基礎學習(三)

1、圖片加載控件javascript

在canvas效果製做中經常要使用多張圖片,爲了提升用戶體驗,須要給用戶提供一個圖片加載中的過分頁面效果。過分效果,我在項目中使用的是Sonic.js,它在git上的地址爲https://github.com/padolsey/Sonic,我的認爲它的樣式和擴展性都還不錯,使用方式也比較簡單。效果圖爲:java

調用代碼也比較簡單git

<script type="text/javascript" src="js/sonic.js"></script>
<script>
            var loading = new Sonic({
                width: 100,
                height: 100,
                stepsPerFrame: 1,
                trailLength: 1,
                pointDistance: .1,
                fps: 15,
                padding: 10,
                fillColor: '#fff',
                setup: function() {
                    this._.lineWidth = 20;
                },
                path: [
                    ['line', 0, 20, 100, 20],
                    ['line', 100, 20, 0, 20]
                ]
            });
            loading.play();
            document.body.appendChild(loading.canvas);
        </script>

下面是本身寫的一個圖片加載的工具方法github

(function(window,undefind){    //圖片加載控件
    function imgLoad(options){
        var defaults = {
            imgArr : [] ,        //圖片數組
            loadOverCallback : null        //加載完成的回調函數
        };
        var opts = $.extend(true , defaults , options || {}) ,
            imgSize = opts.imgArr.length , //須要加載圖片的個數
            completeSize = 0;
        function beginLoad() {
            for (var index in opts.imgArr) {
                var src = opts.imgArr[index];
                src && loadImg(src);
            }
        }
        function loadImg(src) {        //加載圖片
            var image = new Image(),
                handleLoadOver = function() {
                    completeSize++;
                    checkLoadOver();
                };
            image.src = src;
            if (image.complete) { //圖片有緩存
                handleLoadOver();
            } else {
                image.onload = function() { //圖片獲取成功
                    handleLoadOver();
                };
            }
        }
        function checkLoadOver() {    //查詢是否已經加載完畢
            if (completeSize != imgSize) return;
            if(opts.loadOverCallback && typeof opts.loadOverCallback === "function"){
                opts.loadOverCallback();
            }
        }
        beginLoad()//開始執行
    }
    window.imgLoad = imgLoad;
})(window);

代碼的邏輯就是把須要加載的圖片url,以數組的形式傳入,而後經過new Image()對象進行加載,每加載完畢一個執行一次檢查是否完畢的函數,當全部圖片所有加載完則執行結束的回調函數。調用方法爲:web

window.imgLoad({
        imgArr : [
            "img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg", "img/5.jpg"
        ],    
        loadOverCallback : function(){
            //結束操做....
        }
    });

 

2、指定元素上飄雪、綵帶、星星的效果canvas

 

(function(window , document , undefind){        //canvas特效
    function canvasEffect(options) {
        var defaults = {
            ele :  document.getElementById("body"),  //覆蓋元素
            type : "snow" ,  //snow爲雪花,band爲綵帶,star爲星星
            particleMax : 200 ,     //元素最大數
            particleCount : 100 , //使用元素數目
            bandColorArr : ["#82F269", "#F61326", "#F6F313", "#518DF6"] , //綵帶顏色數組
            vy : 1 ,    //Y軸上的運動速度
            vyFloat : 1.5 ,        //Y軸速度浮動的係數
            vx : 0.5 ,    //X軸上的運動速度
            vxFloat : 1 ,        //X軸速度浮動的係數
            w : 8 , //元素的寬度
            wFloat : 2 ,     //寬度的浮動係數
            h : 12 , //元素的高度
            hFloat : 4 , //高度的浮動係數
            o : 0.4 , //元素的透明度
            oFloat : 0.5 ,    //透明度的浮動係數
            r : 1 ,    //半徑
            rFloat : 2    ,//半徑的浮動值
            snowColor : "#FFF"    //雪花的顏色
        }
        var opts = $.extend(true, defaults, options || {});
        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            width = opts.ele.clientWidth,
            height = opts.ele.clientHeight,
            i = 0 , active = false , objFlakes = [] , objFlake,
            lastDate = 0 , dateDel = 0 ,  isChange = false;
        var starPic = new Image();
        starPic.src = "img/star.png";
        canvas.style.position = 'absolute';
        canvas.style.left = canvas.style.top = '0';
        var Objflake = function() {
            this.reset();    //初始化
        };
        Objflake.prototype.reset = function() {
            this.x = Math.random() * width;
            this.y = Math.random() * -height;
            this.vy = opts.vy + Math.random()*opts.vyFloat;
            this.vx = opts.vx - Math.random()*opts.vxFloat;
            this.w = opts.w + Math.random()*opts.wFloat;
            this.h = opts.h + Math.random()*opts.hFloat;
            this.o = opts.o + Math.random()*opts.oFloat;
            this.color = opts.bandColorArr[parseInt(Math.random() * opts.bandColorArr.length)];
            this.c = Math.random() > 0.5 ? 1 : -1;
            this.r = opts.r + Math.random()*opts.rFloat;
            this.picNo = Math.floor(Math.random() * 7);
        };
        function generatebandFlakes() {    //初始化元素個數
            objFlakes = [];
            for (i = 0; i < opts.particleMax; i++) {
                objFlake = new Objflake();
                objFlake.reset();
                objFlakes.push(objFlake);
            }
        }
        function update() {    //更新
            ctx.clearRect(0, 0, width, height);
            if (!active) {
                return;
            }
            if(opts.type == "star"){
                var nowDate = Date.now();
                dateDel += nowDate - lastDate;
                lastDate = nowDate;
                isChange = (dateDel > 60);
                if(isChange){
                    dateDel = 0;
                }
            }
            for (i = 0; i < opts.particleCount; i++) {
                objFlake = objFlakes[i];
                objFlake.y += objFlake.vy;
                objFlake.x += objFlake.vx;
                if(opts.type == "snow"){
                    drawSnow(objFlake.x, objFlake.y, objFlake.r , objFlake.o);
                }else if(opts.type == "band"){
                    drawBand(objFlake.x, objFlake.y, objFlake.color, objFlake.w,
                        objFlake.h, objFlake.c, objFlake.o);
                }else if(opts.type == "star"){
                    if(isChange){
                        objFlake.picNo += 1;
                        objFlake.picNo = objFlake.picNo%7;
                    }
                    ctx.drawImage(starPic, objFlake.picNo * 7, 0, 7, 7, objFlake.x, objFlake.y, 7, 7);
                }
                if (objFlake.y > height) {
                    objFlake.reset();
                }
            }
            requestAnimFrame(update);
        }
        //畫綵帶
        function drawBand(x, y, color, w, h, c, alpha, isRotate, rotatePI) {
            var leakdep = h < 10 ? 2 : 8;
            var leak = c > 0 ? leakdep : -(leakdep);
            ctx.save();
            ctx.fillStyle = color;
            ctx.globalAlpha = alpha;
            ctx.beginPath();
            ctx.moveTo(x, y - h);
            ctx.lineTo(x + w, y - h);
            ctx.quadraticCurveTo(x + w + c, y - h / 2, x + w + leak, y);
            ctx.lineTo(x + leak, y);
            ctx.quadraticCurveTo(x + c, y - h / 2, x, y - h);
            ctx.fill();
            ctx.closePath();
            ctx.restore();
        }
        //畫雪花
        function drawSnow(x  , y  , r , o){
            ctx.save();
            ctx.fillStyle = opts.snowColor;
            ctx.globalAlpha = o;
            ctx.beginPath();
            ctx.arc(x , y , r , 0, Math.PI * 2, false);
            ctx.fill();
            ctx.closePath();
            ctx.restore();
        }
        function onResize() {
            width = opts.ele.clientWidth;
            height = opts.ele.clientHeight;
            canvas.width = width;
            canvas.height = height;
            lastDate = Date.now();
            var wasActive = active;
            active = width > 300;
            if (!wasActive && active) {
                requestAnimFrame(update);
            }
        }
        window.requestAnimFrame = (function() {
            return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                function(callback) {
                    window.setTimeout(callback, 1000 / 60);
                };
        })();
        generatebandFlakes();
        onResize();
        opts.ele.appendChild(canvas);
        window.addEventListener('resize', onResize, false);
    }
    window.canvasEffect = canvasEffect;
})(window,document);

代碼如上,邏輯就是在指定的ele元素上,建立一個canvas標籤,高寬同ele元素,在這個畫布上繪製雪花、綵帶或者星星圖片,根據動畫函數requestAnimationFrame函數以及預先定義好的x,y軸方向的速度,進行一幀一幀的繪製,每一幀的x,y座標發生變化,進行產生動畫效果。星星的圖片爲數組

調用方式以下:緩存

一、星星app

window.canvasEffect({
            ele : document.getElementsByTagName("body")[0] ,  
            type : "star" , 
            particleMax : 300 ,     
            particleCount : 150 ,
            vy : 0.3 ,
            vyFloat : 0.3 ,        
            vx : 0.3 ,    
            vxFloat : 0.6 ,        
            o : 0.3 ,
            oFloat : 0.3 ,    
        });

效果圖爲:dom

 

二、綵帶

window.canvasEffect({
            ele : $("body")[0] ,  
            type : "band" , 
            particleMax : 200 ,     
            particleCount : 100 ,
            bandColorArr : ["#82F269", "#F61326", "#F6F313", "#518DF6"] , 
            w : 8 , 
            wFloat : 2 ,     
            h : 12 , 
            hFloat : 4 , 
            o : 0.4 ,
            oFloat : 0.5 ,    
            r : 1 ,    
            rFloat : 2    
        });

效果圖爲:

 

三、雪花

window.canvasEffect({
            ele : $("body")[0] ,  
            type : "snow" , 
            particleMax : 200 ,     
            particleCount : 100 ,
            o : 0.4 ,
            oFloat : 0.5 ,    
            r : 1 ,    
            rFloat : 2    
        });

效果圖爲:

 

demo的下載放到csdn上去了,地址爲

http://download.csdn.net/detail/hufengsky123/9337827

相關文章
相關標籤/搜索