css 或者 js 怎么实现小汽车走s型运行轨迹,svg或者canvas怎么实现
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
const car = { x: 100, y: 100, r: 10, color: "red" };
const path = { p0: { x: 100, y: 100 }, p1: { x: 100, y: 300 }, p2: { x: 300, y: 100 }, p3: { x: 300, y: 300 } };
let t = 0;
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(path.p0.x, path.p0.y);
ctx.bezierCurveTo(path.p1.x, path.p1.y, path.p2.x, path.p2.y, path.p3.x, path.p3.y);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.arc(car.x, car.y, car.r, 0, 2 * Math.PI);
ctx.fillStyle = car.color;
ctx.fill();
ctx.closePath();
t += 0.005;
if (t > 1) {
t = 0;
}
car.x = (1 - t) ** 3 * path.p0.x + 3 * t * (1 - t) ** 2 * path.p1.x + 3 * t ** 2 * (1 - t) * path.p2.x + t ** 3 * path.p3.x;
car.y = (1 - t) ** 3 * path.p0.y + 3 * t * (1 - t) ** 2 * path.p1.y + 3 * t ** 2 * (1 - t) * path.p2.y + t ** 3 * path.p3.y;
requestAnimationFrame(draw);
}
draw();
</script>
引用自chatGPT:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Canvas Car Animation</title>
</head>
<body>
<canvas id="canvas" width="600" height="200"></canvas>
<script>
// 获取画布和画布上下文
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
// 设置画布尺寸和背景颜色
canvas.width = 600;
canvas.height = 200;
ctx.fillStyle = '#EEE';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 创建一张图片并设置宽高和来源
var carImg = new Image();
carImg.src = 'https://img1.baidu.com/it/u=1849563527,2838003780&fm=253&fmt=auto&app=120&f=JPEG?w=750&h=500';
carImg.width = 50;
carImg.height = 50;
// 图片加载完成后执行的函数
carImg.onload = function () {
var startTime = 0;
// 绘制小车的函数
function drawCar(currentTime) {
// 如果startTime未设置,则设置为当前时间
if (!startTime) startTime = currentTime;
// 计算已过去的时间
var elapsed = currentTime - startTime;
// 计算小车的位置和角度
// 其中,t表示时间的进度,x和y是小汽车的坐标,angle是小汽车的旋转角度,0.8是横向缩放系数,-15是小汽车图像的一半大小。
// 希望以上方法可以帮助你实现小汽车沿着S型轨迹运行的效果。
var t = elapsed / 4000;
var x = 100 + t * 400;
var y = 100 + Math.sin(t * Math.PI) * 50;
var angle = Math.atan2(Math.sin(t * Math.PI), Math.cos(t * Math.PI) * 0.8) + Math.PI / 2;
// 清空画布并绘制背景和贝塞尔曲线
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#EEE';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.quadraticCurveTo(200, 50, 300, 100);
ctx.quadraticCurveTo(400, 150, 500, 100);
ctx.strokeStyle = 'black';
ctx.stroke();
// 保存当前画布状态,即位置和角度
ctx.save();
ctx.translate(x, y);
ctx.rotate(angle);
// 绘制小车
ctx.drawImage(carImg, -15, -15, 30, 30);
// 恢复之前保存的画布状态
ctx.restore();
// 循环调用自身函数,实现小车的动画效果
requestAnimationFrame(drawCar);
}
// 第一次调用绘制小车的函数
requestAnimationFrame(drawCar);
};
</script>
</body>
</html>