花潮论坛

搜索
热搜: 活动 交友 discuz
查看: 79|回复: 11

《起源》使用的播放器插件开发指引

[复制链接]
  • TA的每日心情
    慵懒
    2025-12-16 08:52
  • 签到天数: 1671 天

    [LV.Master]伴坛终老

    3050

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

    发表于 2022-12-19 21:03 | 显示全部楼层 |阅读模式

    请马上登录,朋友们都在花潮里等着你哦:)

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    《起源》一帖,播放器控制器使用纯画布制作。canvas是操作十分繁琐的HTML元素,它是个空板,需要JS(或其他语言)在上面一一绘制图形,还必须不停地擦除、重绘。

    帖子的播放器效果,只不过如下图,看上去简简单单:

    起源.png

    却:

    (一)进度条需要画两个长条矩形(也可以画线条);
    (二)画两处文本;
    (三)画一个圆;
    (四)画播放/暂停按钮需要绘制一个三角形、两个小矩形。

    这四样,如果单独画每一样,那都不是问题(ctx 是画笔):

    ——画矩形:ctx.fillRect(x,y,w,h); 其中,xy为矩形左上角坐标,w是矩形长度,h是矩形高度;
    ——画文本:ctx.fillText(text,x,y); 其中,text 是文本,xy是文本绘制的起点坐标;
    ——画圆:ctx.arc(x,y,r,0,2*Math.PI); 其中,xy是圆心坐标,r是圆半径,0是起始弧度,2*Math.PI 是结束弧度;
    ——画三角形:用画线方法 lineTo() 画三条前后衔接的封闭线即可,lineTo(x1,y1) 要先 moveTo(x,y)。

    可以将各种图形的画法封装成函数:

    //画矩形
    let drawRect = (x,y,ww,hh,color) => {
            ctx.beginPath();
            ctx.fillStyle = color;
            ctx.fillRect(x,y,ww,hh);
    };


    //画文本
    let drawTxt = (text,x,y,align,color) => {
            ctx.beginPath();
            ctx.font = '16px sans-serif';
            ctx.textAlign = align;
            ctx.textBaseline = 'middle';
            ctx.fillStyle = color;
            ctx.fillText(text,x,y);
    };


    //画圆
    let drawCircle = (x,y,r,color) => {
            ctx.beginPath();
            ctx.strokeStyle = color;
            ctx.lineWidth = 2;
            ctx.arc(x,y,r,0,2*Math.PI);
            ctx.stroke();
    };


    //画三角形
    let drawTriangle = (x,y,len,color) => {
            ctx.beginPath();
            ctx.fillStyle = color;
            ctx.moveTo(x,y);
            ctx.lineTo(x, y+len);
            ctx.lineTo(x+len, y + len/2);
            ctx.lineTo(x,y);
            ctx.fill();
    };


    然后将这些函数再封装成一个总封装。封装前为了方便设置一些交互所有变量,先声明一个对象用以存储用得上的变量:

    //创建 player 实体对象
    let player = {
            prog: 0,
            track: w,
            color: ['#ff0000','#a9a9a9'],
            cur: '00:00',
            dur: '00:00',
    };


    接下来才封装各种画法:

    //整体封装
    let drawAll = () => {
            ctx.clearRect(0,0,w,h);
            let btnColor = btnFlag ? player.color[0] : player.color[1]; //按钮颜色
            drawRect(0,10,w, 4, player.color[1]); // 画线 :track
            drawRect(0,10,player.prog, 4, player.color[0]); //画线 : prog
            drawTxt(player.cur,w/2-22,h-20,'right',player.color[1]); //文本 : 当前播放到
            drawCircle(w/2,h-20,16,btnColor); //圆环
            drawTxt(player.dur,w/2 + 22,h-20,'left',player.color[1]); //文本 : 总时长
            //暂停|播放按钮
            aud.paused ? drawTriangle(w/2-6,h-28,16,btnColor) : (drawRect(w/2-6, h-28,4,16,btnColor), drawRect(w/2+2, h-28,4,16,btnColor));
    };


    至此,运行函数 drawAll() 便能得出大概的播放控制器样式,前提是,我们需要补上一些声明和HTML相关标签(比如audio等)。

    以上代码只是揭示《起源》所用到的插件的核心代码制作。播放控制器的完整代码如下:

    1. <style>
    2. #papa { margin: auto; padding: 12px; width: 600px; height: 400px; color: red; border: 1px solid olive; position: relative; }
    3. #canv { position: absolute; left: calc(50% - 150px); top: calc(50% - 50px); }
    4. </style>

    5. <div id="papa">
    6.         <canvas id="canv" width="300" height="60"></canvas>
    7.         <audio id="aud" src="https://music.163.com/song/media/outer/url?id=2005217155.mp3" autoplay></audio>
    8. </div>

    9. <script>
    10. let ctx = canv.getContext('2d');
    11. let w = canv.width, h = canv.height;
    12. let btnFlag = false;

    13. let player = {
    14.         prog: 0,
    15.         track: w,
    16.         color: ['#ff0000','#a9a9a9'],
    17.         cur: '00:00',
    18.         dur: '00:00',
    19. };

    20. //画圆
    21. let drawCircle = (x,y,r,color) => {
    22.         ctx.beginPath();
    23.         ctx.strokeStyle = color;
    24.         ctx.lineWidth = 2;
    25.         ctx.arc(x,y,r,0,2*Math.PI);
    26.         ctx.stroke();
    27. };
    28. //画三角形
    29. let drawTriangle = (x,y,len,color) => {
    30.         ctx.beginPath();
    31.         ctx.fillStyle = color;
    32.         ctx.moveTo(x,y);
    33.         ctx.lineTo(x, y+len);
    34.         ctx.lineTo(x+len, y + len/2);
    35.         ctx.lineTo(x,y);
    36.         ctx.fill();
    37. };

    38. //画矩形
    39. let drawRect = (x,y,ww,hh,color) => {
    40.         ctx.beginPath();
    41.         ctx.fillStyle = color;
    42.         ctx.fillRect(x,y,ww,hh);
    43. };
    44. //画文本
    45. let drawTxt = (text,x,y,align,color) => {
    46.         ctx.beginPath();
    47.         ctx.font = '16px sans-serif';
    48.         ctx.textAlign = align;
    49.         ctx.textBaseline = 'middle';
    50.         ctx.fillStyle = color;
    51.         ctx.fillText(text,x,y);
    52. };

    53. //整体封装
    54. let drawAll = () => {
    55.         ctx.clearRect(0,0,w,h);
    56.         let btnColor = btnFlag ? player.color[0] : player.color[1]; //按钮颜色
    57.         drawRect(0,10,w, 4, player.color[1]); // track
    58.         drawRect(0,10,player.prog, 4, player.color[0]); //画线 : prog
    59.         drawTxt(player.cur,w/2-22,h-20,'right',player.color[1]); //文本 : 当前播放到
    60.         drawCircle(w/2,h-20,16,btnColor); //圆环
    61.         drawTxt(player.dur,w/2 + 22,h-20,'left',player.color[1]); //文本 : 总时长
    62.         //暂停|播放按钮
    63.         aud.paused ? drawTriangle(w/2-6,h-28,16,btnColor) : (drawRect(w/2-6, h-28,4,16,btnColor), drawRect(w/2+2, h-28,4,16,btnColor));
    64. };

    65. //时间信息格式化
    66. let toMin = (val) => {if (!val) return '00:00';val = Math.floor(val);let min = parseInt(val / 60), sec = parseFloat(val % 60);if (min < 10) min = '0' + min;if (sec < 10) sec = '0' + sec;return min + ':' + sec;};
    67. //鼠标指针滑过按钮判断依据
    68. let overBtn = (e) => Math.sqrt((e.offsetX-w/2) ** 2 + (e.offsetY-(h-20)) ** 2) < 16;
    69. //鼠标指针滑过进度条判断依据
    70. let overProg = (e) => e.offsetY > 0 && e.offsetY < 15;
    71. //鼠标指针滑过画布监视
    72. canv.onmousemove = (e) => {
    73.         canv.style.cursor = overBtn(e) || overProg(e) ? 'pointer' : 'default';
    74.         canv.title = overProg(e) ? toMin(e.offsetX*aud.duration/w) : '';
    75.         overBtn(e) ? (btnFlag = true,drawAll()) : (btnFlag = false,drawAll());
    76. }
    77. //按钮和进度条单击
    78. canv.onclick = (e) => {
    79.         if(overBtn(e)) {
    80.                 aud.paused ? aud.play() : aud.pause();
    81.                 drawAll();
    82.         }
    83.         if(overProg(e)) {
    84.                 aud.currentTime = aud.duration * e.offsetX / w;
    85.         }
    86. }
    87. //audio进度监视
    88. aud.addEventListener('timeupdate', () => {
    89.         player.prog = aud.currentTime * w /aud.duration;
    90.         player.cur = toMin(aud.currentTime);
    91.         player.dur = toMin(aud.duration);
    92.         drawAll();
    93. });

    94. drawAll();

    95. </script>
    复制代码



    评分

    参与人数 3威望 +130 金钱 +260 经验 +130 收起 理由
    红影 + 50 + 100 + 50 赞一个!
    小辣椒 + 50 + 100 + 50 赞一个!
    风中飞尘 + 30 + 60 + 30 很给力!

    查看全部评分

  • TA的每日心情
    奋斗
    2023-7-14 22:36
  • 签到天数: 59 天

    [LV.5]常住居民I

    37

    主题

    312

    回帖

    3596

    积分

    贵宾

    Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7Rank: 7

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪音画大师天籁妙音幸福快乐前途似锦花潮贵宾

    发表于 2022-12-19 21:39 | 显示全部楼层
    可以做不同样式的,,,效果更好看期待,
    对                         对
    人                         事
    随                         随
    缘                         心
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-12-16 08:52
  • 签到天数: 1671 天

    [LV.Master]伴坛终老

    3050

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

     楼主| 发表于 2022-12-19 22:53 | 显示全部楼层
    风中飞尘 发表于 2022-12-19 21:39
    可以做不同样式的,,,效果更好看期待,

    可以的。但这个是很基础,合适初级JS水平的爱好者学习
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2019-11-25 21:11
  • 签到天数: 1 天

    [LV.1]初来乍到

    1421

    主题

    6万

    回帖

    12万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀青草情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀男儿情怀鹰傲苍穹心香一瓣音画大师天籁妙音风雨同行我心永远喜乐安康中秋征文指尖上的流年花潮管理

    发表于 2022-12-19 23:04 | 显示全部楼层
    马黑黑 发表于 2022-12-19 22:53
    可以的。但这个是很基础,合适初级JS水平的爱好者学习

    谢谢黑黑分享,黑神太厉害了,一个接一个的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-12-16 08:52
  • 签到天数: 1671 天

    [LV.Master]伴坛终老

    3050

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

     楼主| 发表于 2022-12-19 23:20 | 显示全部楼层
    小辣椒 发表于 2022-12-19 23:04
    谢谢黑黑分享,黑神太厉害了,一个接一个的

    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-12-1 20:32
  • 签到天数: 1052 天

    [LV.10]以坛为家III

    1881

    主题

    32万

    回帖

    37万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女虎龙狗猪多彩人生星月交辉海样胸怀火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀相遇之美一往情深花好月圆心香一瓣紫色情节飞龙在天金剪刀天籁妙音妙笔生花风雨同行我心永远天长地久幸福快乐绚丽缤纷喜乐安康中秋征文周年庆指尖上的流年舞会之星分析(喊冤)章总结章杀人王小强章最佳杀刺临屏写诗七夕诗钟活动第五届风云第六届风云情人节花潮管理

    发表于 2022-12-20 02:16 | 显示全部楼层
    这个解说非常清晰,真的很适合我们这样没什么基础的,黑黑辛苦了
     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-12-1 20:32
  • 签到天数: 1052 天

    [LV.10]以坛为家III

    1881

    主题

    32万

    回帖

    37万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女虎龙狗猪多彩人生星月交辉海样胸怀火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀相遇之美一往情深花好月圆心香一瓣紫色情节飞龙在天金剪刀天籁妙音妙笔生花风雨同行我心永远天长地久幸福快乐绚丽缤纷喜乐安康中秋征文周年庆指尖上的流年舞会之星分析(喊冤)章总结章杀人王小强章最佳杀刺临屏写诗七夕诗钟活动第五届风云第六届风云情人节花潮管理

    发表于 2022-12-20 02:17 | 显示全部楼层
    一步步看下来,竟然看懂了,心里非常欢喜。谢谢
     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-12-16 08:52
  • 签到天数: 1671 天

    [LV.Master]伴坛终老

    3050

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

     楼主| 发表于 2022-12-20 10:07 | 显示全部楼层
    红影 发表于 2022-12-20 02:17
    一步步看下来,竟然看懂了,心里非常欢喜。谢谢

    用心就可以
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-12-1 20:32
  • 签到天数: 1052 天

    [LV.10]以坛为家III

    1881

    主题

    32万

    回帖

    37万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女虎龙狗猪多彩人生星月交辉海样胸怀火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀相遇之美一往情深花好月圆心香一瓣紫色情节飞龙在天金剪刀天籁妙音妙笔生花风雨同行我心永远天长地久幸福快乐绚丽缤纷喜乐安康中秋征文周年庆指尖上的流年舞会之星分析(喊冤)章总结章杀人王小强章最佳杀刺临屏写诗七夕诗钟活动第五届风云第六届风云情人节花潮管理

    发表于 2022-12-20 12:51 | 显示全部楼层

    这个简单又好看,真不错
     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-12-16 08:52
  • 签到天数: 1671 天

    [LV.Master]伴坛终老

    3050

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

     楼主| 发表于 2022-12-20 12:52 | 显示全部楼层
    红影 发表于 2022-12-20 12:51
    这个简单又好看,真不错

    虽简单,也需要一些知识积累做基础
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2025-12-1 20:32
  • 签到天数: 1052 天

    [LV.10]以坛为家III

    1881

    主题

    32万

    回帖

    37万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮美女虎龙狗猪多彩人生星月交辉海样胸怀火热情怀优雅迷人神秘浪漫缤纷心情草莓情怀蝴蝶情怀心曲飞扬星星情怀七彩绚丽活泼开朗女儿情怀相遇之美一往情深花好月圆心香一瓣紫色情节飞龙在天金剪刀天籁妙音妙笔生花风雨同行我心永远天长地久幸福快乐绚丽缤纷喜乐安康中秋征文周年庆指尖上的流年舞会之星分析(喊冤)章总结章杀人王小强章最佳杀刺临屏写诗七夕诗钟活动第五届风云第六届风云情人节花潮管理

    发表于 2022-12-20 16:46 | 显示全部楼层
    马黑黑 发表于 2022-12-20 12:52
    虽简单,也需要一些知识积累做基础

    是的,而且这个还可以有多重画法的可能,真棒。
     
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-12-16 08:52
  • 签到天数: 1671 天

    [LV.Master]伴坛终老

    3050

    主题

    13万

    回帖

    28万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9Rank: 9

    花潮帅哥鼠牛虎兔龙蛇马羊猴鸡狗猪多彩人生星月交辉奔放热烈海样胸怀春风拂面火热情怀优雅迷人神秘浪漫相遇之美鹰傲苍穹花好月圆紫色情节飞龙在天王者至尊大将风范音画大师天籁妙音共看流星风雨同行我心永远幸福快乐喜乐安康侠骨柔肠心想事成开朗大方花潮管理

     楼主| 发表于 2022-12-20 17:25 | 显示全部楼层
    红影 发表于 2022-12-20 16:46
    是的,而且这个还可以有多重画法的可能,真棒。

    还行
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|服务支持:DZ动力|huachaowang.com Inc. ( 蜀ICP备17032287号-1 )

    GMT+8, 2025-12-16 23:50 , Processed in 0.077516 second(s), 29 queries .

    Powered by Discuz! X3.4

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表