戏梦
本帖最后由 山里人 于 2024-5-12 16:41 编辑 <br /><br /><style>#papa {margin: 00px -280px;width: 1164px;height: 620px;background: url('https://ln2018.oss-cn-hangzhou.aliyuncs.com/2024/pp/tp/f.png') no-repeat 80% 20%/200px 200px,url('https://ln2018.oss-cn-hangzhou.aliyuncs.com/2024/tp/xf.gif') no-repeat 80% 35%/220px 300px, url('https://ln2018.oss-cn-hangzhou.aliyuncs.com/2024/pp/tp/sw.jpg') no-repeat center/cover; z-index: 1;display: grid; overflow: hidden;position: relative;}
#aud {position:absolute;margin-top:0px; margin-left:0px;z-index: 60;
display: block;
width:102%;clip-path: inset(20% 1% 20% 1%);filter:invert(100%);margin: 580px -14px;
}
#lrc {
--state: paused;
--motion: cover2;
--tt: 2s;
--bg: linear-gradient(0deg, #ff0000, #ff0000, #ff0000);
position: absolute;z-index: 6;
left: 52%;
transform: translate(-50%);
top: 480px;
font:normal 3em 华文新魏;
font-weight:400;
color: #eeeeee;
white-space: pre;
-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);
}
#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%;}}
#canvas{position: absolute;width: 55%;z-index: 4;top:220px; left:250px; }
#canv { position: absolute;top: -200px;left: 10px; transform: skew(-15deg) scale(1.8, 1.8);opacity: .4;}
</style>
<div id="papa">
<canvas id="canv" width="1200" height="600"></canvas>
<audio id="aud"src="https://shanlr.s3-us-east-1.ossfiles.com/2024/%E6%88%8F%E6%A2%A6.mp3" autoplay loopcontrols crossOrigin="anonymous"></audio>
<div data-lrc="戏梦(DJ)" id="lrc" title="歌词显示">戏梦(DJ)</div>
<canvas id="canvas" "></canvas>
</div>
<script >
(function() {/*原始lrc歌词*/
let lrcStr = `群星 - 戏梦
词:陈大力
在线音乐欣赏.频谱
这里有你想要的快乐
这里有好听音乐
LRC:山里人
昨天华山论剑
今天决战京城
原来世界竟然这么小
去年你是天王
今年我是至尊
谁是谁非谁又能分清
飞来飞去
飞过人群飞上云霄看我多逍遥
爱来爱去
今天爱你明天爱她到底谁爱我
他们说人生一场梦又何必太计较
青春正年少我应该大声笑
岁月如飞刀它刀刀催人老
再回首天荒地老
他们说人生一出戏又何必太认真
生旦净墨丑我统统扮一回
谁扮谁像谁我扮谁又像谁
别忘了下次再会
这里有好听音乐
昨天华山论剑
今天决战京城
原来世界竟然这么小
去年你是天王
今年我是至尊
谁是谁非谁又能分清
飞来飞去
飞过人群飞上云霄看我多逍遥
爱来爱去
今天爱你明天爱她到底谁爱我
他们说人生一场梦又何必太计较
青春正年少我应该大声笑
岁月如飞刀它刀刀催人老
再回首天荒地老
他们说人生一出戏又何必太认真
生旦净墨丑我统统扮一回
谁扮谁像谁我扮谁又像谁
别忘了下次再会
他们说人生一场梦又何必太计较
青春正年少我应该大声笑
岁月如飞刀它刀刀催人老
再回首天荒地老
他们说人生一出戏又何必太认真
生旦净墨丑我统统扮一回
谁扮谁像谁我扮谁又像谁
别忘了下次再会`;
/*变量 :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); /*获得歌词数组*/
})();
</script>
<script>
window.onload = function () {
var oAudio = document.getElementById('aud');
// 创建音频上下文对象
var oCtx = new AudioContext();
// console.log(oCtx);
// 创建媒体源,除了audio本身可以获取,也可以通过oCtx对象提供的api进行媒体源操作
var audioSrc = oCtx.createMediaElementSource(oAudio);
// 创建分析机
var analyser = oCtx.createAnalyser();
// 媒体源与分析机连接
audioSrc.connect(analyser);
// 输出的目标:将分析机分析出来的处理结果与目标点(耳机/扬声器)连接
analyser.connect(oCtx.destination);
// 利用cancas渐变进行音频绘制
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var oW = canvas.width;
var oH = canvas.height;
var color1 = ctx.createLinearGradient(oW / 2, oH / 2 - 30, oW / 2, oH / 2 - 100);
var color2 = ctx.createLinearGradient(oW / 2, oH / 2 + 30, oW / 2, oH / 2 + 100);
color1.addColorStop(0, '#ffffff');
color1.addColorStop(.5, '#fff000');
color1.addColorStop(1, '#00ff00');
color2.addColorStop(0, '#ffffff');
color2.addColorStop(.5, '#fff000');
color2.addColorStop(1, '#00ff00');
// 音频图的条数
var count = 200;
// 缓冲区:进行数据的缓冲处理,转换成二进制数据
var voiceHeight = new Uint8Array(analyser.frequencyBinCount);
// console.log(voiceHeight);
function draw() {
// 将当前的频率数据复制到传入的无符号字节数组中,做到实时连接
analyser.getByteFrequencyData(voiceHeight);
// console.log(voiceHeight);
// 自定义获取数组里边数据的频步
var step = Math.round(voiceHeight.length / count);
ctx.clearRect(0, 0, oW, oH);
for (var i = 0; i < count; i++) {
var audioHeight = voiceHeight;
ctx.fillStyle = color1;// 绘制向上的线条
ctx.fillRect(oW / 2 + (i * 5), oH / 2, 2, -audioHeight);
ctx.fillRect(oW / 2 - (i * 5), oH / 2, 2, -audioHeight);
ctx.fillStyle = color2;// 绘制向下的线条
ctx.fillRect(oW / 2 + (i * 5), oH / 2, 2, audioHeight);
ctx.fillRect(oW / 2 - (i * 5), oH / 2, 2, audioHeight);
}
window.requestAnimationFrame(draw);
}
draw();
}
</script>
<script>
var sF = document.createElement('script');
sF.src = 'https://638183.freep.cn/638183/web/js2024/oc-lz.js';
document.body.appendChild(sF);
/* 粒子配置
papa : 指定帖子容器 id(不要引号)
hue : 粒子色彩在色环中的角度(0~360)
total : 粒子数量
deep : 粒子起伏深度(负值朝下起伏、正值朝上起伏)
*/
var lz = {papa: mybox, hue: 60, total: 10000, deep: -80};
player.onclick = () => aud.paused ? aud.play() : aud.pause();
/*以下是控制动图的插件*/
if ('getContext' in document.createElement('canvas')) {
HTMLImageElement.prototype.play = function() {
if (this.storeCanvas) {
// 移除存储的canvas
this.storeCanvas.parentElement.removeChild(this.storeCanvas);
this.storeCanvas = null;
// 透明度还原
imagelb.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;
}
}
};
}
</script> 好看 好听~~{:4_190:} 漂亮的制作。欣赏山里人好帖{:4_199:}
页:
[1]