马黑黑 发表于 2025-5-3 17:37

太空

<style>
        #papa { --state: running; margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1600px); height: auto; aspect-ratio: 16/9; background: #000 url('https://638183.freep.cn/638183/small/tdks.jpg') no-repeat center/cover; box-shadow: 2px 2px 10px rgba(0,0,0,.65); z-index: 1; display: grid; place-items: center; position: relative; }
#player { position: absolute; z-index: 9; clip-path: circle(45%); transition: filter .7s; cursor: pointer; animation: rot 10s linear infinite var(--state); }
        #player:hover { filter: hue-rotate(90deg); }
        #btnFs { bottom: 30px; color: #eee; }
        #btnFs:hover { color: red; }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=1393476199" autoplay loop></audio>
        <img id="player" src="https://638183.freep.cn/638183/small/mufuz2.jpg" width="10%" title="播放/暂停" />
</div>

<script type="importmap">
        {
                "imports": {
                        "three": "https://esm.sh/three/build/three.webgpu.js",
                        "three/tsl": "https://esm.sh/three@0.176.0/es2022/build/three.tsl.mjs"
                }
        }
</script>

<script type="module">

import * as THREE from 'three';
import {uniform, time, instanceIndex, instancedBufferAttribute} from 'three/tsl';
import {FS} from 'https://638183.freep.cn/638183/web/ku/fscreen.js';

let camera, scene, renderer, material;
let mouseX = 0, mouseY = 0;
let width = papa.offsetWidth, height = papa.offsetHeight;
let windowHalfX = width / 2;
let windowHalfY = height / 2;

