h5 canvas的一个例子


前言

因为工作内容上的需要,最近稍学习了一下h5的canvas使用,可以稍总结下。 假设现在需要绘制一个物体在某个带纹理的场景下的运动。


解析


step1:纹理的使用

  • API: CanvasRenderingContext2D.createPattern()
  • 使用:返回值CanvasPattern可作为当前的fillStyle,当进行绘制时,会在canvas上绘制出效果。
  • 注意点:对纹理的使用是需要Image的onload事件,它的作用是对图片进行预加载处理,即在图片加载完成后才立即除非其后function的代码体。这个是必须的,如果不写的话,画布将会显示黑屏。因为没有等待图片加载完成就填充纹理,导致浏览器找不到图片。


step2:运动的小球

做动画需要一个定时器,设定每间隔多少毫秒做一些改变。后来浏览器厂商提供了requestAnimationFrame()方法,它能从浏览器层面做一些动画渲染的优化。

  • API: window.requestAnimationFrame
  • 使用:虽然浏览器提供了方法,但这个方法并不会为我们做动画,也就是物体如何动是需要自己实现的。
  • 为什么要用它,看看这篇:web动画新选择:requestAnimationFrame
  • 注意点:比如模拟运动的小球,在每间隔时间绘制小球前需要清除画布上一次绘制的内容(不然画布上就是一堆小球),每次要用到ctx.clearRect(),如此我们就需要确保当前画布是可清除的(没有背景、纹理信息等)。


step3:多画布的使用

  • 我们可以对canvas标签的dom设置它的属性z-index,值越大离用户越近。
  • 场景:什么情况下需要使用多画布?从上一步我们可以知道,在做动画时每次绘制前需要清除画布,那如果我们在画布上有一些静态的背景或纹理,如何清除?这时,我们就可以使用多画布,将动静进行拆分。
  • 使用:(1)需要注意z-index 仅能在定位元素上奏效(例如 position:absolute;),不然画布无法重叠。(2)画布层数若是太多,需要注意渲染性能。


实例

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"><title>example</title>   

    <style>
    #backgroundCanvas{
        z-index:1;
        position:absolute;
    }
    #movingCanvas{
        z-index:2;
        position:absolute;
    }

    </style>
</head>
<body>
    <canvas id="backgroundCanvas"></canvas>
    <canvas id="movingCanvas"></canvas>

    <script>
        window.requestAnimFrame = (function() {
            return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                function(callback) {
                    window.setTimeout(callback, 1000 / 60);
                };
        })();


        var backgroundCanvas = document.getElementById('backgroundCanvas');
        backgroundCanvas.width = window.innerWidth;
        backgroundCanvas.height = window.innerHeight;
        var bctx = backgroundCanvas.getContext('2d');

        var img = new Image();
        img.src = "1.jpg";
        img.onload = function(){
            var woodfill = bctx.createPattern(img, "repeat");
            bctx.fillStyle = woodfill;
            bctx.fillRect(0,0,400,400);

            (function animloop(){
                requestAnimFrame(animloop);
                render();
            })();
        };

        var m2_x0=0; //横坐标变化位移
        var m2_eastward=true; //变量为真,横坐标变大
        function render(){
            var movingCanvas = document.getElementById("movingCanvas");
            var mctx = movingCanvas.getContext("2d");
            movingCanvas.width = window.innerWidth;
            movingCanvas.height = window.innerHeight;
            mctx.clearRect(0,0,movingCanvas.width,movingCanvas.height);
            mctx.beginPath();
            mctx.arc(95 + m2_x0, 50, 10,0,2*Math.PI);
            mctx.fillStyle="red";
            mctx.fill();
            mctx.stroke();
            if (m2_eastward) m2_x0++; else m2_x0--;
            if (m2_x0==200) m2_eastward=false;
            if (m2_x0==0) m2_eastward=true;
        }
    </script>
</body>
</html>


最后,另外安利一下

  • codepen,搜canvas,上面有一些很不错的例子。
  • CANVAS,感觉是个萌萌哒的妹纸写的canvas api教程
crystal /
Published under (CC) BY-NC-SA in categories 前端  tagged with canvas  html5