亚伦影音工作室 发表于 2025-4-7 14:03

我记得你眼里的依恋【手机欣赏】

本帖最后由 亚伦影音工作室 于 2025-4-8 13:03 编辑 <br /><br /><style >
#papa{margin: 120px 60px ;
width: 535px;box-shadow: 0px 0px 0px 2px #cccccc, 0px 0px 0px 6px #880000; overflow: hidden;
height: 850px;
border: 1px solid;
background: #333 url('https://img-baofun.zhhainiao.com/pcwallpaper_ugc_mobile/static/c8f4601254445b7c529f7077d413998e.jpg?x-oss-process=image%2fresize%2cm_lfit%2cw_640%2ch_1138') no-repeat center/cover;
position: relative;z-index: 12345;--state: paused;}
#papa:hover { transform:rotate(0deg)scale(1)}
#tu{position: absolute;top:0%; left:0%;z-index: 2;
        width: 100%;filter: url(#water);
        height: 100%;animation: round 60s linear infinite var(--state); }
#tu img{width: 100%;
        }

@keyframes round{
0% {
-webkit-transform:rotate(0)scale(1.5)translate(10%,0%);
opacity:1}
20% {
-webkit-transform:rotate(0)scale(1.5)translate(-10%,0%);
opacity:1}
40% {
-webkit-transform:rotate(0)scale(1.5)translate(0%,10%);
opacity:1}
60% {
-webkit-transform:rotate(0)scale(1.5)translate(0%,-10%);
opacity:1}
80% {
-webkit-transform:rotate(0)scale(1.5)translate(0%,0%);
opacity:1}
100% {
-webkit-transform:rotate(0deg)scale(1.5)translate(10%,0%);
opacity:1}
}
#dt{position: absolute;top:60%; left:18%;
        width: 60%;
        height: 40%;z-index: 3; }

#dt img{
        width: 100%;
        height: 100%;}
.mplayer { position: absolute; width: 300px; height: fit-content; display: flex; flex-direction: column; align-items: center; gap: 10px; color: #eee; margin: auto; top: 90%; left:20%;z-index: 20; }
    .mplayer::before { position: absolute; content: attr(data-time); width: 100%; text-align-last: justify; pointer-events: none; }
    .btnPlay { width: 20px; height: 20px; cursor: pointer; position: relative; }
    .btnPlay::after { position: absolute; content: ''; width: 100%; height: 100%; background: red; clip-path: var(--clip); }
    .progress { --prg: 0%; position: relative; width: 100%; height: 20px; display: grid; place-items: center start; background: linear-gradient(90deg, red var(--prg), gray var(--prg), gray 0) no-repeat center/100% 2px; padding: 0; margin: 0; }
    .thumb { position: absolute; left: calc(var(--prg) - 10px); width: 10px; height: 10px; background: red; border: 1px solid #FF0000; border-radius: 50%; cursor: pointer; box-sizing: border-box; }
    .play { --clip: polygon(10% 0,100% 50%,10% 100%); }
    .pause { --clip: polygon(35% 0,15% 0,15% 100%, 35% 100%,35% 0,75% 0,75% 100%,55% 100%,55% 0); }


</style>
<div id="papa">
<div id='dt'><img id="testImg" src="https://pic1.imgdb.cn/item/67ce8a52066befcec6e25b80.gif" ></div>
<div id='tu'>
<svg width="0" height="0"id="p" >
<filter id="water">
    <feTurbulence type="fractalNoise" baseFrequency=".05 .05" numOctaves="1" result="noise1"></feTurbulence>
    <feColorMatrix in="noise1" type="hueRotate" values="0" result="noise2">
      <animate attributeName="values" from="0" to="360" dur="2s" repeatCount="indefinite"/>
    </feColorMatrix>
    <feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="2" in="SourceGraphic" in2="noise2" />
</filter>
</svg>
<img src="https://img-baofun.zhhainiao.com/pcwallpaper_ugc_mobile/static/c8f4601254445b7c529f7077d413998e.jpg" alt="">
</div>
<div class="mplayer" data-time="00:00 00:00">
        <div class="btnPlay play"></div>
        <div class="progress">
                <div class="thumb"></div>
        </div>
</div>
<div class="lrc">
      <ul id="ul">
      </ul>
    </div>
</div>

<audio id="audio" src="https://s2.ananas.chaoxing.com/sv-w9/audio/20/88/58/254f4814085859f82d2b6d1c3a3f5178/audio.mp3" loop autoplay></audio>

<style>
.lrc {position:absolute;width: 540px;
    height: 450px;z-index: 6;
   border: 0px solid white;
    overflow: hidden;margin: 200px 0px;
}

.lrc #ul {width: 100%;
padding: 0;list-style: none;transition: 0.3s all ease;
    margin: 0}
.lrc #ul li {
   
font-family:微软雅黑;
    font-size: 20px;
    color: #ccc;
    font-weight:400;
    transition: .3s all ease;
    list-style-type: none;
    text-align: center;display: block;
    width: 100%;
    margin: 0 auto;
    height: 50px;
    line-height: 35px;
}
.lrc #ulli.active{   font-size: 30px;
    color: #ff0000;font-weight:800;
