js实现投球

实现投球动画的基本思路
使用JavaScript和CSS动画结合的方式模拟投球效果。核心是通过改变元素的位置、旋转和缩放属性,配合定时器或CSS过渡实现平滑动画。
创建基础HTML结构
<div class="ball" id="ball"></div>
<div class="target" id="target"></div>
添加基础CSS样式
.ball {
width: 50px;
height: 50px;
background-color: red;
border-radius: 50%;
position: absolute;
left: 50px;
top: 300px;
transition: transform 0.5s ease-out;
}
.target {
width: 100px;
height: 100px;
background-color: blue;
position: absolute;
right: 50px;
top: 350px;
}
JavaScript抛物线运动实现
function throwBall() {
const ball = document.getElementById('ball');
const target = document.getElementById('target');
const startPos = { x: 50, y: 300 };
const endPos = {
x: target.offsetLeft - 50,
y: target.offsetTop
};
const duration = 1000; // 动画持续时间(ms)
const startTime = performance.now();
function animate(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// 抛物线轨迹计算
const x = startPos.x + (endPos.x - startPos.x) * progress;
const y = startPos.y + (endPos.y - startPos.y) * progress
- 200 * Math.sin(progress * Math.PI); // 抛物线高度
ball.style.transform = `translate(${x}px, ${y}px)`;
if (progress < 1) {
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
}
// 调用投球函数
throwBall();
添加旋转效果增强真实感
function throwBall() {
// ...之前的代码...
function animate(currentTime) {
// ...之前的计算...
// 添加旋转效果
const rotation = progress * 720; // 旋转两圈
ball.style.transform = `translate(${x}px, ${y}px) rotate(${rotation}deg)`;
// ...剩余代码...
}
}
碰撞检测与回弹效果
function throwBall() {
// ...之前的代码...
function animate(currentTime) {
// ...之前的计算...
// 碰撞检测
if (progress >= 1) {
// 简单回弹效果
ball.style.transition = 'transform 0.3s ease-out';
setTimeout(() => {
ball.style.transform = `translate(${endPos.x}px, ${endPos.y + 20}px)`;
setTimeout(() => {
ball.style.transform = `translate(${endPos.x}px, ${endPos.y}px)`;
}, 300);
}, 0);
return;
}
// ...剩余代码...
}
}
使用CSS动画替代JavaScript动画
@keyframes throw {
0% {
transform: translate(50px, 300px) rotate(0deg);
}
50% {
transform: translate(calc(50% - 25px), 100px) rotate(360deg);
}
100% {
transform: translate(calc(100% - 100px), 350px) rotate(720deg);
}
}
.ball.throwing {
animation: throw 1s cubic-bezier(0.36, 0, 0.64, 1) forwards;
}
function throwBall() {
const ball = document.getElementById('ball');
ball.classList.add('throwing');
// 动画结束后移除类
ball.addEventListener('animationend', () => {
ball.classList.remove('throwing');
});
}
使用物理引擎实现更真实效果
// 使用matter.js物理引擎
const engine = Matter.Engine.create();
const world = engine.world;
const render = Matter.Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false
}
});
const ball = Matter.Bodies.circle(100, 300, 25);
const ground = Matter.Bodies.rectangle(400, 550, 800, 50, { isStatic: true });
Matter.World.add(world, [ball, ground]);
Matter.Engine.run(engine);
Matter.Render.run(render);
// 投球函数
function throwBall() {
Matter.Body.setVelocity(ball, { x: 10, y: -15 });
Matter.Body.setAngularVelocity(ball, 0.1);
}
响应式投球控制
let isDragging = false;
let startX, startY;
document.getElementById('ball').addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
startY = e.clientY;
});
document.addEventListener('mouseup', (e) => {
if (!isDragging) return;
const endX = e.clientX;
const endY = e.clientY;
const velocityX = (startX - endX) / 10;
const velocityY = (startY - endY) / 10;
// 使用物理引擎投球
Matter.Body.setVelocity(ball, { x: velocityX, y: velocityY });
Matter.Body.setAngularVelocity(ball, velocityX / 100);
isDragging = false;
});







