亚伦影音工作室 发表于 2023-12-28 22:04

添加频谱更热闹【多项控制】

本帖最后由 亚伦影音工作室 于 2024-3-7 08:49 编辑 <br /><br /><style>
#papa {
      margin: 120px-300px;
      width: 1164px;
      height: 620px;
      background:#000000 url('https://pic.imgdb.cn/item/658d19f6c458853aef55c1ac.jpg')no-repeat center/cover;
      box-shadow: 0px 0px 0px 2px #cccccc, 0px 0px 0px 8px #880000; position: relative; overflow: hidden;
      display: grid;
      place-items: center;
      }

#lrc {
      --state: paused;
      --motion: cover2;
      --tt: 2s;
      --bg: url('https://pic.imgdb.cn/item/658d19f6c458853aef55c1ac.jpg')no-repeat center/cover;
      position: absolute;z-index: 6;
      left: 48%;
      transform: translate(-52%);
      top: 86%;
      font:normal 3em 华文新魏;
color: #000080;
      
      -webkit-background-clip: text;
      filter:drop-shadow(#FFFFFF 1px 0 0)drop-shadow(#FFFFFF 0 1px 0)drop-shadow(#FFFFFF -1px 0 0) drop-shadow(#FFFFFF 0 -1px0);
}
#lrc::before {
      position: absolute;
      content: attr(data-lrc);
      width: 20%;
      height: 100%;
      color: transparent;
      overflow: hidden;
      white-space: pre;
      background: var(--bg);
-webkit-background-clip: text;
      animation: var(--motion) var(--tt) linear forwards;
      animation-play-state: var(--state);
}
@keyframes cover1{0% { width: 0%;}100% { width: 100%;}}
@keyframes cover2 { 0% { width: 0%;}100% { width: 100%;}}
#canv {display: block; position: absolute;width:100%; height: 200px; bottom: 0px; left: 0px;z-index:1 ; animation: sp 1s linear infinite;}
@keyframes sp {
      0% { filter:hue-rotate(360deg)contrast(150%)brightness(100%); }
}
#bt{width: 200px; overflow: hidden; color: lightgreen; position: absolute; left:6%;top:13%;font-size: 15px; z-index: 9;}
#canv {display: block; position: absolute;width:100%; height: 200px; bottom: 0px; left: 0px;z-index:4 ; animation: sp 1s linear infinite;}
@keyframes sp {
      0% { filter:hue-rotate(360deg)contrast(150%)brightness(100%); }
}
</style>

<div id="papa">

<css-doodle id="mplayer">
      :doodle {z-index:80 ;
                @grid: 2 / 260px 60px;
                position: absolute;
                color: var(--color);
                bottom: 87%;left: 5%;
                --prog: 0%; --size: 40px; --ttmsg1: '00:00'; --ttmsg2: '00:00'; --color: lightgreen; --state: paused;
      }
      /* 时间信息 : 左 */
      @nth(1) {
                @place: 10% 80%;
                :after { content: var(--ttmsg1); }
      }
      /* 控制器 */
      @nth(2) {
                @size: var(--size);
                @shape: windmill;
                @place: 45% 35%;
                background: var(--color);
                animation: rot 6s infinite linear var(--state);
      }
      /* 时间信息 : 右 */
      @nth(3) {
                @place: 80% 80%;
                :after { content: var(--ttmsg2); }
      }
      /* 进度条 */
      @nth(4) {
                @place: 40% 80%;
                @size: 100% 2px;
                background: #bbb;
                display: grid;
                place-items: center start;
                :before {
                        content: '';
                        width: var(--prog);
                        height: 100%;
                        background: var(--color);
                }
      }
      @keyframes rot { to { transform: rotate(1turn); } }

</css-doodle>

<div id="眼睛">
      <div id="舞台">
                <span class="演员"></span>
                <span class="演员"></span>
                <span class="演员"></span>
                <span class="演员"></span>
                <span class="演员"></span>
                <span class="演员"></span>
      </div>
