原生JS实现抛物线与动态模糊:从数学建模到视觉优化
2025.09.18 17:08浏览量:0简介:本文通过原生JavaScript实现抛物线轨迹动画与动态模糊效果,结合数学公式、Canvas渲染和CSS滤镜技术,提供可复用的代码方案与性能优化建议。
原生JS实现抛物线动画以及动态模糊效果
在Web交互设计中,抛物线动画与动态模糊效果常用于模拟物体抛掷、弹窗飞入等场景。本文将通过原生JavaScript实现这两种视觉效果,结合数学公式、Canvas渲染和CSS滤镜技术,提供完整的代码实现与优化方案。
一、抛物线动画的数学基础与实现
1.1 抛物线运动模型
抛物线运动由水平匀速运动和垂直匀加速运动合成,其轨迹方程为:
[
\begin{cases}
x = v_0 \cdot t \cdot \cos\theta \
y = v_0 \cdot t \cdot \sin\theta - \frac{1}{2} g t^2
\end{cases}
]
其中:
- ( v_0 ) 为初始速度
- ( \theta ) 为抛射角度
- ( g ) 为重力加速度(约9.8m/s²,需转换为像素单位)
- ( t ) 为时间参数
1.2 原生JS实现步骤
步骤1:初始化参数
const config = {
startX: 50,
startY: 300,
targetX: 400,
targetY: 100,
duration: 1000, // 动画时长(ms)
angle: 45, // 抛射角度(度)
gravity: 0.2 // 重力系数(像素/帧²)
};
步骤2:计算初始速度
通过终点坐标反推初始速度:
function calculateInitialVelocity(start, target, angle, gravity) {
const dx = target.x - start.x;
const dy = target.y - start.y;
const rad = angle * Math.PI / 180;
// 解二次方程求时间t
const a = -gravity / 2;
const b = Math.tan(rad) * dx;
const c = dy;
const discriminant = b * b - 4 * a * c;
if (discriminant < 0) return null; // 无解
const t = (-b + Math.sqrt(discriminant)) / (2 * a);
const v0x = dx / (t * Math.cos(rad));
const v0y = (dy + 0.5 * gravity * t * t) / (t * Math.sin(rad));
return { v0x, v0y, t };
}
步骤3:动画帧处理
使用requestAnimationFrame
实现平滑动画:
function animateParabola(element, config) {
const { startX, startY, duration } = config;
const params = calculateInitialVelocity(
{ x: startX, y: startY },
{ x: config.targetX, y: config.targetY },
config.angle,
config.gravity
);
if (!params) return;
let startTime = null;
function animate(currentTime) {
if (!startTime) startTime = currentTime;
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// 线性插值计算当前位置
const t = progress * params.t;
const x = startX + params.v0x * Math.cos(config.angle * Math.PI / 180) * t;
const y = startY + params.v0y * Math.sin(config.angle * Math.PI / 180) * t
- 0.5 * config.gravity * t * t;
element.style.transform = `translate(${x}px, ${y}px)`;
if (progress < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
二、动态模糊效果的实现原理
2.1 模糊技术对比
技术方案 | 优点 | 缺点 |
---|---|---|
CSS filter |
实现简单,性能较好 | 静态模糊,无法动态调整 |
Canvas绘制 | 可控性强,支持动态模糊 | 需要手动计算像素模糊 |
WebGL | 高性能,支持复杂效果 | 学习曲线陡峭 |
2.2 基于CSS滤镜的动态模糊
通过动态调整blur()
值实现:
function applyDynamicBlur(element, duration) {
let startTime = null;
const maxBlur = 10; // 最大模糊半径
function blur(currentTime) {
if (!startTime) startTime = currentTime;
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// 模糊半径随时间变化(先增大后减小)
const blurRadius = maxBlur * Math.sin(progress * Math.PI);
element.style.filter = `blur(${blurRadius}px)`;
if (progress < 1) {
requestAnimationFrame(blur);
}
}
requestAnimationFrame(blur);
}
2.3 基于Canvas的高级模糊(可选)
对于需要更高质量的场景,可使用高斯模糊算法:
function applyCanvasBlur(canvas, context, radius) {
// 简化版高斯模糊实现
const pixels = context.getImageData(0, 0, canvas.width, canvas.height);
const data = pixels.data;
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// 简单平均模糊(实际需加权计算)
const avg = (r + g + b) / 3;
data[i] = data[i + 1] = data[i + 2] = avg;
}
context.putImageData(pixels, 0, 0);
}
三、性能优化与最佳实践
3.1 动画性能优化
使用
transform
替代top/left
CSStransform
属性触发GPU加速,避免重排。节流
requestAnimationFrame
在复杂场景中,可通过throttle
限制帧率:function throttle(fn, delay) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= delay) {
fn.apply(this, args);
lastCall = now;
}
};
}
分层渲染
将静态背景与动态元素分离,减少重绘区域。
3.2 模糊效果优化
限制模糊范围
避免全局模糊,仅对运动元素应用滤镜。使用
will-change
属性
提前告知浏览器元素变化:.blur-element {
will-change: filter;
}
降级方案
在低端设备上禁用模糊效果:function isLowPerformanceDevice() {
return /Mobile|Android|iPhone/i.test(navigator.userAgent)
|| window.innerWidth < 768;
}
四、完整示例与扩展应用
4.1 抛物线+模糊组合效果
const ball = document.getElementById('ball');
animateParabola(ball, {
startX: 50,
startY: 300,
targetX: 400,
targetY: 100,
duration: 1500,
angle: 60,
gravity: 0.25
});
applyDynamicBlur(ball, 1500);
4.2 扩展应用场景
购物车飞入效果
将商品图标沿抛物线飞入购物车。游戏粒子系统
模拟爆炸碎片的抛物线运动与模糊拖尾。UI过渡动画
弹窗从屏幕边缘飞入并带模糊背景。
五、总结与关键点
数学建模是核心
抛物线动画需准确计算初始速度与时间参数。性能优先
优先使用CSStransform
和filter
,避免强制同步布局。渐进增强
根据设备性能动态调整效果复杂度。
通过本文的实现方案,开发者可快速集成抛物线动画与动态模糊效果,同时掌握底层原理与优化技巧。完整代码示例与数学推导过程已提供,可直接应用于项目开发。
发表评论
登录后可评论,请前往 登录 或 注册