马黑黑 发表于 2022-12-21 08:04

少女净妖师

<style>
#papa { margin: 0 0 0 calc(50% - 593px); display: grid; place-items: center; width: 1024px; height: 640px; background: gray url('https://638183.freep.cn/638183/t22/webp/unjyu.webp') no-repeat center/cover; box-shadow: 3px 3px 20px #000; user-select: none; position: relative; z-index: 1; }
#papa:hover #fullscreen { display: block; }
#fullscreen { position: absolute; bottom: 140px; color: snow; text-shadow: 1px 1px 2px #000; display: none; cursor: pointer; }
</style>

<div id="papa">
        <img src="https://638183.freep.cn/638183/t22/gif/jigu.gif" alt="" style="position: absolute; bottom: 100px; mix-blend-mode: difference" />
        <span id="fullscreen">全屏观赏</span>
</div>
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=530260398.mp3" loop autoplay></audio>

<script >
(function() {
        (function(mkPlayer) {let defaults = {lrcAr: [],lrc_css: 'top: 15px; left: 50%; transform: translate(-50%)',player_css: 'bottom: 10px; left: 50%; transform: translate(-50%)',playerCode: `<style>#mplayer { --ww: 300px; --color1: hsla(0,80%,50%,.95); --color2: hsla(0,0%,95%,.45); position: absolute; z-index: 901; }#lrc { --motion: cover2; --tt: 1s; --state: running; --bg: linear-gradient(180deg,hsla(100,10%,50%,.75),hsla(100,100%,20%,.65)); position: absolute; font: bold 2.4em sans-serif; color: hsl(100, 100%, 90%); white-space: pre; -webkit-background-clip: text; filter: drop-shadow(1px 1px 2px hsla(0, 100%, 0%, .85)); z-index: 900; }#lrc::before { position: absolute; content: attr(data-lrc); width: 20%; height: 100%; color: transparent; overflow: hidden; white-space: pre; background: var(--bg); filter: inherit; -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%; } }</style><canvas id="mplayer" width="300" height="75"></canvas><div id="lrc" data-lrc="HCPlayer">HCPlayer</div>`,};let playCode = (user_config) => {let data = Object.assign({}, defaults, user_config);papa.innerHTML += data.playerCode;mplayer.style.cssText += data.player_css;lrc.style.cssText += data.lrc_css;let mKey = 0, mFlag = true, btfFlag = false;let getCssVal = (e,v) => getComputedStyle(e).getPropertyValue(v);let ctx = mplayer.getContext('2d');let w = mplayer.width = getCssVal(mplayer,'--ww').replace(/[^0-9]/ig,''), h = mplayer.height = 75;let btnFlag = false;let player = {prog: 0,track: w,color: ,cur: '00:00',dur: '00:00'};let drawCircle = (x,y,r,color) => {ctx.beginPath();ctx.strokeStyle = color;ctx.lineWidth = 2;ctx.arc(x,y,r,0,2*Math.PI);ctx.stroke();};let drawTriangle = (x,y,len,color) => {ctx.beginPath();ctx.fillStyle = color;ctx.moveTo(x,y);ctx.lineTo(x, y+len);ctx.lineTo(x+len, y + len/2);ctx.lineTo(x,y);ctx.fill();};let drawRect = (x,y,ww,hh,color) => {ctx.beginPath();ctx.fillStyle = color;ctx.fillRect(x,y,ww,hh);};let drawOsc = (w1,w2) => {ctx.beginPath();ctx.lineWidth = 1;ctx.strokeStyle = player.color;let slice = 1, tt1 = Math.round(w1/slice), tt2 = Math.round(w2/slice);for(j=0; j<=tt2; j++) {ctx.lineTo(j*slice, Math.random() *30);}ctx.stroke();ctx.beginPath();ctx.strokeStyle = player.color;for(j=tt2; j<tt1; j++) {ctx.lineTo(j*slice, Math.random() *30);}ctx.stroke();};let drawTxt = (text,x,y,align,color) => {ctx.beginPath();ctx.font = '16px sans-serif';ctx.textAlign = align;ctx.textBaseline = 'middle';ctx.fillStyle = color;ctx.fillText(text,x,y);};let btnRender = () => {let btnColor = btnFlag ? player.color : player.color;ctx.clearRect(w/2-18, h-38, 36, 36);drawCircle(w/2,h-20,16,btnColor);aud.paused ? drawTriangle(w/2-6,h-28,16,btnColor) : (drawRect(w/2-6, h-28,4,16,btnColor), drawRect(w/2+2, h-28,4,16,btnColor));};let drawAll = () => {ctx.clearRect(0,0,w,h);drawOsc(w,player.prog);drawTxt(player.cur,w/2-26,h-20,'right',player.color);drawTxt(player.dur,w/2 + 26,h-20,'left',player.color);btnRender();};let overBtn = (e) => Math.sqrt((e.offsetX-w/2) ** 2 + (e.offsetY-(h-20)) ** 2) < 16;let overProg = (e) => e.offsetY > 0 && e.offsetY < 30;mplayer.onmousemove = (e) => {mplayer.style.cursor = overBtn(e) || overProg(e) ? 'pointer' : 'default';mplayer.title = overProg(e) ? toMin(e.offsetX*aud.duration/w) : '';overBtn(e) ? (btnFlag = true,btnRender()) : (btnFlag = false,btnRender());};mplayer.onclick = (e) => {if(overBtn(e)) { aud.paused ? aud.play() : aud.pause(); drawAll(); }if(overProg(e)) aud.currentTime = aud.duration * e.offsetX / w;};mplayer.onmouseout = () => { btnFlag = false; btnRender(); };aud.addEventListener('timeupdate', () => {player.prog = aud.currentTime * w /aud.duration;player.cur = toMin(aud.currentTime);player.dur = toMin(aud.duration);drawAll();for (j = 0; j < data.lrcAr.length; j++) {if (aud.currentTime >= data.lrcAr) {if (mKey === j) showLrc(data.lrcAr);else continue;}}});aud.addEventListener('pause', () => mState());aud.addEventListener('play', () => mState());aud.addEventListener('seeked', () => calcKey());let mState = () => aud.paused ? (lrc.style.setProperty('--state', 'paused')) : (lrc.style.setProperty('--state', 'running'));let showLrc = (time) => {let name = mFlag ? 'cover1' : 'cover2';lrc.innerHTML = data.lrcAr;lrc.dataset.lrc = data.lrcAr.replace(/<br>/, '\n');lrc.style.setProperty('--motion', name);lrc.style.setProperty('--tt', time + 's');lrc.style.setProperty('--state', 'running');mKey += 1;mFlag = !mFlag;};let calcKey = () => {for (j = 0; j < data.lrcAr.length; j++) {if (aud.currentTime <= data.lrcAr) {mKey = j - 1;break;}}if (mKey < 0) mKey = 0;if (mKey > data.lrcAr.length - 1) mKey = data.lrcAr.length - 1;let time = data.lrcAr - (aud.currentTime - data.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;};drawAll();};mkPlayer.HCPlayer = playCode;})(this);
        let lrcAr = [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,];
        HCPlayer({
                lrcAr: lrcAr,
                player_css: '--color1: red; --color2: lightblue; --ww: 400px; bottom: 5px;',
                lrc_css: '--bg: linear-gradient(180deg,hsla(0,100%,50%,.35),hsla(200,100%,50%,.65)); color: lightblue; top: 10px;',
        });
        let fs = true;
        fullscreen.onclick = () => {
                fs ? (fullscreen.innerText = '退出全屏', papa.requestFullscreen()) : (fullscreen.innerText = '全屏观赏', document.exitFullscreen());
                fs = !fs;
        };
})();
</script>

侃大山 发表于 2022-12-21 09:16

这个放全屏看更好

侃大山 发表于 2022-12-21 09:17

全屏欣赏几个字鼠标移上去才有,这个漂亮!

红影 发表于 2022-12-21 09:46

这歌名好玩,少女净妖师就是那个打着爵士鼓的小人么,看得笑{:4_173:}

红影 发表于 2022-12-21 09:49

这张图图特别适合全屏欣赏,把这几个字放在大鼓上,也很匠心{:4_199:}

红影 发表于 2022-12-21 09:49

黑黑又带来新玩法,很赞{:4_187:}

马黑黑 发表于 2022-12-21 09:52

侃大山 发表于 2022-12-21 09:16
这个放全屏看更好

图片质量有点差强人意

马黑黑 发表于 2022-12-21 09:53

侃大山 发表于 2022-12-21 09:17
全屏欣赏几个字鼠标移上去才有,这个漂亮!

CSS中伪类 :hover 可以控制子元素和相邻兄弟元素,要不然需要JS操控了

马黑黑 发表于 2022-12-21 09:53

红影 发表于 2022-12-21 09:46
这歌名好玩,少女净妖师就是那个打着爵士鼓的小人么,看得笑

{:4_170:}

马黑黑 发表于 2022-12-21 09:54

红影 发表于 2022-12-21 09:49
这张图图特别适合全屏欣赏,把这几个字放在大鼓上,也很匠心

多数人的设计思路可能差不多的

马黑黑 发表于 2022-12-21 09:57

红影 发表于 2022-12-21 09:49
黑黑又带来新玩法,很赞

JS控制元素的全屏展示还是不错的。平时,若按F11,得到的全屏基于整体web页,不是针对元素个体,JS可以单独针对特定元素做全屏。

CSS非标准伪类属性 :fullscreen 允许设置全屏状态下元素的样式,这里面还有许多功夫可以下。

小辣椒 发表于 2022-12-21 12:35

居然可以全屏显示,效果太棒了{:4_178:}

马黑黑 发表于 2022-12-21 12:51

小辣椒 发表于 2022-12-21 12:35
居然可以全屏显示,效果太棒了

还有一些小细节没有处理好。例如:如果进入全屏后,如果按 Esc 键而不是点击文本按钮退出,则文本按钮的文本对不上号。

关于全屏,所有浏览器都保护 F11 和 Esc 键的作用,企图阻止 Esc 退出全屏是徒劳的,且想通过监听 Esc 键被按下来执行一些操作也不允许(具体是全屏状态下无法监听 Esc 键的动作)。

好在 JS 还有一个 fullscreenchange 事件,虽然该事件不会传出信息,但加入一个检测语句后信息能拿得到,可以通过这个事件监听到全屏状态下的 Esc 被按下事件,则,文本按钮的表面名称就可以和全屏/非全屏两种状态同步了。

问题已经解决,但本帖不做修改,作为标本保留。

小辣椒 发表于 2022-12-21 13:05

马黑黑 发表于 2022-12-21 12:51
还有一些小细节没有处理好。例如:如果进入全屏后,如果按 Esc 键而不是点击文本按钮退出,则文本按钮的 ...

问题解决了。那个封装的语句是更新的了?

马黑黑 发表于 2022-12-21 15:15

小辣椒 发表于 2022-12-21 13:05
问题解决了。那个封装的语句是更新的了?

我解决问题了,帖子没改

小辣椒 发表于 2022-12-21 20:44

马黑黑 发表于 2022-12-21 15:15
我解决问题了,帖子没改

封装可以套用吧,小辣椒明天做一个,今天来不及,瞎忙

马黑黑 发表于 2022-12-21 20:55

小辣椒 发表于 2022-12-21 20:44
封装可以套用吧,小辣椒明天做一个,今天来不及,瞎忙

去后院看看

小辣椒 发表于 2022-12-21 21:08

马黑黑 发表于 2022-12-21 20:55
去后院看看

好的。刚才有看了一下的

马黑黑 发表于 2022-12-21 22:05

小辣椒 发表于 2022-12-21 21:08
好的。刚才有看了一下的

它就是全屏的实现方式

小辣椒 发表于 2022-12-21 22:07

马黑黑 发表于 2022-12-21 22:05
它就是全屏的实现方式

黑黑我测试了一个,发现这个可以全屏欣赏的字体可以不可以再明显一点,怕别人看不见
页: [1] 2
查看完整版本: 少女净妖师