</div>

<div data-lrc="爱的路上烟雨蒙蒙 - 赵洋" id="lrc">爱的路上烟雨蒙蒙 - 赵洋</div>
<canvas id='canv' width="1200" height="250"></canvas>
<audio id="aud" src="https://www.qqmc.com/mp3/music327680381.mp3" autoplay loopcrossOrigin="anonymous"></audio>
<span id="bt">爱的路上烟雨蒙蒙 - 赵洋</span>
</div>

<script>
(function() {
      let clickIdx = 0, progChg = 0, cursors = ['default','pointer','pointer'];
      let script = document.createElement('script');
      script.src = 'https://638183.freep.cn/638183/web/api/css-doodle.js';
      document.head.appendChild(script);
      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;};
      let mState = () => mplayer.style.setProperty('--state', aud.paused ? 'paused' : 'running');
      aud.addEventListener('play', mState, false);
      aud.addEventListener('pause', mState, false);
      aud.addEventListener('timeupdate', () => {
                mplayer.style.setProperty('--ttmsg1', `'${toMin(aud.currentTime)}'`);
                mplayer.style.setProperty('--ttmsg2', `'${toMin(aud.duration)}'`);
                mplayer.style.setProperty('--prog',`${100 * aud.currentTime / aud.duration}%`)
      });

      mplayer.onclick = () => {
                if(clickIdx === 1) aud.paused ? aud.play() : aud.pause();
                if(clickIdx === 2) aud.currentTime = progChg;
      }
      mplayer.onmousemove = (e) => {
                let size = parseInt(window.getComputedStyle(mplayer).getPropertyValue('--size')), ww = mplayer.offsetWidth, hh = mplayer.offsetHeight;
                clickIdx = e.offsetY > hh/1.5 ? 2 : (e.offsetX > (ww - size)/2 && e.offsetX < (ww + size)/2 && e.offsetY < hh/1.5 ? 1 : 0);
                mplayer.style.cursor = cursors;
                if(clickIdx > 1) progChg = aud.duration * e.offsetX / ww;
      }
})();
</script>
<script >
(function() {
/*原始lrc歌词*/
let lrcStr = `爱的路上烟雨蒙蒙 - 赵洋
词:雨袂独舞
曲:赵洋
编曲:可心文化娱乐工作室
原唱:赵洋
混音:可心文化娱乐工作室
制作人:亚伦
监制:赵峰
出品人:亚伦
出品:亚伦影音工作室

夜晚的风让思念汹涌
酒没喝空却灼伤了喉咙
如今心情不由自己掌控
你不在呼吸都开始疼痛
闭上眼睛不见你入梦
我的情浓为何没人来宠
穿越人海我只对你心动
而你却总惹我眼眶泛红
爱的路上 烟雨蒙蒙
没人知道我已千疮百孔
想你的时候心无法止痛
谁能告诉我该何去何从
爱的路上 烟雨蒙蒙
距离渐渐模糊幸福颜容
如果眼泪是你给的恩宠
我将走不出寂寞的牢笼
闭上眼睛不见你入梦
我的情浓为何没人来宠
穿越人海我只对你心动
而你却总惹我眼眶泛红
爱的路上啊烟雨蒙蒙
没人知道我已千疮百孔
想你的时候心无法止痛
谁能告诉我该何去何从
爱的路上啊烟雨蒙蒙
距离渐渐模糊幸福颜容
如果眼泪是你给的恩宠
我将走不出寂寞的牢笼
爱的路上啊烟雨蒙蒙
没人知道我已千疮百孔
想你的时候心无法止痛
谁能告诉我该何去何从
爱的路上啊烟雨蒙蒙
距离渐渐模糊幸福颜容
如果眼泪是你给的恩宠
我将走不出寂寞的牢笼
我将走不出寂寞的牢笼`;

/*变量 :mKey - 当前歌词索引;mFlag :调用关键帧动画索引;averAdd :平均值补偿*/
let mKey = 0, mFlag = true, averAdd = 0.3;

/*函数 :获取每句歌词用时,歌词用时若超过平均值则取平均值,最后一句歌词则取平均值*/
let lrcTime = (ar) => {
      let tmpAr = [];
      for(j = 0; j <ar.length - 1; j ++) {
                if(j !== ar.length - 1) tmpAr = parseFloat((ar - ar).toFixed(1));
      }
      let aver = parseInt(tmpAr.reduce((a,b) => a + b) / (tmpAr.length - 1)) + averAdd;
      tmpAr.push(aver);
      tmpAr.forEach((item,key) => {
                ar = item > aver ? aver : item;
      });
      return ar;
};

/*函数 :从原始lrc歌词获取信息并存入 n*3 数组*/
let getLrcAr = (text) => {
      let lrcAr = [];
      let calcRule = ;
      for(x of text.split('\n')) {
                let ar = [];
                let re = /\d+[\.:]\d+([\.:]\d+)?/g;
                let geci = x.replace(re,'');
                if(geci) {
                        geci = geci.replace(/[\[\]\'\"\t,]s?/g,'');
                        let time = x.match(re);
                        if(time != null) {
                              for(y of time) {
                                        let tmp = y.match(/\d+/g);
                                        let sec = 0;
                                        for(z in tmp) sec += tmp * calcRule;
                                        ar = ;
                                        lrcAr.push(ar);
                              }
                        }
                }
      }
      lrcAr.sort((a,b)=> a - b);
      return(lrcTime(lrcAr));
};

/*函数 :模拟显示同步歌词*/
let showLrc = (time) => {
      let name = mFlag ? 'cover1' : 'cover2';
      lrc.innerHTML = lrcAr;
      lrc.dataset.lrc = lrcAr;
      lrc.style.setProperty('--motion', name);
      lrc.style.setProperty('--tt', time + 's');
      lrc.style.setProperty('--state', 'running');
      mKey += 1;
      mFlag = !mFlag;
};

/*函数 :处理当前歌词索引 mKey*/
let calcKey = () => {
      for (j = 0; j < lrcAr.length; j++) {
                if (aud.currentTime <= lrcAr) {
                        mKey = j - 1;
                        break;
                }
      }
      if (mKey < 0) mKey = 0;
      if (mKey > lrcAr.length - 1) mKey = lrcAr.length - 1;
      let time = lrcAr - (aud.currentTime - lrcAr);
      showLrc(time);
};

/*格式化时间信息*/
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;
}

/*函数 :关键帧动画状态切换*/
let mState = () => aud.paused ? (lrc.style.setProperty('--state','paused')) : (lrc.style.setProperty('--state','running'));

/*监听播放进度*/
aud.addEventListener('timeupdate', () => {
      for (j = 0; j < lrcAr.length; j++) {
                if (aud.currentTime >= lrcAr) {
                        cKey = j;
                        if (mKey === j) showLrc(lrcAr);
                        else continue;
                }
      }
});
aud.addEventListener('pause', () => mState());/*监听暂停事件*/
aud.addEventListener('play', () => mState());/*监听播放事件*/
aud.addEventListener('seeked', () => calcKey());/*监听查询事件*/
let lrcAr = getLrcAr(lrcStr); /*获得歌词数组*/
})();

舞台.onclick = () => aud.paused ? aud.play() : aud.pause();
aud.addEventListener('playing', () => 舞台.style.animationPlayState = 'running');
aud.addEventListener('pause', () => 舞台.style.animationPlayState = 'paused');
</script>


<style>
#眼睛 {transform:scale(0.8);
      margin: 150px ;position: absolute;z-index: 3;
      left: 10%;
       perspective: 3000px;
      perspective-origin: 50% 40%;
}

