亚伦影音工作室 发表于 2023-5-28 14:11

全控HTML5创意音画《人生是一场难熬的修炼》

本帖最后由 亚伦影音工作室 于 2023-5-28 14:18 编辑 <br /><br /><style>
#papa {
        margin: 100px -300px;
        width: 1164px;
        height: 640px;
        background: url('https://img-baofun.zhhainiao.com/pcwallpaper_ugc/static/0fd840c8d7aec9f667dea44e701c8a1b.png') no-repeat center/cover;
        box-shadow: 0 0 0px #000;
        position: relative;
        z-index: 1;overflow:hidden;
        --state: paused;
}
css-doodle { position: absolute; }

.photo {width: 100%;
height: 100%;
position: absolute;z-index: 5;

top:0px; left:0px;-webkit-mask-image: radial-gradient(black 20% ,transparent 70%);

opacity: 0;

animation: round 90s linear infinite;}

@keyframes round{0% {opacity: 1;transform:translate(-100%,-100%)scale(0);}

4% {opacity: 1;transform:translate(0%,0%)scale(0.8)rotate(-360deg);}

5% {opacity: 1;transform:translate(0%,0%)scale(0.8)rotate(-360deg);}

7% {opacity: 1;transform: perspective(1300px) rotateY(70deg)scale(0.8)}

9% {opacity: 1;transform: perspective(1300px) rotateY(-70deg)scale(0.8)}

11% {opacity: 0;transform:translate(100%,100%) perspective(1300px)rotatex(-90deg) rotateY(-40deg)scale(3);}

}

img:nth-child(1) {animation-delay: 84s;}

img:nth-child(2) {animation-delay: 78s;}

img:nth-child(3) {animation-delay: 72s;}

img:nth-child(4) {animation-delay: 66s;}

img:nth-child(5) {animation-delay: 60s;}

img:nth-child(6) {animation-delay: 54s;}

img:nth-child(7) {animation-delay: 48s;}

img:nth-child(8) {animation-delay: 42s;}

img:nth-child(9) {animation-delay: 36s;}

img:nth-child(10){animation-delay: 30s;}

img:nth-child(11){animation-delay: 24s;}

img:nth-child(12){animation-delay: 18s;}

img:nth-child(13){animation-delay: 12s;}

img:nth-child(14) {animation-delay: 6s;}

img:nth-child(15) {animation-delay: 0s;}

.stop img:nth-child(1),

.stop img:nth-child(2),

.stop img:nth-child(3),

.stop img:nth-child(4),

.stop img:nth-child(5),

.stop img:nth-child(6),

.stop img:nth-child(7),

.stop img:nth-child(8),

.stop img:nth-child(9),

.stop img:nth-child(10),

.stop img:nth-child(11),

.stop img:nth-child(12),

.stop img:nth-child(13),

.stop img:nth-child(14),

.stop img:nth-child(15){animation-play-state: paused;}



#canv {filter:hue-rotate(0deg)contrast(100%)brightness(100%);
        position: absolute;
        display: block;
        height: 100%;
        position: relative;
        cursor: pointer;
        z-index: 4;opacity: 1;
}
#vid { display: none; }

