zoukankan      html  css  js  c++  java
  • 原生js实现歌词本

    /**
    * Created by Administrator on 2017/4/30.
    */
    // 1. 歌词在一个矩形区域内显示
    // 2. 当前歌词行高亮
    // 3. 在矩形显示区域中部固定位置显示当前歌词行
    // 4. 当前歌词行切换到下一行时,下一行歌词高亮,并逐步移动到当前歌词行位置
    // 5. 初始显示时歌词第一行顶住显示区域,当前歌词行未到达显示矩形区域的中部固定高亮位置时,不需要移动
    // 6. 歌词尾行到达显示区域后,不需要移动
    // 7. 用户可通过鼠标或者滚动条滚动歌词
    // 8. 用户滚动歌词后,若当前歌词行被移动到矩形显示区域外,下一行歌词需定位到当前歌词行位置


    <!DOCTYPE HTML>
    <html lang=zh-cn>
    <head>
    <meta charset=utf-8>
    <title>滚动歌词demo</title>
    <style>
    * {
    margin: 0px;
    padding: 0px;
    }

    body {
    100%;
    height: 100%;
    overflow: hidden;
    }

    .box {
    margin: 100px auto 0 auto;
    400px;
    }

    .lrc {
    position: relative;
    300px;
    height: 200px;
    overflow-y: auto;
    background-color: #ccc
    }

    .lrc li {
    display: block;
    padding: 5px 0;
    }

    .z-crt {
    color: #0f0;
    }

    .ctrl {
    margin: 0 auto;
    padding-left: 100px;
    300px;
    }
    </style>
    </head>
    <body>
    <div class="box">
    <audio id="bgMusic" src="yichangyouxiyichagmeng.mp3"></audio>
    </div>
    <div class="box" id="box">
    <ul class="lrc" id="lrc">
    </ul>
    </div>
    <script language="javascript">
    function playMusic() {
    // 经解析后的歌词
    var __lis = [{"offset": 500, "text": "一场游戏一场梦"},
    {"offset": 1000, "text": "演唱:王杰"},
    {"offset": 3000, "text": "不要谈什么分离"},
    {"offset": 6000, "text": "我不会因为这样而哭泣"},
    {"offset": 8000, "text": "那只是昨夜的一场梦而已"},
    {"offset": 9000, "text": "不要说愿不愿意"},
    {"offset": 12000, "text": "我不会因为这样而在意"},
    {"offset": 14000, "text": "那只是昨夜的一场游戏"},
    {"offset": 15000, "text": "那只是一场游戏一场梦"},
    {"offset": 18000, "text": "虽然你影子还出现我眼里"},
    {"offset": 24000, "text": "在我的歌声中早已没有你"},
    {"offset": 25000, "text": "只是一场游戏一场梦"},
    {"offset": 26000, "text": "不要把残缺的爱留在这里"},
    {"offset": 30000, "text": "在俩个人的世界里不该有你"},
    {"offset": 32000, "text": "oh.为什么道别离说什么在一起"},
    {"offset": 33000, "text": "如今虽然没有你我还是我自己"},
    {"offset": 35000, "text": "说什么此情永不愈"},
    {"offset": 36000, "text": "说什么我爱你"},
    {"offset": 38000, "text": "如今依然没有你我还是我自己"},
    {"offset": 39000, "text": "那只是一场游戏一场梦"},
    {"offset": 40000, "text": "虽然你影子还出现我眼里"},
    {"offset": 42000, "text": "在我的歌声中早已没有你"},
    {"offset": 44000, "text": "只是一场游戏一场梦"},
    {"offset": 46000, "text": "不要把残缺的爱留在这里"},
    {"offset": 48000, "text": "在俩个人的世界里不该有你"},
    {"offset": 50000, "text": "oh.为什么道别离说什么在一起"},
    {"offset": 52000, "text": "说什么此情永不愈"},
    {"offset": 54000, "text": "说什么我爱你"},
    {"offset": 56000, "text": "如今依然没有你我还是我自己"},
    {"offset": 58000, "text": "为什么道别离说什么在一起"},
    {"offset": 60000, "text": "如今虽然没有你我还是我自己"},
    {"offset": 62000, "text": "说什么此情永不愈"},
    {"offset": 64000, "text": "说什么我爱你"},
    {"offset": 66000, "text": "如今依然没有你我还是我自己"}];

    var __eul = document.getElementById("lrc");
    (function () {
    for (var i = 0; i < __lis.length; i++) {
    var eli = document.createElement("li");
    eli.innerText = __lis[i].text;
    __eul.appendChild(eli);
    }
    })();

    var __freq = 30; // 滚动频率(ms)
    var __fraction = 2 / 5; // 高亮显示行在歌词显示区域中的固定位置百分比

    /**
    * 当前歌词行(lineno)滚动
    */
    var __go = function (_lineno) {
    var _time;
    if (_lineno === 0) {
    _time = __lis[_lineno].offset;
    } else {
    _time = __lis[_lineno].offset - __lis[_lineno - 1].offset;
    }
    var _timer = setTimeout(__go.bind(this, _lineno + 1), _time);

    // 高亮下一行歌词
    if (_lineno > 0) {
    __eul.children[_lineno - 1].setAttribute("class", "");
    }
    var _ep = __eul.children[_lineno];
    _ep.setAttribute("class", "z-crt");

    // 满足需求5,6
    var _scrollTop;
    if (_ep.offsetTop < __eul.clientHeight * __fraction) {
    _scrollTop = 0;
    } else if (_ep.offsetTop > (__eul.scrollHeight - __eul.clientHeight * (1 - __fraction))) {
    _scrollTop = __eul.scrollHeight - __eul.clientHeight;
    } else {
    _scrollTop = _ep.offsetTop - __eul.clientHeight * __fraction;
    }

    // 如用户拖动滚动条导致当前显示行超出显示区域范围,下一行直接定位到当前显示行
    if (__eul.scrollTop > (_scrollTop + __eul.clientHeight * __fraction)
    || (__eul.scrollTop + __eul.clientHeight * __fraction) < _scrollTop) {
    __eul.scrollTop = _scrollTop;
    } else { // 单行滚动
    // 获取滚动步长
    var _step = Math.ceil(Math.abs(__eul.scrollTop - _scrollTop) / (_time / __freq));
    __scroll(__eul.scrollTop, _scrollTop, _step);
    }

    };
    /**
    * 歌词单行滚动实现
    */
    __scroll = function (_crt, _dst, _step) {
    if (Math.abs(_crt - _dst) < _step) {
    return;
    }
    if (_crt < _dst) {
    __eul.scrollTop += _step;
    _crt += _step;
    } else {
    __eul.scrollTop -= _step;
    _crt -= _step;
    }
    setTimeout(__scroll.bind(this, _crt, _dst, _step), __freq);
    };

    __go(0);

    }

    setTimeout(playMusic, 36000);

    //背景音乐播放
    /* function audio3() {
    var a = document.getElementById('bgMusic');
    a.play();
    }
    audio3();*/
    </script>
    </body>
    </html>

  • 相关阅读:
    把VB.NET代码转换为C#代码的方法
    离散数学 第二章 谓词逻辑 26 前束范式
    离散数学 第二章 谓词逻辑 27 谓词演算的推理理论
    asp.net中怎样用Javascript控制RequiredFieldValidator控件什么时候启用,什么时候不启用验证?
    离散数学中的IFF标记
    BIRT Overview
    离散数学 第二章 谓词逻辑 25 谓词演算的等价式和蕴涵式
    getRemoteAddr()和getRemoteHost()的区别
    scp 不用密码
    利用spring实现javamail功能
  • 原文地址:https://www.cnblogs.com/bgxiaoniu/p/6790557.html
Copyright © 2011-2022 走看看