text-align: center;color: transparent; background: repeating-linear-gradient(to right, gold, lightgreen, snow, #ff0000, orange) 50%/200px 60px; -webkit-background-clip: text;filter:drop-shadow(#000 1px 0 0)drop-shadow(#000 0 1px 0)drop-shadow(#000 -1px 0 0) drop-shadow(#000 0 -1px0);
}
</style>
<script>
var lrc = `我记得你眼里的依恋
演唱:陈爱玲
歌词编辑:亚伦
走在红尘俗世间
谁的呼唤飘在耳边
那么熟悉却又遥远
为什么痴心两处总难相见
徘徊在起风的午夜
谁的叹息飘在风间
那么无奈却又无悔
多少前世残留有待今生缘
就算换了时空变了容颜
我依然记得你眼里的依恋
纵然聚散由命也要用心感动天
就算换了时空变了容颜
我依然记得你眼里的依恋
纵然难续前世
也要再结今生缘
......
走在红尘俗世间
谁的呼唤飘在耳边
那么熟悉却又遥远
为什么痴心两处总难相见
徘徊在起风的午夜
谁的叹息飘在风间
那么无奈却又无悔
多少前世残留有待今生缘
就算换了时空变了容颜
我依然记得你眼里的依恋
纵然聚散由命也要用心感动天
就算换了时空变了容颜
我依然记得你眼里的依恋
纵然难续前世
也要再结今生缘
......
就算换了时空变了容颜
我依然记得你眼里的依恋
就算换了时空你变了容颜
我依然记得你眼里的依恋
`;

// 最开始获取到的歌词列表是字符串类型(不好操作)
let lrcArr = lrc.split('\n');
// 接收修正后的歌词数组
let result = [];
// 获取所要用到的dom列表
doms = {
    audio: document.querySelector("#audio"),
    ul: document.querySelector("#ul"),
    container: document.querySelector(".lrc")
}
// 将歌词数组转成由对象组成的数组,对象有time和word两个属性(为了方便操作)
for (let i = 0; i < lrcArr.length; i++) {
    var lrcData = lrcArr.split(']');
    var lrcTime = lrcData.substring(1);
    var obj = {
      time: parseTime(lrcTime),
      word: lrcData
    }
    result.push(obj);
}
// 将tiem转换为秒的形式
function parseTime(lrcTime) {
    lrcTimeArr = lrcTime.split(":")
    return +lrcTimeArr * 60 + +lrcTimeArr;
}
// 获取当前播放到的歌词的下标
function getIndex() {
    let Time = doms.audio.currentTime;
    for (let i = 0; i < result.length; i++) {
      if (result.time > Time) {
            return i - 1;
      }
    }
}
// 创建歌词列表
function createElements() {
    let frag = document.createDocumentFragment(); // 文档片段
    for (let i = 0; i < result.length; i++) {
      let li = document.createElement("li");
      li.innerText = result.word;
      frag.appendChild(li);
    }
    doms.ul.appendChild(frag);
}
createElements();
// 获取显示窗口的可视高度
let containerHeight = doms.container.clientHeight;
// 获取歌词列表的可视高度
let liHeight = doms.ul.children.clientHeight;
// 设置最大最小偏移量,防止显示效果不佳
let minOffset = 0;
let maxOffset = doms.ul.clientHeight - containerHeight;
// 控制歌词滚动移动的函数
function setOffset() {
    let index = getIndex();
    // 计算滚动距离
    let offset = liHeight * index - containerHeight / 2 + liHeight / 2;
    if (offset < minOffset) {
      offset = minOffset;
    };
    if (offset > maxOffset) {
      offset = maxOffset;
    };
    // 滚动
    doms.ul.style.transform = `translateY(-${offset}px)`;
    // 清除之前的active
    let li = doms.ul.querySelector(".active")
    if (li) {
      li.classList.remove("active");
    }
    // 为当前所唱到的歌词添加active
    li = doms.ul.children;
    if (li) {
      li.classList.add("active");
    }
};
// 当audio的播放时间更新时,触发该事件
doms.audio.addEventListener("timeupdate", setOffset);
</script>

<script>
if ('getContext' in document.createElement('canvas')) {
    HTMLImageElement.prototype.play = function() {
      if (this.storeCanvas) {
            // 移除存储的canvas
            this.storeCanvas.parentElement.removeChild(this.storeCanvas);
            this.storeCanvas = null;
            // 透明度还原
            image.style.opacity = '';
      }
      if (this.storeUrl) {
            this.src = this.storeUrl;   
      }
    };
    HTMLImageElement.prototype.stop = function() {
      var canvas = document.createElement('canvas');
      // 尺寸
      var width = this.width, height = this.height;
      if (width && height) {
            // 存储之前的地址
            if (!this.storeUrl) {
                this.storeUrl = this.src;
            }
            // canvas大小
            canvas.width = width;
            canvas.height = height;
            // 绘制图片帧(第一帧)
            canvas.getContext('2d').drawImage(this, 0, 0, width, height);
            // 重置当前图片
            try {
                this.src = canvas.toDataURL("image/gif");
            } catch(e) {
                // 跨域
                this.removeAttribute('src');
                // 载入canvas元素
                canvas.style.position = 'absolute';
                // 前面插入图片
                this.parentElement.insertBefore(canvas, this);
                // 隐藏原图
                this.style.opacity = '0';
                // 存储canvas
                this.storeCanvas = canvas;
            }
      }
    };
}
var image= document.getElementById("testImg");
</script>