#lrc {
        --state: paused;
        --motion: cover2;
        --tt: 2s;
        --bg: linear-gradient(180deg, #880000, #ff0000, #80ef03);
        position: absolute;z-index: 6;
        left: 50%;
        transform: translate(-50%);
        top: 85%;
        font:normal 3em 华文行楷;
        color: #055306;
        white-space: pre;
        -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 { from { width: 0; } to { width: 100%; } }
@keyframes cover2 { from { width: 0; } to { width: 100%; } }

.wenzi { position: absolute; left: 10%; top: 18%; z-index: 10; color:#ffffff; font: bold 20px/20px 'FangSong',serif;opacity: 1; }
#papa:hover #fullscreen { display:block ;}


#fullscreen { position: absolute; top:2%; left:5%;color:#FFffff; font: normal 2.2em华文行楷; opacity: 1; cursor: pointer; z-index: 6}

</style>

<div id="papa">
      <div id="lrc" data-lrc="花潮lrc在线">花潮lrc在线</div>
<div id="testImg" >

<img alt="" class="photo" src="https://file.moyublog.com/d/file/2021-11-17/nyv0qsjh0s2.jpg" />

<img alt="" class="photo"src="https://file.moyublog.com/d/file/2022-12-02/365f5998753741a910fac58b2be63d91.jpg" />

<img alt=""class="photo"src="https://365.tf/disk/tf/1676473345.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676383211.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676420707.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676438603.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676393369.jpg" />

<img alt="" class="photo" src="https://file.moyublog.com/d/file/2022-09-20/66695b8106d2596e6b1cd5c6cb77eda6.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676392055.jpg" />

<img alt="" class="photo"src="https://365.tf/disk/tf/1676436325.jpg" />

<img alt=""class="photo"src="https://365.tf/disk/tf/1676409961.jpg" />

<img alt="" class="photo" src="https://file.moyublog.com/d/file/2021-01-18/c02923924e30e172098ec67a6ae5fc94.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676421148.jpg" />

<img alt="" class="photo" src="https://365.tf/disk/tf/1676449988.jpg" />

<img alt="" class="photo" src="https://file.moyublog.com/d/file/2022-05-31/8db359878f7ab03dd2e8e4b0badf2be7.jpg" />

</div>

        <divstyle="width: 400px;height: 320px;overflow:hidden;margin: 3% 70%;position: absolute;" id="but">
<css-doodleid="mplayer">
          :doodle {
                @grid: 2 / 300px 60px;
            position: absolute;z-index: 40;
                color: var(--color);
            transform: scale(1);
                --prog: 0%; --size: 35px; --ttmsg1: '00:00'; --ttmsg2: '00:00'; --color:#ffffff; --state: paused;
      }
      /* 时间信息 : 左 */
      @nth(1) {
                @place: 25% 80%;
                :after { content: var(--ttmsg1); }
      }
      /* 控制器 */
      @nth(2) {
                @size: var(--size);
                @shape: clover 5;
                @place: 50% 35%;
                background: var(--color);
                animation: rot 6s infinite linear var(--state);
      }
      /* 时间信息 : 右 */
      @nth(3) {
                @place: 75% 80%;
                :after { content: var(--ttmsg2); }
      }
   /* 进度条 */
      @nth(4) {
                @place: 50% 80%;
                @size: 100% 2px;
                background: #aaaaaa;
               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 class="wenzi">人生是一场难熬的修炼</div>

</div>

<canvas id="canv"></canvas>
        <span id="fullscreen">全屏观赏</span>
<video id="vid" src="https://img-baofun.zhhainiao.com/pcwallpaper_ugc/preview/48b2ac2f0819777dc33f965f3659d211_preview.mp4" autoplay loop muted></video>
        <audio id="aud" src="https://www.qqmc.com/mp3/music275828149.mp3" autoplay loop></audio>

</div>

<script>
let ctx = canv.getContext('2d');
let ww = canv.width = papa.offsetWidth, hh = canv.height = papa.offsetHeight;
let loop = () => {
        ctx.drawImage(vid, 0, 0, ww, hh);
        if(!vid.paused) {
                requestAnimationFrame(loop);
                return;
        }
}
let mState = () => aud.paused ? ( mplayer.style.setProperty('--state', 'paused'), vid.pause()) : ( mplayer.style.setProperty('--state', 'running'), vid.play());
vid.addEventListener('play', loop, false);
aud.addEventListener('play', () => mState());
aud.addEventListener('pause', () => mState());

</script>

<script>

(function() {
      let script = document.createElement('script');
      script.src = 'https://unpkg.com/css-doodle@0.34.9/css-doodle.min.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 = (e) => {
                if(e.offsetX > 130 && e.offsetX < 170 && e.offsetY < 46) aud.paused ? aud.play() : aud.pause();
                if(e.offsetY > 46) aud.currentTime = aud.duration * e.offsetX / mplayer.offsetWidth;
      }
})();


</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'),mplayer.style.animationPlayState = 'paused') : (lrc.style.setProperty('--state','running'),mplayer.style.animationPlayState = '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); /*获得歌词数组*/
})();

let fs = true;
        fullscreen.onclick = () => {
                fs ? (fullscreen.innerText = '退出全屏',papa.requestFullscreen()) : (fullscreen.innerText = '全屏观赏', document.exitFullscreen());
                fs = !fs;
        };
</script>
<script>
var image = document.getElementById("testImg"),
    button = document.getElementById("but");
   
if (image.classList && image && button) {
    button.onclick = function() {
      if (this.value == '.') {
            image.classList.remove('stop');
          this.value = '*';
      } else {
            image.classList.add('stop');
            this.value = '.';
      }
    };
}

</script>

一斛珠 发表于 2023-5-28 15:16

撒花欣赏{:6_220:}

醉美水芙蓉 发表于 2023-5-28 16:44

梦缘 发表于 2023-5-28 17:57

好美的图画,欣赏问好!{:4_187:}

亦是金 发表于 2023-5-28 17:58

欣赏美帖!收藏学习备用,谢谢了!{:4_190:}

梦缘 发表于 2023-5-28 17:58

播放器很有特色,欣赏点赞!{:4_171:}

红影 发表于 2023-5-28 18:44

这个的确可以做到按钮可以全控。制作漂亮。歌曲的歌词很实在。欣赏亚伦老师好帖{:4_199:}

小辣椒 发表于 2023-5-30 21:53

反复看了几遍,感觉亚伦这个制作图图有点多了,感觉画面乱了,简洁的反而漂亮,一个背景动图,几个小动图就可以了,一键停止动图,简单明了。

亚伦影音工作室 发表于 2023-5-31 12:12

小辣椒 发表于 2023-5-30 21:53
反复看了几遍,感觉亚伦这个制作图图有点多了,感觉画面乱了,简洁的反而漂亮,一个背景动图,几个小动图就 ...

谢谢老师的建议,我的目的是测试多图动画控制!
页: [1]
查看完整版本: 全控HTML5创意音画《人生是一场难熬的修炼》