js实现轨迹
js实现轨迹动画
使用requestAnimationFrame实现平滑动画效果,通过不断更新元素的位置属性形成轨迹运动。以下是基础实现代码:
let startTime = null;
const duration = 2000; // 动画持续时间(ms)
const element = document.getElementById('movingElement');
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const progress = (timestamp - startTime) / duration;
if (progress < 1) {
const x = progress * 500; // 水平移动距离
const y = Math.sin(progress * Math.PI * 2) * 50; // 垂直正弦波动
element.style.transform = `translate(${x}px, ${y}px)`;
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
贝塞尔曲线轨迹
使用三次贝塞尔曲线创建复杂轨迹路径,需要计算曲线上的点坐标:

function cubicBezier(t, p0, p1, p2, p3) {
const mt = 1 - t;
return {
x: mt*mt*mt*p0.x + 3*mt*mt*t*p1.x + 3*mt*t*t*p2.x + t*t*t*p3.x,
y: mt*mt*mt*p0.y + 3*mt*mt*t*p1.y + 3*mt*t*t*p2.y + t*t*t*p3.y
};
}
const controlPoints = [
{x:0, y:0}, // 起点
{x:100, y:50}, // 控制点1
{x:200, y:-50},// 控制点2
{x:300, y:0} // 终点
];
SVG路径轨迹
对于更复杂的轨迹,可以结合SVG路径和getPointAtLength方法:

const path = document.getElementById('motionPath');
const pathLength = path.getTotalLength();
let position = 0;
function followPath() {
position = (position + 1) % pathLength;
const point = path.getPointAtLength(position);
element.style.left = point.x + 'px';
element.style.top = point.y + 'px';
requestAnimationFrame(followPath);
}
物理轨迹模拟
实现抛物线等物理运动轨迹,需要考虑初速度和重力加速度:
let velocityX = 2;
let velocityY = -8;
const gravity = 0.2;
let posX = 0;
let posY = 0;
function physicsAnimation() {
velocityY += gravity;
posX += velocityX;
posY += velocityY;
if (posY > window.innerHeight) {
posY = window.innerHeight;
velocityY *= -0.8; // 弹性系数
}
element.style.left = posX + 'px';
element.style.top = posY + 'px';
requestAnimationFrame(physicsAnimation);
}
轨迹记录与回放
记录移动轨迹数据并实现回放功能:
const recordedPositions = [];
let isRecording = true;
function recordPosition(x, y) {
if (isRecording) {
recordedPositions.push({x, y});
}
}
function replayAnimation(index = 0) {
if (index < recordedPositions.length) {
const pos = recordedPositions[index];
element.style.left = pos.x + 'px';
element.style.top = pos.y + 'px';
setTimeout(() => replayAnimation(index + 1), 16);
}
}






