SVG动画案例库

浏览精选的SVG动画案例

移开即停止播放
'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 600; const CENTER_X = VIEW_WIDTH / 2; const CENTER_Y = VIEW_HEIGHT / 2; const RAY_LENGTH = 350; // Refractive Indices const N1 = 1.00; // Air const N2 = 1.33; // Water export const LightRefractionView = () => { const [incidentAngleDeg, setIncidentAngleDeg] = useState(45); const timeRef = useRef(0); const requestRef = useRef<number>(); // Animation Loop con

Light refraction at the water surface

移开即停止播放
'use client'; import React, { useState, useEffect, useRef } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 400; const WAVE_SPEED = 2; // 波纹扩散速度 const EMISSION_RATE = 15; // 发射频率 (每多少帧发射一次) const MAX_SOURCE_SPEED = 1.2; // 源点移动最大速度 (需小于 WAVE_SPEED 以避免音爆/混乱) export const DopplerEffectView = () => { const [waves, setWaves] = useState([]); const [sourceX, setSourceX] = useState(200); const [velocity, setVelocity] = useState(0); const [phase, setPhase] = useState('static'); // s

Doppler effect of a moving wave source

移开即停止播放
'use client'; import React, { useState, useEffect, useRef } from 'react'; const VIEW_WIDTH = 1000; const VIEW_HEIGHT = 600; const ARRAY_SIZE = 15; // Helper to generate sorted unique random numbers const generateSortedArray = (size) => { const set = new Set(); while (set.size < size) { set.add(Math.floor(Math.random() * 90) + 10); } return Array.from(set).sort((a, b) => a - b); // Numeric sort }; export const BinarySearchView = () => { // State const [array, setArray] = useSt

Binary search in computing

移开即停止播放
'use client'; import React, { useState, useEffect, useRef } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 600; const GROUND_Y = 500; const APPLE_START_X = 480; const APPLE_START_Y = 220; const GRAVITY = 0.6; const BOUNCE_FACTOR = 0.5; export const AppleFallAnimation = () => { // 动画状态 const [appleY, setAppleY] = useState(APPLE_START_Y); const [rotation, setRotation] = useState(0); const [status, setStatus] = useState<'hanging' | 'falling' | 'resting'>('hanging'); // 物理

An apple falling from a tree

移开即停止播放
'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; const VIEW_WIDTH = 1000; const VIEW_HEIGHT = 600; export const MoonOrbitView = () => { // 动画状态:角度 (0 ~ 2PI) const [angle, setAngle] = useState(0); const requestRef = useRef<number>(); // 轨道参数 const centerX = VIEW_WIDTH / 2; const centerY = VIEW_HEIGHT / 2; const orbitRadiusX = 350; // 椭圆长轴 const orbitRadiusY = 120; // 椭圆短轴 (模拟3D视角倾斜) const earthRadius = 80; const moonRadius = 20; const

Moon orbiting Earth

移开即停止播放
'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 450; const ANIMATION_DURATION = 8000; // 8 seconds per loop export default function NewsIntroAnimation() { const [time, setTime] = useState(0); const requestRef = useRef(null); const startTimeRef = useRef(null); // Animation Loop const animate = (timestamp) => { if (!startTimeRef.current) startTimeRef.current = timestamp; const elapsed = timestamp -

News-style intro: ANIMORA spins then becomes Animation Studio

移开即停止播放
'use client'; import React, { useState, useEffect, useRef } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 400; export default function LittleBoyDriving() { const [frame, setFrame] = useState(0); // 动画循环 useEffect(() => { let animationFrameId; const loop = () => { setFrame((f) => f + 1); animationFrameId = requestAnimationFrame(loop); }; loop(); return () => cancelAnimationFrame(animationFrameId); }, []); // 动画参数计算 const roadSpeed = 8;

Little boy driving a car

移开即停止播放
'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; const VIEW_WIDTH = 1000; const VIEW_HEIGHT = 600; const CENTER_Y = VIEW_HEIGHT / 2; const CIRCLE_X = 150; const WAVE_START_X = 300; const RADIUS = 80; export const SineWaveView = () => { // 动画相位状态 const [phase, setPhase] = useState(0); const requestRef = useRef<number>(); const previousTimeRef = useRef<number>(); // 动画循环 const animate = (time: number) => { if (previousTimeRef.current !== undefi

Sine wave extending forward on axes

广告

Ads
移开即停止播放
'use client'; import React, { useState, useEffect, useRef } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 600; const BALL_RADIUS = 30; const STRING_LENGTH = 250; const PIVOT_Y = 100; const CENTER_X = VIEW_WIDTH / 2; const MAX_ANGLE = Math.PI / 4; // 45 degrees swing export const NewtonsCradle = () => { const [time, setTime] = useState(Math.PI); // Start with left ball ready to swing down const requestRef = useRef<number>(); // Physics loop const animate = () => { //

Newton's cradle with 5 metal balls

移开即停止播放
'use client'; import React, { useState, useEffect, useRef, useMemo } from 'react'; // 视图配置 const VIEW_WIDTH = 800; const VIEW_HEIGHT = 500; const CENTER_X = VIEW_WIDTH / 2; const CENTER_Y = VIEW_HEIGHT / 2; // 轨道参数 const A = 300; // 半长轴 const E = 0.6; // 离心率 (0.6 使得速度差异明显) const B = A * Math.sqrt(1 - E * E); // 半短轴 const C = A * E; // 焦距 (中心到焦点的距离) // 动画参数 const ANIMATION_SPEED = 0.015; // 平均角速度因子 const SWEEP_INTERVAL = 1.5; // 扫过区域的时间间隔 (弧度制下的平均近点角跨度) export const KeplerSecondLawView = ()

Planetary elliptical orbit showing equal swept areas (Kepler's second law)

移开即停止播放
'use client'; import React, { useMemo, useEffect, useState } from 'react'; const VIEW_WIDTH = 800; const VIEW_HEIGHT = 600; const CENTER_X = VIEW_WIDTH / 2; const CENTER_Y = VIEW_HEIGHT / 2; export const BlackHoleAnimation = () => { // 生成背景星空 const stars = useMemo(() => { return Array.from({ length: 150 }).map((_, i) => ({ id: i, x: Math.random() * VIEW_WIDTH, y: Math.random() * VIEW_HEIGHT, r: Math.random() * 1.5 + 0.5, opacity: Math.random() * 0.7 + 0.3

Black hole with accretion disk