#舞台 {
      position: relative;
      width: 300px;
      height: 300px;
      transform-style: preserve-3d;
      animation: spin 10s infinite linear;
      transform: rotateX(-15deg) rotateY(-15deg) rotateX(-15deg);
}

.演员 {
      position: absolute;
      width: 100%;
      height: 100%;
      display: grid;
      place-items: center;
      font: normal 2em arial sans-serif;
      opacity: 1;
}

.演员:nth-of-type(1) {
      background: url('https://pic.imgdb.cn/item/64fd5599661c6c8e5429c0e2.jpg')no-repeat center/cover;
      transform: translateZ(150px) rotateY(0deg);
}

.演员:nth-of-type(2) {
      background: url('https://pic.imgdb.cn/item/658c0a24c458853aef9d89ab.jpg')no-repeat center/cover;
      transform: translateZ(-150px) rotateY(0deg);
}

.演员:nth-of-type(3) {
      background: url('https://pic.imgdb.cn/item/658c09d6c458853aef9c646b.jpg')no-repeat center/cover;
      transform: translateX(-150px) rotateY(90deg);
}

.演员:nth-of-type(4) {
      background: url('https://pic.imgdb.cn/item/64f93f7e661c6c8e54359206.jpg')no-repeat center/cover;
      transform: translateX(150px) rotateY(90deg);
}

