AI студия Владимира Ломтева
УСЛУГИПРОЕКТЫСТАТЬИБАЗА ЗНАНИЙМаркетплейсОбучениеПолезные сервисы

Оставьте заявку,
чтобы обсудить проект

Напишите ваш вопрос, не забудьте указать телефон. Мы перезвоним и все расскажем.

Контакты

Москва

Работаем по всей России
и миру (онлайн)

+7 (999) 760-24-41

Ежедневно с 9:00 до 21:00

v.lomtev@airassvet.ru

По вопросам сотрудничества

TelegramWhatsApp

Есть предложение?

Напишите нам в мессенджеры

© 2025 AI студия Владимира Ломтева

Политика конфиденциальностиСогласие на обработку ПДн|ИНН 623412173261
    Threejs Animation — Скилл для ИИ-агентов | AI Рассвет

    Threejs Animation

    Three.js animation keyframe animation, skeletal animation, morph targets, animation mixing. Use when animating objects, playing GLTF animations, creating procedural motion, or blending animations.

    Скиллы для операций#GitHub#cloudai-x/threejs-skills#skills.sh
    Скачивания
    3
    В избранном
    0
    Комментарии
    0
    Просмотры
    44

    Установить скилл

    Добавьте инструмент одной командой или скачайте проверенный архив версии.

    npx skills add cloudai-x/threejs-skills --skill threejs-animation
    Скачать ZIP
    Версия
    1.0.0+b1c623076c66
    Автор
    Владимир Ломтев
    Репозиторий
    cloudai-x/threejs-skills
    GitHub: cloudai-x/threejs-skills

    Как установить

    1. 1Скопируйте команду из блока установки.
    2. 2Запустите её в терминале из каталога проекта.

    Документация

    Three.js Animation

    Quick Start

    import * as THREE from "three";
    
    // Simple procedural animation
    const clock = new THREE.Clock();
    
    function animate() {
      const delta = clock.getDelta();
      const elapsed = clock.getElapsedTime();
    
      mesh.rotation.y += delta;
      mesh.position.y = Math.sin(elapsed) * 0.5;
    
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    }
    animate();
    

    Animation System Overview

    Three.js animation system has three main components:

    1. AnimationClip - Container for keyframe data
    2. AnimationMixer - Plays animations on a root object
    3. AnimationAction - Controls playback of a clip

    AnimationClip

    Stores keyframe animation data.

    // Create animation clip
    const times = [0, 1, 2]; // Keyframe times (seconds)
    const values = [0, 1, 0]; // Values at each keyframe
    
    const track = new THREE.NumberKeyframeTrack(
      ".position[y]", // Property path
      times,
      values,
    );
    
    const clip = new THREE.AnimationClip("bounce", 2, [track]);
    

    KeyframeTrack Types

    // Number track (single value)
    new THREE.NumberKeyframeTrack(".opacity", times, [1, 0]);
    new THREE.NumberKeyframeTrack(".material.opacity", times, [1, 0]);
    
    // Vector track (position, scale)
    new THREE.VectorKeyframeTrack(".position", times, [
      0,
      0,
      0, // t=0
      1,
      2,
      0, // t=1
      0,
      0,
      0, // t=2
    ]);
    
    // Quaternion track (rotation)
    const q1 = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, 0, 0));
    const q2 = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, Math.PI, 0));
    new THREE.QuaternionKeyframeTrack(
      ".quaternion",
      [0, 1],
      [q1.x, q1.y, q1.z, q1.w, q2.x, q2.y, q2.z, q2.w],
    );
    
    // Color track
    new THREE.ColorKeyframeTrack(".material.color", times, [
      1,
      0,
      0, // red
      0,
      1,
      0, // green
      0,
      0,
      1, // blue
    ]);
    
    // Boolean track
    new THREE.BooleanKeyframeTrack(".visible", [0, 0.5, 1], [true, false, true]);
    
    // String track (for morph targets)
    new THREE.StringKeyframeTrack(
      ".morphTargetInfluences[smile]",
      [0, 1],
      ["0", "1"],
    );
    

    Interpolation Modes

    const track = new THREE.VectorKeyframeTrack(".position", times, values);
    
    // Interpolation
    track.setInterpolation(THREE.InterpolateLinear); // Default
    track.setInterpolation(THREE.InterpolateSmooth); // Cubic spline
    track.setInterpolation(THREE.InterpolateDiscrete); // Step function
    

    AnimationMixer

    Plays animations on an object and its descendants.

    const mixer = new THREE.AnimationMixer(model);
    
    // Create action from clip
    const action = mixer.clipAction(clip);
    action.play();
    
    // Update in animation loop
    function animate() {
      const delta = clock.getDelta();
      mixer.update(delta); // Required!
    
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    }
    

    Mixer Events

    mixer.addEventListener("finished", (e) => {
      console.log("Animation finished:", e.action.getClip().name);
    });
    
    mixer.addEventListener("loop", (e) => {
      console.log("Animation looped:", e.action.getClip().name);
    });
    

    AnimationAction

    Controls playback of an animation clip.

    const action = mixer.clipAction(clip);
    
    // Playback control
    action.play();
    action.stop();
    action.reset();
    action.halt(fadeOutDuration);
    
    // Playback state
    action.isRunning();
    action.isScheduled();
    
    // Time control
    action.time = 0.5; // Current time
    action.timeScale = 1; // Playback speed (negative = reverse)
    action.paused = false;
    
    // Weight (for blending)
    action.weight = 1; // 0-1, contribution to final pose
    action.setEffectiveWeight(1);
    
    // Loop modes
    action.loop = THREE.LoopRepeat; // Default: loop forever
    action.loop = THREE.LoopOnce; // Play once and stop
    action.loop = THREE.LoopPingPong; // Alternate forward/backward
    action.repetitions = 3; // Number of loops (Infinity default)
    
    // Clamping
    action.clampWhenFinished = true; // Hold last frame when done
    
    // Blending
    action.blendMode = THREE.NormalAnimationBlendMode;
    action.blendMode = THREE.AdditiveAnimationBlendMode;
    

    Fade In/Out

    // Fade in
    action.reset().fadeIn(0.5).play();
    
    // Fade out
    action.fadeOut(0.5);
    
    // Crossfade between animations
    const action1 = mixer.clipAction(clip1);
    const action2 = mixer.clipAction(clip2);
    
    action1.play();
    
    // Later, crossfade to action2
    action1.crossFadeTo(action2, 0.5, true);
    action2.play();
    

    Loading GLTF Animations

    Most common source of skeletal animations.

    import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
    
    const loader = new GLTFLoader();
    loader.load("model.glb", (gltf) => {
      const model = gltf.scene;
      scene.add(model);
    
      // Create mixer
      const mixer = new THREE.AnimationMixer(model);
    
      // Get all clips
      const clips = gltf.animations;
      console.log(
        "Available animations:",
        clips.map((c) => c.name),
      );
    
      // Play first animation
      if (clips.length > 0) {
        const action = mixer.clipAction(clips[0]);
        action.play();
      }
    
      // Play specific animation by name
      const walkClip = THREE.AnimationClip.findByName(clips, "Walk");
      if (walkClip) {
        mixer.clipAction(walkClip).play();
      }
    
      // Store mixer for update loop
      window.mixer = mixer;
    });
    
    // Animation loop
    function animate() {
      const delta = clock.getDelta();
      if (window.mixer) window.mixer.update(delta);
    
      requestAnimationFrame(animate);
      renderer.render(scene, camera);
    }
    

    Skeletal Animation

    Skeleton and Bones

    // Access skeleton from skinned mesh
    const skinnedMesh = model.getObjectByProperty("type", "SkinnedMesh");
    const skeleton = skinnedMesh.skeleton;
    
    // Access bones
    skeleton.bones.forEach((bone) => {
      console.log(bone.name, bone.position, bone.rotation);
    });
    
    // Find specific bone by name
    const headBone = skeleton.bones.find((b) => b.name === "Head");
    if (headBone) headBone.rotation.y = Math.PI / 4; // Turn head
    
    // Skeleton helper
    const helper = new THREE.SkeletonHelper(model);
    scene.add(helper);
    

    Programmatic Bone Animation

    function animate() {
      const time = clock.getElapsedTime();
    
      // Animate bone
      const headBone = skeleton.bones.find((b) => b.name === "Head");
      if (headBone) {
        headBone.rotation.y = Math.sin(time) * 0.3;
      }
    
      // Update mixer if also playing clips
      mixer.update(clock.getDelta());
    }
    

    Bone Attachments

    // Attach object to bone
    const weapon = new THREE.Mesh(weaponGeometry, weaponMaterial);
    const handBone = skeleton.bones.find((b) => b.name === "RightHand");
    if (handBone) handBone.add(weapon);
    
    // Offset attachment
    weapon.position.set(0, 0, 0.5);
    weapon.rotation.set(0, Math.PI / 2, 0);
    

    Morph Targets

    Blend between different mesh shapes.

    // Morph targets are stored in geometry
    const geometry = mesh.geometry;
    console.log("Morph attributes:", Object.keys(geometry.morphAttributes));
    
    // Access morph target influences
    mesh.morphTargetInfluences; // Array of weights
    mesh.morphTargetDictionary; // Name -> index mapping
    
    // Set morph target by index
    mesh.morphTargetInfluences[0] = 0.5;
    
    // Set by name
    const smileIndex = mesh.morphTargetDictionary["smile"];
    mesh.morphTargetInfluences[smileIndex] = 1;
    

    Animating Morph Targets

    // Procedural
    function animate() {
      const t = clock.getElapsedTime();
      mesh.morphTargetInfluences[0] = (Math.sin(t) + 1) / 2;
    }
    
    // With keyframe animation
    const track = new THREE.NumberKeyframeTrack(
      ".morphTargetInfluences[smile]",
      [0, 0.5, 1],
      [0, 1, 0],
    );
    const clip = new THREE.AnimationClip("smile", 1, [track]);
    mixer.clipAction(clip).play();
    

    Animation Blending

    Mix multiple animations together.

    // Setup actions
    const idleAction = mixer.clipAction(idleClip);
    const walkAction = mixer.clipAction(walkClip);
    const runAction = mixer.clipAction(runClip);
    
    // Play all with different weights
    idleAction.play();
    walkAction.play();
    runAction.play();
    
    // Set initial weights
    idleAction.setEffectiveWeight(1);
    walkAction.setEffectiveWeight(0);
    runAction.setEffectiveWeight(0);
    
    // Blend based on speed
    function updateAnimations(speed) {
      if (speed < 0.1) {
        idleAction.setEffectiveWeight(1);
        walkAction.setEffectiveWeight(0);
        runAction.setEffectiveWeight(0);
      } else if (speed < 5) {
        const t = speed / 5;
        idleAction.setEffectiveWeight(1 - t);
        walkAction.setEffectiveWeight(t);
        runAction.setEffectiveWeight(0);
      } else {
        const t = Math.min((speed - 5) / 5, 1);
        idleAction.setEffectiveWeight(0);
        walkAction.setEffectiveWeight(1 - t);
        runAction.setEffectiveWeight(t);
      }
    }
    

    Additive Blending

    // Base pose
    const baseAction = mixer.clipAction(baseClip);
    baseAction.play();
    
    // Additive layer (e.g., breathing)
    const additiveAction = mixer.clipAction(additiveClip);
    additiveAction.blendMode = THREE.AdditiveAnimationBlendMode;
    additiveAction.play();
    
    // Convert clip to additive
    THREE.AnimationUtils.makeClipAdditive(additiveClip);
    

    Animation Utilities

    import * as THREE from "three";
    
    // Find clip by name
    const clip = THREE.AnimationClip.findByName(clips, "Walk");
    
    // Create subclip
    const subclip = THREE.AnimationUtils.subclip(clip, "subclip", 0, 30, 30);
    
    // Convert to additive
    THREE.AnimationUtils.makeClipAdditive(clip);
    THREE.AnimationUtils.makeClipAdditive(clip, 0, referenceClip);
    
    // Clone clip
    const clone = clip.clone();
    
    // Get clip duration
    clip.duration;
    
    // Optimize clip (remove redundant keyframes)
    clip.optimize();
    
    // Reset clip to first frame
    clip.resetDuration();
    

    Procedural Animation Patterns

    Smooth Damping

    // Smooth follow/lerp
    const target = new THREE.Vector3();
    const current = new THREE.Vector3();
    const velocity = new THREE.Vector3();
    
    function smoothDamp(current, target, velocity, smoothTime, deltaTime) {
      const omega = 2 / smoothTime;
      const x = omega * deltaTime;
      const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x);
      const change = current.clone().sub(target);
      const temp = velocity
        .clone()
        .add(change.clone().multiplyScalar(omega))
        .multiplyScalar(deltaTime);
      velocity.sub(temp.clone().multiplyScalar(omega)).multiplyScalar(exp);
      return target.clone().add(change.add(temp).multiplyScalar(exp));
    }
    
    function animate() {
      current.copy(smoothDamp(current, target, velocity, 0.3, delta));
      mesh.position.copy(current);
    }
    

    Spring Physics

    class Spring {
      constructor(stiffness = 100, damping = 10) {
        this.stiffness = stiffness;
        this.damping = damping;
        this.position = 0;
        this.velocity = 0;
        this.target = 0;
      }
    
      update(dt) {
        const force = -this.stiffness * (this.position - this.target);
        const dampingForce = -this.damping * this.velocity;
        this.velocity += (force + dampingForce) * dt;
        this.position += this.velocity * dt;
        return this.position;
      }
    }
    
    const spring = new Spring(100, 10);
    spring.target = 1;
    
    function animate() {
      mesh.position.y = spring.update(delta);
    }
    

    Oscillation

    function animate() {
      const t = clock.getElapsedTime();
    
      // Sine wave
      mesh.position.y = Math.sin(t * 2) * 0.5;
    
      // Bouncing
      mesh.position.y = Math.abs(Math.sin(t * 3)) * 2;
    
      // Circular motion
      mesh.position.x = Math.cos(t) * 2;
      mesh.position.z = Math.sin(t) * 2;
    
      // Figure 8
      mesh.position.x = Math.sin(t) * 2;
      mesh.position.z = Math.sin(t * 2) * 1;
    }
    

    Performance Tips

    1. Share clips: Same AnimationClip can be used on multiple mixers
    2. Optimize clips: Call clip.optimize() to remove redundant keyframes
    3. Disable when off-screen: Stop mixer updates for invisible objects
    4. Use LOD for animations: Simpler rigs for distant characters
    5. Limit active mixers: Each mixer.update() has a cost
    // Pause animation when not visible
    mesh.onBeforeRender = () => {
      action.paused = false;
    };
    
    mesh.onAfterRender = () => {
      // Check if will be visible next frame
      if (!isInFrustum(mesh)) {
        action.paused = true;
      }
    };
    
    // Cache clips
    const clipCache = new Map();
    function getClip(name) {
      if (!clipCache.has(name)) {
        clipCache.set(name, loadClip(name));
      }
      return clipCache.get(name);
    }
    

    See Also

    • threejs-loaders - Loading animated GLTF models
    • threejs-fundamentals - Clock and animation loop
    • threejs-shaders - Vertex animation in shaders

    Требования и возможности

    Источник пакета
    https://github.com/cloudai-x/threejs-skills/tree/b1c623076c661fc9b03dac19292e825a5d106823/skills/threejs-animation

    Файлы версии

    ПутьРазмерSHA256
    SKILL.md12557b24dc96c7a854ab9...

    Частые вопросы

    Как установить Threejs Animation?
    Используйте команду npx skills add cloudai-x/threejs-skills --skill threejs-animation или скачайте ZIP-архив.
    Можно ли скачать Threejs Animation бесплатно?
    Да, опубликованную версию можно скачать из маркетплейса бесплатно.

    Похожие инструменты

    Смотреть все
    Ozon Seller и Performance APIСправочник Ozon Seller API и Performance API с локальными OpenAPI-спецификациями.Grill MeA relentless interview to sharpen a plan or design.Stop SlopRemove AI writing patterns from prose. Use when drafting, editing, or reviewing text to eliminate predictable AI tells.Git CommitExecute git commit with conventional commit message analysis, intelligent staging, and message generation. Use when user asks to commit changes, create a git commit, or mentions "/commit". Supports: (1) Auto-detecting type and scope from changes, (2) Generating conventional commit messages from diff, (3) Interactive commit with optional type/scope/description overrides, (4) Intelligent file staging for logical grouping
    Комментарии

    Войдите, чтобы оставить комментарий.

    Комментариев пока нет.

    Установить скилл

    Добавьте инструмент одной командой или скачайте проверенный архив версии.

    npx skills add cloudai-x/threejs-skills --skill threejs-animation
    Скачать ZIP
    Версия
    1.0.0+b1c623076c66
    Автор
    Владимир Ломтев
    Репозиторий
    cloudai-x/threejs-skills
    GitHub: cloudai-x/threejs-skills