requestAnimationFrame 实验

requestAnimationFrame 实验

requestAnimationFrame MDN

window.requestAnimationFrame() 方法会告诉浏览器你希望执行一个动画。它要求浏览器在下一次重绘之前,调用用户提供的回调函数。

简而言之,这个方法会让动画表现得更丝滑。今天来做个小实验,看看它和 js, css 设置的动画的表现差异吧。

1. 获取帧率/屏幕刷新率

绘画离不开帧率,借助 performance API 可以大致得出当前屏幕刷新率。

function getRefreshRate(callback) {
    let frames = 0;
    let startTime = performance.now();

    function tick() {
        frames++;
        const currentTime = performance.now();
        const duration = currentTime - startTime;

        if (duration >= 1000) {
            const fps = Math.floor(frames / duration * 1000);
            callback(fps);
        } else {
            requestAnimationFrame(tick);
        }
    }

    requestAnimationFrame(tick);
}

检查

getRefreshRate((fps) => {
    console.log(`refresh rate: ${fps} Hz`);
})

结果(本人电脑):

本人电脑fps-浏览器

确实和本机设置里同值。

本人电脑fps-本机设置

备注:这个计算帧率方法不绝对精确。

2. 偏移动画

设置三个元素,分别用 js-setInterval, js-requestAnimationFrame, css-animation 执行动画,对应代码:

const range = 500

function runA() {
    let tX = 1
    const timer = setInterval(() => {
        boxA.style.transform = `translateX(${tX}px)`;
        tX++;
        if(tX === range + 1) {
            clearInterval(timer)
        }
    }, 1000 / FPS_VALUE)
}

function runB() {
    let tX = 1

    const animate = () => {
        boxB.style.transform = `translateX(${tX}px)`;
        tX++;
        if(tX === range + 1) {
            return;
        }
        requestAnimationFrame(animate);
    }
    
    requestAnimationFrame(animate);
}

function runC() {
    const time = (range / FPS_VALUE) + 's'
    boxC.style.animation = `moveRight ${time} linear forwards`;
}

/*
// css
@keyframes moveRight {
    from {
        transform: translateX(0);
    }
    to {
        transform: translateX(500px);
    }
}
*/

3.效果

gif演示

忽略误差造成的移动速度差距,对比看出,boxA(setInterval 方法)比 boxB(requestAnimationFrame 方法),boxC(animation CSS)有些许卡顿,后两者表现相差无几。

可能 gif 表现不明显–特别是在网站上看,下面有完整代码,拷贝到本地用浏览器打开即可。

完整代码 GitHub

See u! 感谢阅读

### Three.js 示例 实验室 项目教程 #### 使用 WebXR 创建虚拟现实场景 为了创建支持VR的基础场景,可以利用Three.js提供的WebXR功能。通过`three/examples/jsm`加载器引入必要的模块来初始化场景并启用VR模式[^1]。 ```javascript import * as THREE from 'three'; import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; import { XRControllerModelFactory } from 'three/addons/webxr/XRControllerModelFactory.js'; // 初始化场景、相机和渲染器 const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 启用WebXR renderer.xr.enabled = true; ``` #### React 和 Three.js 结合展示环境数据 对于希望集成实时传感器数据显示的应用程序来说,在React应用中嵌入Three.js是一个不错的选择。这允许开发者构建交互式的三维可视化界面来呈现诸如温度和湿度这样的参数变化情况[^2]。 ```jsx import React, { useRef, useEffect } from 'react'; import * as THREE from 'three'; function App() { const mountRef = useRef(null); useEffect(() => { // 设置Three.js场景... function animate() { requestAnimationFrame(animate); // 更新显示逻辑... renderer.render(scene, camera); } animate(); }, []); return ( <div ref={mountRef} style={{ width: "800px", height: "600px" }}></div> ); } export default App; ``` #### 室内导航模拟与角色动画控制 当涉及到更复杂的互动体验时,比如在一个建筑物内部进行漫游或是让一个角色按照预定路径移动,则可能需要用到更加精细的角色动作管理技术。这里介绍如何加载带有多个预设动画的人形模型,并仅激活所需的特定片段(如站立不动或行走),同时调整它们之间的过渡效果[^3]。 ```javascript gltf.scene.traverse((child) => { if (child.isMesh) child.castShadow = true; }); mixer = new THREE.AnimationMixer(gltf.scene); // 获取所有可用的动作名称列表 let actionNames = []; for (let i = 0; i < gltf.animations.length; ++i) { let clip = gltf.animations[i]; actionNames.push(clip.name); } console.log(actionNames); // 输出所有的动作名 // 找到名为'none'(静止状态)以及'walking'(走路状态)的动作对象 idleAction = mixer.clipAction(gltf.animations.find(({ name }) => name === 'none')); walkAction = mixer.clipAction(gltf.animations.find(({ name }) => name === 'walking')); // 开始播放选定的动作序列 idleAction.play(); // 默认先播放静态姿势 walkAction.setEffectiveWeight(0).play(); // 动态切换两种姿态间的平滑度 function blendActions(weightForWalk) { idleAction.crossFadeTo(walkAction, weightForWalk ? 0.5 : 0.5, true); walkAction.setEffectiveWeight(weightForWalk); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值