<script>
//获取需要操作的元素标识
const mplayer = document.querySelector('.mplayer');
const btnPlay = document.querySelector('.btnPlay');
const progress = document.querySelector('.progress');
const thumb = document.querySelector('.thumb');
const audio = document.querySelector('audio');
// 拖曳操作状态(初始值为假)
let isDraggable = false;

//时间格式化工具函数 :秒转分秒 mm:ss 格式
const formatTime = (seconds) => {
        const mins = Math.floor(seconds / 60);
        const secs = Math.floor(seconds % 60);
        return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
};

// 联动函数 mState :处理按钮形状
const mState = () => {papa.style.setProperty('--state', audio.paused ? 'paused' : 'running');
        btnPlay.className = `btnPlay ${['pause', 'play'][+audio.paused]}`;
};

// 获取设备指针所在点在进度条上的距离(百分比)
const getPercent = (e) => {
        const rect = progress.getBoundingClientRect();
        const left = rect.left;
        const width = rect.width;
        let x = e.clientX ?? e.touches?.?.clientX ?? e.changedTouches?.?.clientX;
        x = Math.min(width, Math.max(0, x - left));
        return x / width * 100;
};

// 滑块鼠标按下、触屏设备手指或触笔按下
thumb.onmousedown = thumb.ontouchstart = (e) => {
        isDraggable = true; // 拖曳状态进行中
        e.preventDefault(); // 阻止默认行为
};

// 文档指针松开、触屏设备手指或触笔弹开
document.onmouseup = document.ontouchend = (e) => {
    // 松开时若拖曳状态为真,驱动 audio 改变播放进度
        if (isDraggable) audio.currentTime = `${getPercent(e) * audio.duration / 100}`;
        isDraggable = false; //然后拖曳状态为假
};

// 文档上指针或手指、触笔移动时
document.onmousemove = document.ontouchmove = (e) => {
        if (!isDraggable) return; // 若不是拖曳状态则忽略之
        // 反之,若处于拖曳状态,给CSS变量 --prg 赋值
        progress.style.setProperty('--prg', `${getPercent(e)}%`);
        // 给时间文本信息即mplayer伪元素 attr(data-time) 函数赋值
        mplayer.dataset.time = `${formatTime(audio.duration * getPercent(e) / 100)} ${formatTime(audio.duration)}`;
};

// 进度条点击事件
progress.onclick = (e) => audio.currentTime = `${getPercent(e) * audio.duration / 100}`;

// 音频标签开始播放和暂停时执行联动函数
audio.onplaying = audio.onpause = () => mState();

// 音频时间更新事件 :驱动文本时间信息及进度条进度变更
audio.ontimeupdate = () => {
        if (isDraggable) return; // 拖曳操作发生时忽略
        mplayer.dataset.time = `${formatTime(audio.currentTime)} ${formatTime(audio.duration)}`;
        progress.style.setProperty('--prg', `${audio.currentTime / audio.duration * 100}%`);
};

// 按钮单击 :播放、暂停状态切换
btnPlay.onclick = () => audio.paused ? (audio.play(),image.play(),p.unpauseAnimations()) : (audio.pause(),image.stop(),p.pauseAnimations());

</script>

杨帆 发表于 2025-4-7 16:22

真漂亮,谢谢精彩分享,祝贺亚伦老师再创新高{:4_176:}

红影 发表于 2025-4-7 19:23

这个图图好美,还能移动展示。好像有水波纹效果,这效果会导致面部有点变形。
这频谱是动图吧,看到暂停时停在固定的帧上了。{:4_187:}

红影 发表于 2025-4-7 19:24

同步歌词漂亮,一键全控也很赞。
欣赏亚伦老师好帖{:4_199:}

小辣椒 发表于 2025-4-7 20:55

亚纶这个制作太美了,手机模式确实不错{:4_178:}

小辣椒 发表于 2025-4-7 20:55

也是我非常喜欢的一首歌{:4_208:}

小辣椒 发表于 2025-4-7 20:58

感觉这个背景移动大图片效果不知道怎么样

小辣椒 发表于 2025-4-7 21:00

大图歌词上去不会遮挡人物,亚纶做个大图试试{:4_173:}

亚伦影音工作室 发表于 2025-4-7 21:53

小辣椒 发表于 2025-4-7 20:58
感觉这个背景移动大图片效果不知道怎么样

以前做过大图效果还可以!
页: [1]
查看完整版本: 我记得你眼里的依恋【手机欣赏】