const init = () => {
        camera = new THREE.PerspectiveCamera(55, width / height, 2, 2000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        scene.fog = new THREE.FogExp2(0x000000, 0.001);
        const count = 6000;
        const positions = [];
        for (let i = 0; i < count; i ++) {
                positions.push( 2000 * Math.random() - 1000, 2000 * Math.random() - 1000, 2000 * Math.random() - 1000 );
        }
        const positionAttribute = new THREE.InstancedBufferAttribute(new Float32Array(positions), 3);
        const map = new THREE.TextureLoader().load('https://638183.freep.cn/638183/small/star.png');
        map.colorSpace = THREE.SRGBColorSpace;
        material = new THREE.SpriteNodeMaterial({sizeAttenuation: true, map, alphaMap: map, alphaTest: 0.1});
        material.color.setHSL(1.0, 0.3, 0.7, THREE.SRGBColorSpace);
        material.positionNode = instancedBufferAttribute(positionAttribute);
        material.rotationNode = time.add(instanceIndex).sin();
        material.scaleNode = uniform(15);
        const particles = new THREE.Sprite(material);
        particles.count = count;
        scene.add(particles);
        renderer = new THREE.WebGPURenderer();
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(width, height);
        renderer.setAnimationLoop(render);
        papa.appendChild(renderer.domElement);
        papa.style.touchAction = 'none';
        papa.addEventListener('pointermove', onPointerMove);
        window.addEventListener('resize', onWindowResize);
};

const onWindowResize = () => {
        width = papa.offsetWidth;
        height = papa.offsetHeight;
        windowHalfX = width / 2;
        windowHalfY = height / 2;
        camera.aspect = width / height;
        camera.updateProjectionMatrix();
        renderer.setSize(width, height);
};

const onPointerMove = (event) => {
        if (event.isPrimary === false) return;
        mouseX = event.clientX - windowHalfX;
        mouseY = event.clientY - windowHalfY;
};

const render = () => {
        const time = Date.now() * 0.00005;
        camera.position.x += (mouseX - camera.position.x) * 0.05;
        camera.position.y += (- mouseY - camera.position.y) * 0.05;
        camera.lookAt(scene.position);
        const h = ( 360 * (1.0 + time ) % 360) / 360;
        material.color.setHSL(h, 0.5, 0.5);
        renderer.render(scene, camera);
};

init();
FS(papa, player);

</script>

马黑黑 发表于 2025-5-3 17:40

帖子代码:

<style>
        #papa { --state: running; margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%); width: clamp(600px, 90vw, 1600px); height: auto; aspect-ratio: 16/9; background: #000 url('https://638183.freep.cn/638183/small/tdks.jpg') no-repeat center/cover; box-shadow: 2px 2px 10px rgba(0,0,0,.65); z-index: 1; display: grid; place-items: center; position: relative; }
#player { position: absolute; z-index: 9; clip-path: circle(45%); transition: filter .7s; cursor: pointer; animation: rot 10s linear infinite var(--state); }
        #player:hover { filter: hue-rotate(90deg); }
        #btnFs { bottom: 30px; color: #eee; }
        #btnFs:hover { color: red; }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=1393476199" autoplay loop></audio>
        <img id="player" src="https://638183.freep.cn/638183/small/mufuz2.jpg" width="10%" title="播放/暂停" />
</div>

<script type="importmap">
        {
                "imports": {
                        "three": "https://esm.sh/three/build/three.webgpu.js",
                        "three/tsl": "https://esm.sh/three@0.176.0/es2022/build/three.tsl.mjs"
                }
        }
</script>

<script type="module">

import * as THREE from 'three';
import {uniform, time, instanceIndex, instancedBufferAttribute} from 'three/tsl';
import {FS} from 'https://638183.freep.cn/638183/web/ku/fscreen.js';

let camera, scene, renderer, material;
let mouseX = 0, mouseY = 0;
let width = papa.offsetWidth, height = papa.offsetHeight;
let windowHalfX = width / 2;
let windowHalfY = height / 2;

const init = () => {
        camera = new THREE.PerspectiveCamera(55, width / height, 2, 2000);
        camera.position.z = 1000;
        scene = new THREE.Scene();
        scene.fog = new THREE.FogExp2(0x000000, 0.001);
        const count = 6000;
        const positions = [];
        for (let i = 0; i < count; i ++) {
                positions.push( 2000 * Math.random() - 1000, 2000 * Math.random() - 1000, 2000 * Math.random() - 1000 );
        }
        const positionAttribute = new THREE.InstancedBufferAttribute(new Float32Array(positions), 3);
        const map = new THREE.TextureLoader().load('https://638183.freep.cn/638183/small/star.png');
        map.colorSpace = THREE.SRGBColorSpace;
        material = new THREE.SpriteNodeMaterial({sizeAttenuation: true, map, alphaMap: map, alphaTest: 0.1});
        material.color.setHSL(1.0, 0.3, 0.7, THREE.SRGBColorSpace);
        material.positionNode = instancedBufferAttribute(positionAttribute);
        material.rotationNode = time.add(instanceIndex).sin();
        material.scaleNode = uniform(15);
        const particles = new THREE.Sprite(material);
        particles.count = count;
        scene.add(particles);
        renderer = new THREE.WebGPURenderer();
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(width, height);
        renderer.setAnimationLoop(render);
        papa.appendChild(renderer.domElement);
        papa.style.touchAction = 'none';
        papa.addEventListener('pointermove', onPointerMove);
        window.addEventListener('resize', onWindowResize);
};

const onWindowResize = () => {
        width = papa.offsetWidth;
        height = papa.offsetHeight;
        windowHalfX = width / 2;
        windowHalfY = height / 2;
        camera.aspect = width / height;
        camera.updateProjectionMatrix();
        renderer.setSize(width, height);
};

const onPointerMove = (event) => {
        if (event.isPrimary === false) return;
        mouseX = event.clientX - windowHalfX;
        mouseY = event.clientY - windowHalfY;
};

const render = () => {
        const time = Date.now() * 0.00005;
        camera.position.x += (mouseX - camera.position.x) * 0.05;
        camera.position.y += (- mouseY - camera.position.y) * 0.05;
        camera.lookAt(scene.position);
        const h = ( 360 * (1.0 + time ) % 360) / 360;
        material.color.setHSL(h, 0.5, 0.5);
        renderer.render(scene, camera);
};

init();
FS(papa, player);

</script>

花飞飞 发表于 2025-5-3 17:42

沙发又被我抢了。{:4_170:}

马黑黑 发表于 2025-5-3 17:43

本帖基于 three.js 的 webGPU API,仅为测试。

WebGPU 相对于 WebGL 更为强大,但是目前它的兼容性还做得不好,three.js 对此采用了一个回退机制,所以在非 https 协议的网站中,控制台会有一个警告级别的提示。

花飞飞 发表于 2025-5-3 17:44

鼠标跟随能互动的超级好玩。。。
这个星星是彩色的,鼠标移动的方向跟星星运动方向不同
空间感绝了,能感觉到太空深处。。

马黑黑 发表于 2025-5-3 17:45

花飞飞 发表于 2025-5-3 17:42
沙发又被我抢了。

你坐的是高端板凳,材质和沙发一样,舒适度也和沙发无异

花飞飞 发表于 2025-5-3 17:49

星星居然是个可以替换的图片,我的天,那岂不是可以有无限种可能。。。。{:4_173:}
之前你说那个扑面粒子有5000个,这个是有6000个么。

花飞飞 发表于 2025-5-3 17:50

马黑黑 发表于 2025-5-3 17:45
你坐的是高端板凳,材质和沙发一样,舒适度也和沙发无异

才不是,江湖默认第一个回复坐的都是沙发。{:4_173:}

花飞飞 发表于 2025-5-3 17:52

马黑黑 发表于 2025-5-3 17:43
本帖基于 three.js 的 webGPU API,仅为测试。

WebGPU 相对于 WebGL 更为强大,但是目前它的兼容性还做 ...

能运行,能互动,目前并没收到警告提示

马黑黑 发表于 2025-5-3 17:55

花飞飞 发表于 2025-5-3 17:52
能运行,能互动,目前并没收到警告提示

警告是无关紧要的。错误才是致命的:运行不了。

另外,论坛是 https 协议,没问题的

马黑黑 发表于 2025-5-3 17:55

花飞飞 发表于 2025-5-3 17:50
才不是,江湖默认第一个回复坐的都是沙发。

第一个回复是我呀,二楼

马黑黑 发表于 2025-5-3 17:56

花飞飞 发表于 2025-5-3 17:49
星星居然是个可以替换的图片,我的天,那岂不是可以有无限种可能。。。。
之前你说那个扑面粒子 ...

但是非常复杂,没有 css + HTML + CSS 那么一目了然

马黑黑 发表于 2025-5-3 17:57

花飞飞 发表于 2025-5-3 17:44
鼠标跟随能互动的超级好玩。。。
这个星星是彩色的,鼠标移动的方向跟星星运动方向不同
空间感绝了,能感 ...

星星是变色的

花飞飞 发表于 2025-5-3 18:03

马黑黑 发表于 2025-5-3 17:55
警告是无关紧要的。错误才是致命的:运行不了。

另外,论坛是 https 协议,没问题的

没见过警告,。。。
开始学代码时整过不能运行的,这个见过
论坛应该能兼容多数效果吧。。不然它会被用的人淘汰的

花飞飞 发表于 2025-5-3 18:05

马黑黑 发表于 2025-5-3 17:55
第一个回复是我呀,二楼

你发的贴子啊,有补充说明是正常的。你总 不能把东西放在沙发上。。
所以回复的第一个人坐的就是沙发。{:4_173:}

花飞飞 发表于 2025-5-3 18:06

马黑黑 发表于 2025-5-3 17:56
但是非常复杂,没有 css + HTML + CSS 那么一目了然

看到引用了两个JS,还有这么大一群代码,每个代码都是一颗星星的节奏。{:4_173:}

花飞飞 发表于 2025-5-3 18:06

马黑黑 发表于 2025-5-3 17:57
星星是变色的

各种颜色随机出现,这个色更好看些。。

马黑黑 发表于 2025-5-3 18:32

花飞飞 发表于 2025-5-3 18:06
看到引用了两个JS,还有这么大一群代码,每个代码都是一颗星星的节奏。

第一个JS是引路用的,用来构造资源对象。three.js 需要引入太多资源,这些资源目前来源于那个 esm.sh 中转站,目前是比较好用的

马黑黑 发表于 2025-5-3 18:32

花飞飞 发表于 2025-5-3 18:06
各种颜色随机出现,这个色更好看些。。

五色令人目盲{:4_170:}

马黑黑 发表于 2025-5-3 18:34

花飞飞 发表于 2025-5-3 18:03
没见过警告,。。。
开始学代码时整过不能运行的,这个见过
论坛应该能兼容多数效果吧。。不然它会被用 ...

这个不是论坛的问题,是网站的协议,http 和 https ,前者现在被认为是不安全的,用个 WebGPU 接口也会警告有危险。
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: 太空