机器人发福利
本帖最后由 马黑黑 于 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 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>
本帖:
ThreeJS 动画特效由 GLTF 模型自带,帖子JS代码中检索模型所带的全部动画,每隔十秒随机播放其中的一个动画(可能有重复上一个动画的现象),音乐暂停时动画间隔机制不改变。
播放 .glb 模型动画的相关介绍请查看 《那匹马》 :https://www.huachaowang.com/forum.php?mod=viewthread&tid=84502&extra=page%3D1 本帖所使用的机器人模型集成有很多动画,详情请查阅:
ThreeJS:罗列并运行GLTF模型所有动画
在上述页面运行代码,可以看到页面上方有很多按钮,按钮上面的名称即为模型自带动画的名称
问好黑黑
欣赏你的精彩
{:4_178:} 现在AI有很高的智能啊,阿法尔狗电脑竟然下赢围棋世界冠军柯洁了。 马黑黑 发表于 2025-7-4 13:05
本帖:
ThreeJS 动画特效由 GLTF 模型自带,帖子JS代码中检索模型所带的全部动画,每隔十秒随机播放其中 ...
模型之前有两个贴子里曾出现过,比如万马奔腾,还有飞鸟。。。
这个机器人模型所带的运动更加复杂,动作更多。。。
它舞跳得不错,非常协调,也有难度,应该跟名师学习过。{:4_173:} 右键机器人转动滚轮,可以变大或者变小。。。更厉害的是无论大小都一样清晰。。。这就是模型的优势所在吧 马黑黑 发表于 2025-7-4 13:10
本帖所使用的机器人模型集成有很多动画,详情请查阅:
看了一下,很壮观的一排按纽。。。
这么多分开的动作,在贴子里合并集为一体了。。。{:4_170:}
原来是JS代码检索出所有动画,再按10秒进行播放。。效果完美 太厉害了,这机器人是用代码画出来,不可思议!{:4_187:} 点击机器人还会缩小,跳舞,打招呼, 效果独特,内涵丰富,谢谢马老师经典示范{:4_191:} 实现了:模型 + 动画 = 精彩无限 机器人会跳舞,还发红包,赞一个
“不同的模型其内部机制有所不同,模型场景的缩放系数需要调整,模型场景在ThreeJS场景中的初始位置、初始旋转角度则根据模型的具体情况和展现模型需求而定。”,这个调整就不易了
请教马老师,“ @keyframes rot { to { transform: rotate(360deg); } }”起什么作用呀{:4_190:} 杨帆 发表于 2025-7-4 17:34
请教马老师,“ @keyframes rot { to { transform: rotate(360deg); } }”起什么作用呀
这是多余代码:原理设计有一个旋转的图片,后面拿掉了,CSS对应语句没有拿掉。 杨帆 发表于 2025-7-4 17:31
“不同的模型其内部机制有所不同,模型场景的缩放系数需要调整,模型场景在ThreeJS场景中的初始位置、初 ...
就是位置、旋转、缩放相关 梦江南 发表于 2025-7-4 15:49
点击机器人还会缩小,跳舞,打招呼,
它有很多个动作,都集成在模型里 花飞飞 发表于 2025-7-4 13:57
看了一下,很壮观的一排按纽。。。
这么多分开的动作,在贴子里合并集为一体了。。。
原来是J ...
{:4_190:}