Antonio Mocho(问候小辣椒)
本帖最后由 马黑黑 于 2025-7-11 21:42 编辑 <br /><br /><style>#papa { margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1400px); height: auto; aspect-ratio: 16/9; background: url('https://638183.freep.cn/638183/t24/w4/mocho.webp') no-repeat center/cover; perspective: 800px; box-shadow: 2px 2px 8px #000; z-index: 1; display: grid; place-items: center; position: relative; --size: 120px; --z: 300px; }
#papa div { display: inherit; place-items: inherit; }
#btnFs { left: 15px; bottom: 20px; color: white; }
#box { --bg: #000; --border-color: yellow; position: absolute; bottom: 50px; width: var(--size); height: var(--size); transform-style: preserve-3d; transform: rotateX(-15deg) rotateY(30deg) rotateZ(0); }
#lzpa { position: absolute; bottom: 50px; width: calc(var(--size) - 50px); height: calc(var(--size) - 50px); transition: transform 0.75s; transform-style: preserve-3d; }
li-zi { position: absolute; width: 25px; height: 25px; border-radius: 50%; background: linear-gradient(35deg, skyblue, green); }
.front { transform: rotateY(0) translateZ(calc(var(--size) / 2)); }
.back { transform: rotateY(180deg) translateZ(calc(var(--size) / 2)); }
.left { transform: rotateY(-90deg) translateZ(calc(var(--size) / 2)); }
.right { transform: rotateY(90deg) translateZ(calc(var(--size) / 2)); }
.top { transform: rotateX(90deg) translateZ(calc(var(--size) / 2)); }
.bottom { transform: rotateX(-90deg) translateZ(calc(var(--size) / 2)); }
.board { position: absolute; width: 100%; height: 100%; transition: transform 1s; font: bold 30px sans-serif; text-shadow: 2px 2px 4px orange; color: white; border: 3px dotted var(--border-color); background: var(--bg); opacity: 0.45; cursor: pointer; user-select: none; }
.ani-fly { animation: fly 20s var(--delay) linear infinite; }
@keyframes fly {
from { transform: rotateY(0) translate3d(0, 0, var(--z)); }
to { transform: rotateY(-360deg) translate3d(0, 0, var(--z)) rotateY(360deg); }
}
</style>
<div id="papa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1066074" autoplay loop></audio>
<div id="lzpa"></div>
<div id="box">
<div class="board front">PLAY</div>
<div class="board back"></div>
<div class="board left"></div>
<div class="board right"></div>
<div id="upboard" class="board top"></div>
<div class="board bottom"></div>
</div>
</div>
<script type="module">
import { FS } from 'https://638183.freep.cn/638183/web/js/fullscreen.js'
const total = 60;
const lzAr = [];
let lzRun = false;
Array.from({ length: total }).forEach( (lz, k) => {
lz = document.createElement('li-zi');
lz.style.cssText += `
left: ${lzpa.clientWidth * Math.random()}px;
top: ${lzpa.clientHeight * Math.random()}px;
background: linear-gradient(
${80 - Math.random() * 80}deg,
#${Math.random().toString(16).substring(2, 8)},
#${Math.random().toString(16).substring(2, 8)},
purple
);
--delay: ${-k * 20 / total}s;
`;
lzAr.push(lz);
lzpa.appendChild(lz);
});
const boards = document.querySelectorAll('.board');
const setAnimate = (begin = true) => {
lzAr.forEach(lz => {
begin ? lz.classList.add('ani-fly') : lz.classList.remove('ani-fly');
});
};
const setYPos = (up = true) => {
const yy = (papa.clientHeight / 2) * (up ? -1 : 0);
lzpa.style.transform = `translateY(${yy}px)`;
}
const lzInit = () => {
if (aud.paused) {
setAnimate(false);
setTimeout( () => {
upboard.style.setProperty('transform', `rotateX(90deg) translateZ(calc(var(--size) / 2))`);
setYPos(false);
}, 500);
} else {
upboard.style.setProperty('transform', `rotateX(180deg) translateZ(300px)`);
setYPos(true);
setTimeout( () => {
setAnimate(true);
}, 500);
}
};
aud.onplaying = aud.onpause = () => lzInit();
window.onresize = () => {
papa.style.setProperty('perspective', 800 * papa.clientWidth/1400 + 'px');
papa.style.setProperty('--z', 300 * papa.clientWidth/1400 + 'px');
setYPos(aud.paused ? false : true);
}
FS(papa, box);
</script> 本帖最后由 马黑黑 于 2025-7-11 21:43 编辑
参考代码:
<style>
#papa { margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1400px); height: auto; aspect-ratio: 16/9; background: url('https://638183.freep.cn/638183/t24/w4/mocho.webp') no-repeat center/cover; perspective: 800px; box-shadow: 2px 2px 8px #000; z-index: 1; display: grid; place-items: center; position: relative; --size: 120px; --z: 300px; }
#papa div { display: inherit; place-items: inherit; }
#btnFs { left: 15px; bottom: 20px; color: white; }
#box { --bg: #000; --border-color: yellow; position: absolute; bottom: 50px; width: var(--size); height: var(--size); transform-style: preserve-3d; transform: rotateX(-15deg) rotateY(30deg) rotateZ(0); }
#lzpa { position: absolute; bottom: 50px; width: calc(var(--size) - 50px); height: calc(var(--size) - 50px); transition: transform 0.75s; transform-style: preserve-3d; }
li-zi { position: absolute; width: 25px; height: 25px; border-radius: 50%; background: linear-gradient(35deg, skyblue, green); }
.front { transform: rotateY(0) translateZ(calc(var(--size) / 2)); }
.back { transform: rotateY(180deg) translateZ(calc(var(--size) / 2)); }
.left { transform: rotateY(-90deg) translateZ(calc(var(--size) / 2)); }
.right { transform: rotateY(90deg) translateZ(calc(var(--size) / 2)); }
.top { transform: rotateX(90deg) translateZ(calc(var(--size) / 2)); }
.bottom { transform: rotateX(-90deg) translateZ(calc(var(--size) / 2)); }
.board { position: absolute; width: 100%; height: 100%; transition: transform 1s; font: bold 30px sans-serif; text-shadow: 2px 2px 4px orange; color: white; border: 3px dotted var(--border-color); background: var(--bg); opacity: 0.45; cursor: pointer; user-select: none; }
.ani-fly { animation: fly 20s var(--delay) linear infinite; }
@keyframes fly {
from { transform: rotateY(0) translate3d(0, 0, var(--z)); }
to { transform: rotateY(-360deg) translate3d(0, 0, var(--z)) rotateY(360deg); }
}
</style>
<div id="papa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=1066074" autoplay loop></audio>
<div id="lzpa"></div>
<div id="box">
<div class="board front">PLAY</div>
<div class="board back"></div>
<div class="board left"></div>
<div class="board right"></div>
<div id="upboard" class="board top"></div>
<div class="board bottom"></div>
</div>
</div>
<script type="module">
import { FS } from 'https://638183.freep.cn/638183/web/js/fullscreen.js'
const total = 60;
const lzAr = [];
let lzRun = false;
Array.from({ length: total }).forEach( (lz, k) => {
lz = document.createElement('li-zi');
lz.style.cssText += `
left: ${lzpa.clientWidth * Math.random()}px;
top: ${lzpa.clientHeight * Math.random()}px;
background: linear-gradient(
${80 - Math.random() * 80}deg,
#${Math.random().toString(16).substring(2, 8)},
#${Math.random().toString(16).substring(2, 8)},
purple
);
--delay: ${-k * 20 / total}s;
`;
lzAr.push(lz);
lzpa.appendChild(lz);
});
const boards = document.querySelectorAll('.board');
const setAnimate = (begin = true) => {
lzAr.forEach(lz => {
begin ? lz.classList.add('ani-fly') : lz.classList.remove('ani-fly');
});
};
const setYPos = (up = true) => {
const yy = (papa.clientHeight / 2) * (up ? -1 : 0);
lzpa.style.transform = `translateY(${yy}px)`;
}
const lzInit = () => {
if (aud.paused) {
setAnimate(false);
setTimeout( () => {
upboard.style.setProperty('transform', `rotateX(90deg) translateZ(calc(var(--size) / 2))`);
setYPos(false);
}, 500);
} else {
upboard.style.setProperty('transform', `rotateX(180deg) translateZ(300px)`);
setYPos(true);
setTimeout( () => {
setAnimate(true);
}, 500);
}
};
aud.onplaying = aud.onpause = () => lzInit();
window.onresize = () => {
papa.style.setProperty('perspective', 800 * papa.clientWidth/1400 + 'px');
papa.style.setProperty('--z', 300 * papa.clientWidth/1400 + 'px');
setYPos(aud.paused ? false : true);
}
FS(papa, box);
</script>
本帖最后由 马黑黑 于 2025-7-11 21:03 编辑
说明:
帖子HTML结构分三层,这是出于控制的便捷性而设计的结构:
帖子容器开始
粒子容器开始
粒子
粒子容器结束
播放器容器开始
立方体播放器
播放器容器结束
帖子容器结束
立方体播放器和粒子是平行的第二层,各自都带有子元素:小播是立方体的两个面,粒子容器是N多个 li-zi 自定义标签。
音频联动控制机制中,通过函数 lzInite() 完成一些CSS数据设置,包括粒子容器的上下位移、粒子的绕圈运动、小播的开合等。这些控制机制有得分类封装成小函数,有得直接操作。联动控制机制用到定时器 setTimeout。
帖子动画机制自适应窗口的功能放在 window.onresize 事件中,主要调节3d动画场景视图、粒子运行的Z轴尺寸和粒子容器位置设置。
帖子实现细节中又不完美之处,例如,粒子整体上下、下降时有点生硬。
有些像开盲盒的效果,赞{:4_178:} 开始带文字的一面应该是在盒子前面,播放时跑到盒子外面,暂停时在盒子顶面,就无法回到盒子前面了呢。 马黑黑 发表于 2025-7-11 20:43
说明:
帖子HTML结构分三层,这是出于控制的便捷性而设计的结构:
这么多动作,尤其粒子的动作特别好看,放出去,散开,聚合,回到盒子,每个动作都很清晰有序。
散开旋转的粒子,在全屏时会有微小的上下移动,就是自适应窗口在起作用吧。{:4_204:} 帖子做得精致,只是这背景图可否换一张{:4_203:} 朵拉 发表于 2025-7-11 20:57
有些像开盲盒的效果,赞
这是京东盲盒{:4_170:} 红影 发表于 2025-7-11 21:39
开始带文字的一面应该是在盒子前面,播放时跑到盒子外面,暂停时在盒子顶面,就无法回到盒子前面了呢。
ID放错地方了,谢谢提醒 这个是问候小辣椒的,进来就忙着看帖子,都忘了喊她。@小辣椒 亲爱的快来收礼{:4_187:} 红影 发表于 2025-7-11 21:43
这么多动作,尤其粒子的动作特别好看,放出去,散开,聚合,回到盒子,每个动作都很清晰有序。
散开旋转 ...
这是CSS对应选择器 transition 属性在起作用:只要设置了该属性,基于指定属性的变化过程,就在该属性值内完成。 马黑黑 发表于 2025-7-11 21:44
ID放错地方了,谢谢提醒
呵呵,现在文字一面一直在前面了{:4_173:} 马黑黑 发表于 2025-7-11 21:45
这是CSS对应选择器 transition 属性在起作用:只要设置了该属性,基于指定属性的变化过程,就在该属性值 ...
这个动作的设置特别好看。粒子的排布也很奇特,层层叠叠的呢。 红影 发表于 2025-7-11 21:47
呵呵,现在文字一面一直在前面了
这是改来改去改错的:之前是使用 去而已Sel二次托人All 获取操作标识的,最后觉得就操作一个面板,不如就加个标签ID吧,然后就加错地方了 红影 发表于 2025-7-11 21:44
这个是问候小辣椒的,进来就忙着看帖子,都忘了喊她。@小辣椒 亲爱的快来收礼
{:4_190:} 红影 发表于 2025-7-11 21:49
这个动作的设置特别好看。粒子的排布也很奇特,层层叠叠的呢。
这是在JS创建粒子时安排好的:粒子在其父容器内在指定范围内随机分布 构思奇特,效果惊艳,很智能的感觉{:4_191:}
借马老师美帖祝小辣椒开心幸福{:4_187:} 马黑黑 发表于 2025-7-11 21:50
这是改来改去改错的:之前是使用 去而已Sel二次托人All 获取操作标识的,最后觉得就操作一个面板,不如就 ...
那个加错的其实也挺好看的,很有特点呢{:4_187:} 马黑黑 发表于 2025-7-11 21:50
替她先谢谢黑黑的惦记,和黑黑一起祝福她安康。{:4_204:} 马黑黑 发表于 2025-7-11 21:51
这是在JS创建粒子时安排好的:粒子在其父容器内在指定范围内随机分布
这样的排布方式特别好,很丰富的感觉。