马黑黑 发表于 2025-7-4 13:00

机器人发福利

本帖最后由 马黑黑 于 2025-7-4 17:49 编辑 <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: snow url('https://638183.freep.cn/638183/t24/6/stage.jpg') no-repeat center/cover; box-shadow: 2px 2px 8px #000; display: grid; place-items: center; z-index: 1; position: relative; --state: running; }
    #btnFs { bottom: 30px; color: cyan; border-color: cyan !important; }
    #player { position: absolute; left: -1000px; }
    #vid {position: absolute; width: 100%; height: 100%; object-fit: cover; mask: radial-gradient(transparent 20%, red); -webkit-mask: radial-gradient(transparent 20%, red); opacity: .6; pointer-events: none; }
</style>

<div id="papa">
    <audio id="aud" src="https://music.163.com/song/media/outer/url?id=2077537719" autoplay loop></audio>
    <video id="vid" src="https://bpic.588ku.com/video_listen/588ku_video/22/11/03/14/51/00/video636364d43e50d.mp4" autoplay loop muted></video>
    <div id="player"></div>
</div>

<script type="importmap">
    {
      "imports": {
            "three": "https://638183.freep.cn/638183/3dev/build/three.module.min.js",
            "three/addons/": "https://638183.freep.cn/638183/3dev/examples/jsm/"
      }
    }
</script>
<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 { OrbitControls } from "three/addons/controls/OrbitControls.js";
    import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
    import { FS } from 'https://638183.freep.cn/638183/web/ku/FS.js';
    basic3(papa);

    renderer.outputEncoding = THREE.sRGBEncoding;
    const controls = new OrbitControls(camera, renderer.domElement);

    let mixer, model, startTime = 0, actions = [];
    const url = 'https://638183.freep.cn/638183/web/3models/RobotExpressive.glb';

    scene.add(new THREE.AmbientLight());

    new GLTFLoader().load(url, gltf => {
      model = gltf.scene;
      const scale = 0.5;
      model.scale.set(scale, scale, scale);
      model.position.y -= 2;
      scene.add(model);
      mixer = new THREE.AnimationMixer(model);
      if (gltf.animations.length > 0) {
            gltf.animations.forEach(a => actions.push(a));
            playModel();
      }
      animate();
   });

    function animate() {
      requestAnimationFrame(animate);
      camera.lookAt(0, 0, 0);
      const delta = clock.getDelta();
      mixer.update(delta);
      renderer.render(scene, camera);
    }

    function playModel(idx = null) {
      const playIdx = idx !== null ? idx : Math.floor(Math.random() * actions.length);
      for (let k = 0; k < actions.length; k ++) {
            const clip = mixer.clipAction(actions);
            k === playIdx ? clip.play() : clip.stop();
      }
    }

    aud.onplaying = aud.onpause = () => {
      aud.paused ? clock.stop() : clock.start();
    };

    papa.onmousedown = () => startTime = Date.now();

    papa.onmouseup = (e) => {
      if (!click3(model, e)) return;
          if (Date.now() - startTime < 300) player.click();
   };

    papa.onmousemove = (e) => {
      papa.title = click3(model, e) ? '播放/暂停(Alt+X)' : '';
      papa.style.cursor = click3(model, e) ? 'pointer' : 'default';
    };

    setInterval(playModel, 10000);

    FS(papa, player);
</script>

马黑黑 发表于 2025-7-4 13:00

本帖最后由 马黑黑 于 2025-7-4 17:49 编辑

帖子代码

<style>
    #papa { margin: 30px 0; left: calc(50% - 81px); transform: translateX(-50%);width: clamp(600px, 90vw, 1400px); height: auto; aspect-ratio: 16/9; background: snow url('https://638183.freep.cn/638183/t24/6/stage.jpg') no-repeat center/cover; box-shadow: 2px 2px 8px #000; display: grid; place-items: center; z-index: 1; position: relative; --state: running; }
    #btnFs { bottom: 30px; color: cyan; border-color: cyan !important; }
    #player { position: absolute; left: -1000px; }
    #vid {position: absolute; width: 100%; height: 100%; object-fit: cover; mask: radial-gradient(transparent 20%, red); -webkit-mask: radial-gradient(transparent 20%, red); opacity: .6; pointer-events: none; }
</style>

<div id="papa">
    <audio id="aud" src="https://music.163.com/song/media/outer/url?id=2077537719" autoplay loop></audio>
    <video id="vid" src="https://bpic.588ku.com/video_listen/588ku_video/22/11/03/14/51/00/video636364d43e50d.mp4" autoplay loop muted></video>
    <div id="player"></div>
</div>

<script type="importmap">
    {
      "imports": {
            "three": "https://638183.freep.cn/638183/3dev/build/three.module.min.js",
            "three/addons/": "https://638183.freep.cn/638183/3dev/examples/jsm/"
      }
    }
