马黑黑 发表于 2025-5-12 20:50

失格人间

<style>
        #tz { --state: running; margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1400px); min-height: 80vh; aspect-ratio: 16/9; background: url('https://638183.freep.cn/638183/t24/webp3/nhtx.webp') no-repeat center/cover; box-shadow: 2px 2px 8px #000; display: grid; place-items: center; z-index: 1; position: relative; }
        #btnFs { bottom: 20px; color: #eee; text-align: center; }
        #btnFs:hover { color: red; }
        #vid {position: absolute; width: 100%; height: 100%; opacity: .5; object-fit: cover; mask: radial-gradient(transparent 20%, red); -webkit-mask: radial-gradient(transparent 20%, red); pointer-events: none; }
        #player { position: absolute; left: 30px; top: 30px; z-index: 10; clip-path: circle(45%); transition: filter .7s; cursor: pointer; animation: rot 8s infinite linear var(--state); }
        #player:hover { filter: invert(0.8); }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="tz">
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=574182361" autoplay loop></audio>
        <video id="vid" src="https://bpic.588ku.com/video_listen/588ku_video/23/09/25/19/47/56/video6511736c0999a.mp4" autoplay loop muted></video>
        <img id="player" src="https://638183.freep.cn/638183/small/snow.webp" width="10%" title="播放/暂停" />
</div>

<script type="module">
        import * as THREE from 'https://esm.sh/three';
        import { OrbitControls } from "https://esm.sh/three/examples/jsm/controls/OrbitControls";
        import { FS } from 'https://638183.freep.cn/638183/web/ku/fscreen.js';

        let isPlaying = true, raf;

        const scene = new THREE.Scene;
        const camera = new THREE.PerspectiveCamera(75, tz.offsetWidth / tz.offsetHeight, 0.1, 1000);
        camera.position.set(0, 0, 5);
        const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        renderer.setSize(tz.offsetWidth, tz.offsetHeight);
        tz.appendChild(renderer.domElement);

        const controller = new OrbitControls(camera, renderer.domElement);
        controller.autoRotate = true;

        const geometry = new THREE.CapsuleGeometry(1, 1, 16, 16);
        geometry.rotateX(0.5);
        geometry.rotateY(0.5);
        const texture = new THREE.TextureLoader().load('https://638183.freep.cn/638183/t24/webp3/nhtx.webp');
        const material = new THREE.MeshBasicMaterial({
                map: texture,
                transparent: true,
                opacity: .6
        });

        const capsule = new THREE.Mesh(geometry, material);
        scene.add(capsule);

        const render = () => {
                isPlaying ? raf = requestAnimationFrame(render) : cancelAnimationFrame(raf);
                controller.update();
                renderer.render(scene, camera);
        };

        window.onresize = () => {
                renderer.setSize(tz.offsetWidth, tz.offsetHeight);
                renderer.render(scene, camera);
        }

        tz.onclick = (e) => {
                if (e.target.id !== 'player') return;
                isPlaying = !aud.paused;
                render();
        };

        render();
        FS(tz, player);
</script>

马黑黑 发表于 2025-5-12 20:51

帖子代码:

<style>
        #tz { --state: running; margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1400px); min-height: 80vh; aspect-ratio: 16/9; background: url('https://638183.freep.cn/638183/t24/webp3/nhtx.webp') no-repeat center/cover; box-shadow: 2px 2px 8px #000; display: grid; place-items: center; z-index: 1; position: relative; }
        #btnFs { bottom: 20px; color: #eee; text-align: center; }
        #btnFs:hover { color: red; }
        #vid {position: absolute; width: 100%; height: 100%; opacity: .5; object-fit: cover; mask: radial-gradient(transparent 20%, red); -webkit-mask: radial-gradient(transparent 20%, red); pointer-events: none; }
        #player { position: absolute; left: 30px; top: 30px; z-index: 10; clip-path: circle(45%); transition: filter .7s; cursor: pointer; animation: rot 8s infinite linear var(--state); }
        #player:hover { filter: invert(0.8); }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="tz">
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=574182361" autoplay loop></audio>
        <video id="vid" src="https://bpic.588ku.com/video_listen/588ku_video/23/09/25/19/47/56/video6511736c0999a.mp4" autoplay loop muted></video>
        <img id="player" src="https://638183.freep.cn/638183/small/snow.webp" width="10%" title="播放/暂停" />
</div>

<script type="module">
        import * as THREE from 'https://esm.sh/three';
        import { OrbitControls } from "https://esm.sh/three/examples/jsm/controls/OrbitControls";
        import { FS } from 'https://638183.freep.cn/638183/web/ku/fscreen.js';

        let isPlaying = true, raf;

        const scene = new THREE.Scene;
        const camera = new THREE.PerspectiveCamera(75, tz.offsetWidth / tz.offsetHeight, 0.1, 1000);
        camera.position.set(0, 0, 5);
        const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        renderer.setSize(tz.offsetWidth, tz.offsetHeight);
        tz.appendChild(renderer.domElement);

        const controller = new OrbitControls(camera, renderer.domElement);
        controller.autoRotate = true;

        const geometry = new THREE.CapsuleGeometry(1, 1, 16, 16);
        geometry.rotateX(0.5);
        geometry.rotateY(0.5);
        const texture = new THREE.TextureLoader().load('https://638183.freep.cn/638183/t24/webp3/nhtx.webp');
        const material = new THREE.MeshBasicMaterial({
                map: texture,
                transparent: true,
                opacity: .6
        });

        const capsule = new THREE.Mesh(geometry, material);
        scene.add(capsule);

        const render = () => {
                isPlaying ? raf = requestAnimationFrame(render) : cancelAnimationFrame(raf);
                controller.update();
                renderer.render(scene, camera);
        };

        window.onresize = () => {
                renderer.setSize(tz.offsetWidth, tz.offsetHeight);
                renderer.render(scene, camera);
        }

        tz.onclick = (e) => {
                if (e.target.id !== 'player') return;
                isPlaying = !aud.paused;
                render();
        };

        render();
        FS(tz, player);
