zoukankan      html  css  js  c++  java
  • 【实例】html5-canvas中实现背景图片的移动

    本例来自于《HTML5 Canvas核心技术 图形、动画与游戏开发》

    在线演示 (图有点多,请多刷新几次)

    本例还有一点代码不理解,我用注释和问号标注出来了,有大神看到求解答,谢谢

    本例子难点主要在通过当前的FPS计算图像下一帧的显示坐标,这也是我不理解的地方

    还有就是requestAnimationFrame这个,这个是用来以浏览器最合适的方式循环执行一些代码

    [html] view plain copy
     
     print?
    1. <!DOCTYPE html>  
    2. <html>  
    3.     <head>  
    4.         <meta charset="utf-8">  
    5.         <title>图片运动实例</title>  
    6.         <style type="text/css">  
    7.             body {  
    8.                 background: #DDDDDD;  
    9.             }  
    10.             #canvas {  
    11.                 border: thin solid black;  
    12.             }  
    13.             input {  
    14.                 margin-left: 15px;  
    15.             }  
    16.         </style>  
    17.     </head>  
    18.     <body>  
    19.         <canvas id="canvas" width="1000" height="440">  
    20.             您的浏览器不支持canvas,请更新到最新的浏览器  
    21.         </canvas>  
    22.         <input type="button" name="animateButton" id="animateButton" value="运动" />  
    23.         <hr />  
    24.         <div>  
    25.             <table border="1" cellspacing="" cellpadding="">  
    26.                 <tr>  
    27.                     <td>FPS</td>  
    28.                     <td><span id="FPS"></span></td>  
    29.                 </tr>  
    30.                 <tr>  
    31.                     <td>SKY_VELOCITY/fps</td>  
    32.                     <td><span id="SKY_VELOCITY"></span></td>  
    33.                 </tr>  
    34.                 <tr>  
    35.                     <td>GRASS_VELOCITY/fps</td>  
    36.                     <td><span id="GRASS_VELOCITY"></span></td>  
    37.                 </tr>  
    38.                 <tr>  
    39.                     <td>TREE_VELOCITY/fps</td>  
    40.                     <td><span id="TREE_VELOCITY"></span></td>  
    41.                 </tr>  
    42.                 <tr>  
    43.                     <td>FAST_TREE_VELOCITY/fps</td>  
    44.                     <td><span id="FAST_TREE_VELOCITY"></span></td>  
    45.                 </tr>  
    46.                   
    47.             </table>  
    48.         </div>  
    49.     </body>  
    50.     <script type="text/javascript">  
    51.       
    52.         var canvas = document.getElementById("canvas"),  
    53.             context = canvas.getContext("2d"),  
    54.             animateButton = document.getElementById("animateButton"),  
    55.               
    56.             //创建多个图像对象  
    57.             sky = new Image(),  
    58.             tree = new Image(),  
    59.             nearTree = new Image(),  
    60.             grass = new Image(),  
    61.             grass2 = new Image(),  
    62.             redRect = new Image,  
    63.               
    64.               
    65.             paused = true,  
    66.             lastTime = 0,   
    67.             fps = 0,    //当前的帧速率  
    68.               
    69.             //都是不同图像  
    70.             skyOffset = 0,  
    71.             grassOffset = 0,  
    72.             treeOffset = 0,  
    73.             nearTreeOffset = 0,  
    74.               
    75.             TREE_VELOCITY = 20,  
    76.             FAST_TREE_VELOCITY = 40,  
    77.             SKY_VELOCITY = 8,  
    78.             GRASS_VELOCITY = 75;  
    79.           
    80.         //以下是检测对象  
    81.         var SKY_VELOCITYFps = document.getElementById("SKY_VELOCITY");  
    82.         var GRASS_VELOCITYFps = document.getElementById("GRASS_VELOCITY");  
    83.         var TREE_VELOCITYFps = document.getElementById("TREE_VELOCITY");  
    84.         var FAST_TREE_VELOCITYFps = document.getElementById("FAST_TREE_VELOCITY");  
    85.         var FPS = document.getElementById("FPS");  
    86.               
    87.         //擦除方法  
    88.         function erase() {  
    89.             context.clearRect(0, 0, canvas.width, canvas.height);             
    90.         }  
    91.           
    92.         function draw() {  
    93.             context.save();  
    94.               
    95.             //fps是共用的  
    96.               
    97.             //应该是确定当前图像位置的坐标X  
    98.             //???以下四行还是有点不太理解,只知道这个可以用来循环的显示image对象,至于SKY_VELOCITY/fps是什么还不清楚  
    99.             skyOffset = skyOffset canvas.width ? skyOffset + SKY_VELOCITY/fps : 0;  
    100.             grassOffset = grassOffset canvas.width ? grassOffset + GRASS_VELOCITY/fps : 0;  
    101.             treeOffset = treeOffset canvas.width ? treeOffset + TREE_VELOCITY/fps : 0;  
    102.             nearTreeOffset = nearTree canvas.width ? nearTree + FAST_TREE_VELOCITY/fps : 0;  
    103.               
    104.             //检测数据  
    105.             SKY_VELOCITYFps.innerHTML = SKY_VELOCITY/fps;  
    106.             GRASS_VELOCITYFps.innerHTML = GRASS_VELOCITY/fps;  
    107.             TREE_VELOCITYFps.innerHTML = TREE_VELOCITY/fps;  
    108.             FAST_TREE_VELOCITYFps.innerHTML = FAST_TREE_VELOCITY/fps;  
    109.             FPS.innerHTML = fps;  
    110.               
    111.             //像下面几行这样写的后果:canvas运动到后面的时候就可能没有图像对象了  
    112. //          skyOffset += SKY_VELOCITY/fps;  
    113. //          grassOffset += GRASS_VELOCITY/fps;  
    114. //          treeOffset += TREE_VELOCITY/fps;  
    115. //          nearTreeOffset += FAST_TREE_VELOCITY/fps;  
    116.               
    117.             //开始绘制天空  
    118.             context.save();  
    119.             //改变坐标原点  
    120.             context.translate(-skyOffset, 0);  
    121.             //绘制一个天空  
    122.             context.drawImage(sky, 0, 0);  
    123.             //在即将天空结尾的时候在绘制一个天空用来衔接  
    124.             context.drawImage(sky, sky.width-2, 0);  
    125.             //将改变的坐标原点改回来  
    126.             context.restore();  
    127.               
    128.             //开始绘制远处的树  
    129.             //此处绘制的位置有的地方出现在canvas.width之外  
    130.             context.save();  
    131.             //改变坐标原点  
    132.             context.translate(-treeOffset, 0);  
    133.             //以改变原点后的坐标上绘制好多个树  
    134.             context.drawImage(tree, 100, 240);  
    135.             context.drawImage(tree, 1100, 240);  
    136.             context.drawImage(tree, 400, 240);  
    137.             context.drawImage(tree, 1400, 240);  
    138.             context.drawImage(tree, 700, 240);  
    139.             context.drawImage(tree, 1700, 240);  
    140.             //恢复坐标原点  
    141.             context.restore();  
    142.               
    143.             //绘制近处的树木,他的运行速度更加的块  
    144.             context.save();  
    145.             context.translate(-nearTreeOffset, 0);  
    146.             context.drawImage(nearTree, 250, 220);  
    147.             context.drawImage(nearTree, 1250, 220);  
    148.             context.drawImage(nearTree, 800, 220);  
    149.             context.drawImage(nearTree, 1800, 220);  
    150.             context.restore();  
    151.               
    152.               
    153.               
    154.             //绘制绿地  
    155.             context.save();  
    156.             context.translate(-grassOffset, 0);  
    157.             //在canvas底部绘制草地image对象  
    158.             context.drawImage(grass, 0, canvas.height-grass.height);  
    159.             context.drawImage(grass, grass.width, canvas.height-grass.height);  
    160.             context.drawImage(grass2, 0, canvas.height-grass2.height);  
    161.             context.drawImage(grass2, grass2.width, canvas.height-grass2.height);  
    162.             context.restore();  
    163.               
    164.         }  
    165.           
    166.         //计算当前的FPS  
    167.         function calculateFps(now) {  
    168.             //1000毫秒除以距离上一次计算FPS的时间意思是,或者距离上一次绘制图像  
    169.             //这段时间里面执行了多少次  
    170.             //除以1000是因为now和lastTime都是以毫秒为单位的  
    171.             //反正fps就是一秒内能够执行绘制多少次嘛~所以的  
    172.             var fps = 1000 / (now - lastTime);  
    173.             lastTime = now;  
    174.             return fps;  
    175.         }  
    176.           
    177.         function animate(now) {  
    178.             //如果当前时间还没有定义  
    179.             if(now === undefined) {  
    180.                 //就把当前时间赋值给now  
    181.                 now = +new Date;  
    182.             }  
    183.             fps = calculateFps(now);  
    184.               
    185.             //只要不是暂停状态就执行  
    186.             if(!paused) {  
    187.                 //擦除canvas  
    188.                 //原例子中是用兼容的手法实现requestAnimationFrame,所以需要erase  
    189. //              erase();  
    190.                 //马上绘制新的  
    191.                 draw();  
    192.             }  
    193.             //以最适合的速度执行animate中的内容,这个比较适合动画的处理,类似于setTimeout  
    194.             requestAnimationFrame(animate);  
    195.         }  
    196.           
    197.         animateButton.onclick = function(e) {  
    198.             paused = paused ? false : true;  
    199.             if(paused) {  
    200.                 animateButton.value = "运动";  
    201.             } else {  
    202.                 animateButton.value = "暂停";  
    203.             }  
    204.         };  
    205.           
    206. //      canvas.width = canvas.width;  
    207. //      canvas.height = canvas.height;  
    208.         sky.src = "sky.png";  
    209.         tree.src = "smalltree.png";  
    210.         nearTree.src = "tree-twotrunks.png";  
    211.         grass.src = "grass.png";  
    212.         grass2.src = "grass2.png";  
    213.           
    214.         sky.onload = function(e) {  
    215.             draw();  
    216.         };  
    217.           
    218. //      requestAnimationFrame(animate);  
    219.         //启动  
    220.         animate();  
    221.     </script>  
    222. </html>  
  • 相关阅读:
    vue中动态数据使用wowjs显示动画
    vue 切换路由页面不在最顶部
    dp,.单词的划分
    二分建火车站
    .最大上升子序列和
    饥饿的奶牛(不重区间最大值)
    F. 1.小W 的质数(prime)(欧拉筛)
    月月给华华出题
    积性函数
    垒石头(排序+dp)
  • 原文地址:https://www.cnblogs.com/wangluochong/p/5814334.html
Copyright © 2011-2022 走看看