</script>
<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 { OrbitControls } from "three/addons/controls/OrbitControls.js";
    import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
    import { FS } from 'https://638183.freep.cn/638183/web/ku/FS.js';
    basic3(papa);

    renderer.outputEncoding = THREE.sRGBEncoding;
    const controls = new OrbitControls(camera, renderer.domElement);

    let mixer, model, startTime = 0, actions = [];
    const url = 'https://638183.freep.cn/638183/web/3models/RobotExpressive.glb';

    scene.add(new THREE.AmbientLight());

    new GLTFLoader().load(url, gltf => {
      model = gltf.scene;
      const scale = 0.5;
      model.scale.set(scale, scale, scale);
      model.position.y -= 2;
      scene.add(model);
      mixer = new THREE.AnimationMixer(model);
      if (gltf.animations.length > 0) {
            gltf.animations.forEach(a => actions.push(a));
            playModel();
      }
      animate();
   });

    function animate() {
      requestAnimationFrame(animate);
      camera.lookAt(0, 0, 0);
      const delta = clock.getDelta();
      mixer.update(delta);
      renderer.render(scene, camera);
    }

    function playModel(idx = null) {
      const playIdx = idx !== null ? idx : Math.floor(Math.random() * actions.length);
      for (let k = 0; k < actions.length; k ++) {
            const clip = mixer.clipAction(actions);
            k === playIdx ? clip.play() : clip.stop();
      }
    }

    aud.onplaying = aud.onpause = () => {
      aud.paused ? clock.stop() : clock.start();
    };

    papa.onmousedown = () => startTime = Date.now();

    papa.onmouseup = (e) => {
      if (!click3(model, e)) return;
            if (Date.now() - startTime < 300) player.click();
   };

    papa.onmousemove = (e) => {
      papa.title = click3(model, e) ? '播放/暂停(Alt+X)' : '';
      papa.style.cursor = click3(model, e) ? 'pointer' : 'default';
    };

    setInterval(playModel, 10000);

    FS(papa, player);
</script>

马黑黑 发表于 2025-7-4 13:05

本帖:

ThreeJS 动画特效由 GLTF 模型自带,帖子JS代码中检索模型所带的全部动画,每隔十秒随机播放其中的一个动画(可能有重复上一个动画的现象),音乐暂停时动画间隔机制不改变。

播放 .glb 模型动画的相关介绍请查看 《那匹马》 :https://www.huachaowang.com/forum.php?mod=viewthread&tid=84502&extra=page%3D1

马黑黑 发表于 2025-7-4 13:10

本帖所使用的机器人模型集成有很多动画,详情请查阅:


    ThreeJS:罗列并运行GLTF模型所有动画

在上述页面运行代码,可以看到页面上方有很多按钮,按钮上面的名称即为模型自带动画的名称

寻梦花园 发表于 2025-7-4 13:26

问好黑黑
欣赏你的精彩
{:4_178:}

愤怒的葡萄 发表于 2025-7-4 13:32

现在AI有很高的智能啊,阿法尔狗电脑竟然下赢围棋世界冠军柯洁了。

花飞飞 发表于 2025-7-4 13:51

马黑黑 发表于 2025-7-4 13:05
本帖:

ThreeJS 动画特效由 GLTF 模型自带,帖子JS代码中检索模型所带的全部动画,每隔十秒随机播放其中 ...

模型之前有两个贴子里曾出现过,比如万马奔腾,还有飞鸟。。。
这个机器人模型所带的运动更加复杂,动作更多。。。
它舞跳得不错,非常协调,也有难度,应该跟名师学习过。{:4_173:}

花飞飞 发表于 2025-7-4 13:53

右键机器人转动滚轮,可以变大或者变小。。。更厉害的是无论大小都一样清晰。。。这就是模型的优势所在吧

花飞飞 发表于 2025-7-4 13:57

马黑黑 发表于 2025-7-4 13:10
本帖所使用的机器人模型集成有很多动画,详情请查阅:




看了一下,很壮观的一排按纽。。。
这么多分开的动作,在贴子里合并集为一体了。。。{:4_170:}
原来是JS代码检索出所有动画,再按10秒进行播放。。效果完美

梦江南 发表于 2025-7-4 15:45

太厉害了,这机器人是用代码画出来,不可思议!{:4_187:}

梦江南 发表于 2025-7-4 15:49

点击机器人还会缩小,跳舞,打招呼,

杨帆 发表于 2025-7-4 17:19

效果独特,内涵丰富,谢谢马老师经典示范{:4_191:}

杨帆 发表于 2025-7-4 17:20

实现了:模型 + 动画 = 精彩无限

杨帆 发表于 2025-7-4 17:21

机器人会跳舞,还发红包,赞一个

杨帆 发表于 2025-7-4 17:31


“不同的模型其内部机制有所不同,模型场景的缩放系数需要调整,模型场景在ThreeJS场景中的初始位置、初始旋转角度则根据模型的具体情况和展现模型需求而定。”,这个调整就不易了

杨帆 发表于 2025-7-4 17:34

请教马老师,“ @keyframes rot { to { transform: rotate(360deg); } }”起什么作用呀{:4_190:}

马黑黑 发表于 2025-7-4 17:42

杨帆 发表于 2025-7-4 17:34
请教马老师,“ @keyframes rot { to { transform: rotate(360deg); } }”起什么作用呀

这是多余代码:原理设计有一个旋转的图片,后面拿掉了,CSS对应语句没有拿掉。

马黑黑 发表于 2025-7-4 17:43

杨帆 发表于 2025-7-4 17:31
“不同的模型其内部机制有所不同,模型场景的缩放系数需要调整,模型场景在ThreeJS场景中的初始位置、初 ...

就是位置、旋转、缩放相关

马黑黑 发表于 2025-7-4 17:44

梦江南 发表于 2025-7-4 15:49
点击机器人还会缩小,跳舞,打招呼,

它有很多个动作,都集成在模型里

马黑黑 发表于 2025-7-4 17:44

花飞飞 发表于 2025-7-4 13:57
看了一下,很壮观的一排按纽。。。
这么多分开的动作,在贴子里合并集为一体了。。。
原来是J ...

{:4_190:}
页: [1] 2 3 4 5 6
查看完整版本: 机器人发福利