</script>

马黑黑 发表于 2025-5-12 20:52

本帖最后由 马黑黑 于 2025-5-12 20:57 编辑

帖子做的比较匆忙,不知道有木有错误。

解释下:

帖子使用胶囊图形几何体构建 three.js 动画部分的图形骨架。关于胶囊图形几何体,请参与 【新提醒】three.js几何体之胶囊图形几何体 - 马黑黑教程专版 - 花潮论坛 - Powered by Discuz! 。材质使用基础材质,给它做了纹理贴图,代码在 37 ~ 42 行,具体是 37、39 行。

刚做帖时,打算通过胶囊做音频播放/暂停控制,实际上是可以的,只是里面存在诸多交互逻辑问题需要处理,代码量太大,放弃。

花飞飞 发表于 2025-5-12 20:53

居然给胶囊穿了个花衣裳,这个神奇了。。。我仔细看看代码,怎么做到的。。{:4_170:}

花飞飞 发表于 2025-5-12 21:10

马黑黑 发表于 2025-5-12 20:52
帖子做的比较匆忙,不知道有木有错误。

解释下:


这也太厉害了,居然还可以整体贴图,
看代码是在材质之外的。。。

用主体胶囊控制动态,好复杂的吧,它本身构成就很复杂。{:4_199:}支持放弃

马黑黑 发表于 2025-5-12 21:12

花飞飞 发表于 2025-5-12 21:10
这也太厉害了,居然还可以整体贴图,
看代码是在材质之外的。。。



纹理,作用的层面是表面

花飞飞 发表于 2025-5-12 21:17

感觉加了背景图片之后,这里的基础设置线条都不见了。。
是不是可以CapsuleGeometry(1, 1, 16, 16);就前两项就行了。。
那些线反正也看不到了{:4_173:}

花飞飞 发表于 2025-5-12 21:19

马黑黑 发表于 2025-5-12 21:12
纹理,作用的层面是表面

看到了,这个形状适合星球大战里{:4_173:}从胶囊里拿出个秘笈之类的。

小辣椒 发表于 2025-5-12 21:32

发现这个中间的胶囊状旋转效果是背景图一起的??

小辣椒 发表于 2025-5-12 21:34

现在黑黑的代码特效很奇特了

观赏性更强了{:4_178:}

马黑黑 发表于 2025-5-12 22:14

小辣椒 发表于 2025-5-12 21:34
现在黑黑的代码特效很奇特了

观赏性更强了

感谢支持

马黑黑 发表于 2025-5-12 22:14

小辣椒 发表于 2025-5-12 21:32
发现这个中间的胶囊状旋转效果是背景图一起的??
你再细看

马黑黑 发表于 2025-5-12 22:14

花飞飞 发表于 2025-5-12 21:19
看到了,这个形状适合星球大战里从胶囊里拿出个秘笈之类的。

挺厉害的样纸

马黑黑 发表于 2025-5-12 22:15

本帖最后由 马黑黑 于 2025-5-13 07:47 编辑

花飞飞 发表于 2025-5-12 21:17
感觉加了背景图片之后,这里的基础设置线条都不见了。。
是不是可以CapsuleGeometry(1, 1, 16, 16);就前两 ...
线条是通过 wireframe: true 实现的,这里没有了

红影 发表于 2025-5-12 23:32

马黑黑 发表于 2025-5-12 20:52
帖子做的比较匆忙,不知道有木有错误。

解释下:


这个居然是把底图贴它身上了,还以为是胶囊自己反射得到的效果呢{:4_173:}

红影 发表于 2025-5-12 23:35

很奇妙的效果,这背景也选得好,和胶囊贴上的效果相得益彰{:4_199:}

红影 发表于 2025-5-12 23:36

这效果越看越玄幻{:4_199:}

马黑黑 发表于 2025-5-13 07:51

红影 发表于 2025-5-12 23:32
这个居然是把底图贴它身上了,还以为是胶囊自己反射得到的效果呢

好像小辣椒也这么认为。three.js绘制的图形对象支持纹理(texture),可以使用图片、视频等,其中视频会涉及到跨域问题。纹理用于材质的外观属性,和材质的 color 参数同理,给相应参数赋值。

马黑黑 发表于 2025-5-13 07:52

红影 发表于 2025-5-12 23:35
很奇妙的效果,这背景也选得好,和胶囊贴上的效果相得益彰

其实可以使用较小的图片做纹理,也会很好看。texture纹理的细节也很多,以后如果合适,会有专门介绍。

马黑黑 发表于 2025-5-13 07:54

红影 发表于 2025-5-12 23:36
这效果越看越玄幻

这个不仅仅是胶囊穿衣的效果,应该跟胶囊设置了一定透明的有关系。放大看效果玄妙。
页: [1] 2 3
查看完整版本: 失格人间