.演员:nth-of-type(5) {
      background:url('https://pic.imgdb.cn/item/64e9fa3f661c6c8e544f1b3a.jpg')no-repeat center/cover;
      transform: translateY(-150px) rotateX(90deg);
}

.演员:nth-of-type(6) {
      background: url('https://pic.imgdb.cn/item/64fd530c661c6c8e542948df.jpg')no-repeat center/cover;
      transform: translateY(150px) rotateX(90deg);
}

@keyframes spin {
      from { transform: rotateX(0) rotateY(0) rotateZ(0); }
      to { transform: rotateX(0deg) rotateY(360deg) rotateZ(360deg); }
}
</style>
<script>
(function () {

        let Act = new AudioContext();

        let audSrc = Act.createMediaElementSource(aud);

        let analyser = Act.createAnalyser();

        audSrc.connect(analyser);

        analyser.connect(Act.destination);

        let ctx = canv.getContext('2d');

        let width = canv.width;

        let height = canv.height;

        let ppColor = ctx.createLinearGradient(350,200,350,0);

        ppColor.addColorStop(0.6, '#00ff00');

        ppColor.addColorStop(0.4, '#00ff00');

        ppColor.addColorStop(0, '#00ff00');

        let ppNum = 200;

        let voiceHeight = new Uint8Array(analyser.frequencyBinCount);



        (function draw() {

                analyser.getByteFrequencyData(voiceHeight);

                let step = Math.round(voiceHeight.length / ppNum);

                ctx.clearRect(0, 0, width, height);

                for (let j = 0; j < ppNum; j++) {

                        let audiheighteight = voiceHeight;

                        ctx.fillStyle = ppColor;

                        ctx.fillRect(width / 2 + (j * 8), height, 4, -audiheighteight);

                        ctx.fillRect(width / 2 - (j * 8), height, 4, -audiheighteight);

                }

                window.requestAnimationFrame(draw);

        })();

        canv.onclick = () => aud.paused ? aud.play() : aud.pause();

})();

</script>

亚伦影音工作室 发表于 2023-12-28 22:17

如果mp3地址异常,可以打包成html发帖!

红影 发表于 2023-12-28 22:23

频谱、播放器按钮、旋转魔方都能操控音乐,这个制作真好{:4_187:}

红影 发表于 2023-12-28 22:23

欣赏亚伦老师好帖{:4_199:}

醉美水芙蓉 发表于 2023-12-28 23:26

亦是金 发表于 2023-12-29 07:55

精彩漂亮,欣赏点赞学习了!{:4_190:}

愤怒的葡萄 发表于 2023-12-29 09:12

来欣赏佳作了。

侃大山 发表于 2023-12-29 18:34

欣赏好帖{:4_204:}
页: [1]
查看完整版本: 添加频谱更热闹【多项控制】