遇见都是天意
<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/5/2501.jpg') no-repeat center/cover; box-shadow: 2px 2px 8px #000; display: grid; place-items: center; z-index: 1; position: relative; }
#btnFs { bottom: 30px; color: #eee; }
#player { position: absolute; left: -1000px; }
</style>
<div id="papa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=2042902830" autoplay loop></audio>
<div id="player"></div>
</div>
<script type="module">
import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js?v=1.0';
import TWEEN from 'https://638183.freep.cn/638183/3dev/examples/jsm/libs/tween.module.js';
import { FS } from 'https://638183.freep.cn/638183/web/ku/FS.js';
basic3(papa, aud.paused);
// 绘制点云球体 :点颜色随机
const geometry = new THREE.SphereGeometry(0.8, 64, 64);
const count = geometry.attributes.position.count;
const colors = new Float32Array(count * 3);
for (let i = 0; i < count; i++) {
colors = Math.random();
colors = Math.random();
colors = Math.random();
}
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.PointsMaterial({ size: 0.05, vertexColors: true });
const mesh = new THREE.Points(geometry, material);
scene.add(mesh);
// 加入 tween 动画 :点从球体飞往各处再折回
const startPositions = geometry.getAttribute('position');
for(let i = 0; i < startPositions.count; i++) {
if (i % 5 === 0) continue; // 排除索引被5整除的点
const tween = new TWEEN.Tween(startPositions.array)
.to({
: THREE.MathUtils.randFloatSpread(10),
: THREE.MathUtils.randFloatSpread(10),
: THREE.MathUtils.randFloatSpread(10)
}, 5000 * Math.random() + 6000)
.delay(2000)
.easing(TWEEN.Easing.Exponential.Out)
.onUpdate(() => startPositions.needsUpdate = true)
.repeat(Infinity)
.repeatDelay(1500)
.yoyo(6000)
.start();
}
const animate = () => {
TWEEN.update();
const delta = clock.getDelta();
mesh.rotation.x += delta / 5;
mesh.rotation.y += delta / 5;
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
papa.onclick = (e) => {
if (click3(mesh, e)) player.click();
};
papa.onmousemove = (e) => {
papa.title = click3(mesh, e) ? '播放/暂停(Alt+X)' : '';
papa.style.cursor = click3(mesh, e) ? 'pointer' : 'default';
};
const tweens = TWEEN.getAll();
aud.onplaying = aud.onpause = () => {
tweens.forEach(tween => aud.paused ? tween.pause() : tween.resume());
aud.paused ? clock.stop() : clock.start();
};
animate();
FS(papa, player);
</script>
音频为 枫尚 / 老陈阿 的小串串系列。帖子代码:
<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/5/2501.jpg') no-repeat center/cover; box-shadow: 2px 2px 8px #000; display: grid; place-items: center; z-index: 1; position: relative; }
#btnFs { bottom: 30px; color: #eee; }
#player { position: absolute; left: -1000px; }
</style>
<div id="papa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=2042902830" autoplay loop></audio>
<div id="player"></div>
</div>
<script type="module">
import { THREE, scene, camera, renderer, clock, basic3, click3 } from 'https://638183.freep.cn/638183/3dev/3/3basic.js?v=1.0';
import TWEEN from 'https://638183.freep.cn/638183/3dev/examples/jsm/libs/tween.module.js';
import { FS } from 'https://638183.freep.cn/638183/web/ku/FS.js';
basic3(papa, aud.paused);
// 绘制点云球体 :点颜色随机
const geometry = new THREE.SphereGeometry(0.8, 64, 64);
const count = geometry.attributes.position.count;
const colors = new Float32Array(count * 3);
for (let i = 0; i < count; i++) {
colors = Math.random();
colors = Math.random();
colors = Math.random();
}
geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
const material = new THREE.PointsMaterial({ size: 0.05, vertexColors: true });
const mesh = new THREE.Points(geometry, material);
scene.add(mesh);
// 加入 tween 动画 :点从球体飞往各处再折回
const startPositions = geometry.getAttribute('position');
for(let i = 0; i < startPositions.count; i++) {
if (i % 5 === 0) continue; // 排除索引被5整除的点
const tween = new TWEEN.Tween(startPositions.array)
.to({
: THREE.MathUtils.randFloatSpread(10),
: THREE.MathUtils.randFloatSpread(10),
: THREE.MathUtils.randFloatSpread(10)
}, 5000 * Math.random() + 6000)
.delay(2000)
.easing(TWEEN.Easing.Exponential.Out)
.onUpdate(() => startPositions.needsUpdate = true)
.repeat(Infinity)
.repeatDelay(1500)
.yoyo(6000)
.start();
}
const animate = () => {
TWEEN.update();
const delta = clock.getDelta();
mesh.rotation.x += delta / 5;
mesh.rotation.y += delta / 5;
renderer.render(scene, camera);
requestAnimationFrame(animate);
};
papa.onclick = (e) => {
if (click3(mesh, e)) player.click();
};
papa.onmousemove = (e) => {
papa.title = click3(mesh, e) ? '播放/暂停(Alt+X)' : '';
papa.style.cursor = click3(mesh, e) ? 'pointer' : 'default';
};
const tweens = TWEEN.getAll();
aud.onplaying = aud.onpause = () => {
tweens.forEach(tween => aud.paused ? tween.pause() : tween.resume());
aud.paused ? clock.stop() : clock.start();
};
animate();
FS(papa, player);
</script>
本帖使用到的点云材质着色技术请参阅:ThreeJS点材质着色问题 - 马黑黑教程专版 - 花潮论坛 - Powered by Discuz!
Tween 动画:tween.js 初探 - 马黑黑教程专版 - 花潮论坛 - Powered by Discuz!
黑黑老师的代码魔术盒真厉害!{:4_178:} 这个有意思,做Tween 动画的时候,还留下了被5整除的点,其他的店开始循环往复的散开和归拢的过程{:4_199:} 这里来回奔走的粒子在天地间不停遇见啊,这天意也太多了{:4_173:} 漂亮!谢谢马老师经典示范{:4_191:} 花暴了,赶紧切沾光{:4_189:} 樵歌 发表于 2025-6-29 18:29
花暴了,赶紧切沾光
开光了木有{:4_170:} 杨帆 发表于 2025-6-29 13:37
漂亮!谢谢马老师经典示范
{:4_191:} 红影 发表于 2025-6-29 13:34
这里来回奔走的粒子在天地间不停遇见啊,这天意也太多了
天意和天翼一样,无所不在 红影 发表于 2025-6-29 13:32
这个有意思,做Tween 动画的时候,还留下了被5整除的点,其他的店开始循环往复的散开和归拢的过程
{:4_190:} 梦江南 发表于 2025-6-29 11:56
黑黑老师的代码魔术盒真厉害!
{:4_190:} 马黑黑 发表于 2025-6-29 19:51
天意和天翼一样,无所不在
天翼又是什么鬼{:4_173:} 马黑黑 发表于 2025-6-29 19:52
很惊艳的制作{:4_199:} 红影 发表于 2025-6-29 22:29
很惊艳的制作
{:4_191:} 红影 发表于 2025-6-29 22:28
天翼又是什么鬼
天意的老弟 马黑黑 发表于 2025-6-29 22:49
留下能被5整除的,好像剩下的图形也挺好看。 马黑黑 发表于 2025-6-29 22:49
天意的老弟
哈哈,都属于天意家族呗{:4_173:} 红影 发表于 2025-6-29 22:55
留下能被5整除的,好像剩下的图形也挺好看。
是的。被10整除也行