zoukankan      html  css  js  c++  java
  • 【重点突破】——Canvas技术绘制音乐播放器界面

    一、引言

    在用Canvas练习制作了验证码之后,还有一个用Canvas技术很综合的练习——制作音乐播放器。在做这个练习的过程中,还有一个重要的观察点,那就是理解Canvas的一大问题。

    二、要求 

    • 点击播放按钮,碟片开始旋转,背景音乐开始播放
    • 再次点击播放按钮,碟片停止旋转,背景音乐停止播放

    三、问题

    1、在canvas中放进4个图片请求,1、2、3、4,会以什么顺序加载?按顺序?

    实际:绝不会以顺序加载,因为,异步请求,会同时加载4张图片。

    所以:Canvas绘图中若需要多张图片,他们的加载都是异步的,无法预测哪一张先加载完成

     

    2、但是绘图往往需要按照一定的顺序,如先绘制背景,再绘上面的内容。怎么办?

    方法:必须等待所有图片全部加载完成,才能开始绘图

    四、实现

    思路:先在最外层定义一个变量 progress=0 表示所有图片的总加载进度;在每一个图片加载完成之后,按文件大小占总文件的比例分配权重,比如img1占20%,就给progress +=20;再然后,判断progress是否全等于100,等于100时,执行startDraw()函数,开始绘制图片,如果不等于,则不绘制;最后在最外层的底部,定义startDraw()函数。

    难点;如何为Canvas上的图形图像绑定事件监听?

    方法:只能绑定给整个Canvas!然后再具体计算事件发生坐标是否处于某个图像/图形的内部——仅适用于规则图形

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
        <style>
            body{
                text-align:center;
            }
        </style>
    </head>
    <body>
        <h3>Canvas制作音乐播放器</h3>
    
        <canvas id="c2"></canvas>
    
        <script>
            var progress = 0;//所有图片的总加载进度
    
            var imgBg = new Image();
            imgBg.src = 'image/bg.jpg';
            imgBg.onload = function(){
                console.log('1 背景图片加载完成');
                progress += 20;//按文件大小所占比例加权重
                if(progress===100){
                    stratDraw();
                }
            }
    
            var imgDisc = new Image();
            imgDisc.src = 'image/disc.png';
            imgDisc.onload = function(){
                console.log('2 封面图片加载完成');
                progress += 40;//按文件大小所占比例加权重
                if(progress===100){
                    stratDraw();
                }
            }
    
            var imgPlay = new Image();
            imgPlay.src = 'image/play.png';
            imgPlay.onload = function(){
                console.log('3 播放图片加载完成');
                progress += 20;//按文件大小所占比例加权重
                if(progress===100){
                    stratDraw();
                }
            }
    
            var imgPause = new Image();
            imgPause.src = 'image/pause.png';
            imgPause.onload = function(){
                console.log('4 暂停图片加载完成');
                progress += 20;//按文件大小所占比例加权重
                if(progress===100){
                    stratDraw();
                }
            }
    
            function stratDraw(){
                console.log('开始绘图……');
                var w = imgBg.width;
                var h = imgBg.height;
                //让画布的宽高与背景图一样
                c2.width = w;
                c2.height = h;
                var ctx = c2.getContext('2d');
    
                //1 绘制背景图
                 ctx.drawImage(imgBg, 0, 0);
                //2 绘制黑色的胶片
                 ctx.beginPath();
                 ctx.arc(w/2,h/2,120,0,2*Math.PI);//r,起始角0,终止角2*Math.PI
                 ctx.fill();
                //3 绘制胶片封面
                 var left = 120*Math.sin(Math.PI/4);
                 ctx.drawImage(imgDisc,w/2-left,h/2-left,2*left,2*left);
                //4 绘制播放和暂停按钮
                 ctx.drawImage(imgPlay, w/2-40, h-80,80,80);
    
                c2.onclick = function(e){
                    var ex = e.offsetX;
                    var ey = e.offsetY;
                    var rx = w/2;   //圆形按钮圆形坐标
                    var ry = h-40;
                    var r = 40;     //圆形按钮的半径
                    //计算两个点间距,是否小于圆形半径
                    if((Math.sqrt((ex-rx)*(ex-rx)+(ey-ry)*(ey-ry)))<r){
                        alert("按钮被点击了……")
                    }
                  }
             }
    
        </script>
    </body>
    </html>

    效果:


     注:转载请注明出处

  • 相关阅读:
    BeanUtils在web项目中的应用
    BeanUtils的日期问题
    使用BeanUtils组件
    调用数据库过程函数mysql
    sql注入
    如何取SO中的特性
    Read config detail from SO
    Parts-Ufida ERP project 1
    常用医疗英语
    April 24th 2020
  • 原文地址:https://www.cnblogs.com/ljq66/p/7622430.html
Copyright © 2011-2022 走看看