You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Canvas上绘制红圈移动轨迹且避免蓝圈移动时留下痕迹

Canvas 单元素轨迹保留实现方案

需求说明

已经实现的基础效果:蓝色小圆围绕红色大圆旋转,按住鼠标时红色大圆会沿蓝圈当前指向的方向移动。需要实现的效果是:仅保留红圈的移动轨迹,蓝圈旋转/移动时不留任何痕迹。

核心实现思路

不需要删除clearRect清屏逻辑,换轨迹存储的思路即可实现:

  1. 新增一个数组专门存储红圈移动过程中的所有历史坐标点
  2. 每次动画帧执行时先清屏,再按顺序绘制所有历史轨迹点、当前红圈、当前蓝圈
  3. 只有按住鼠标红圈移动时,才往轨迹数组中新增坐标点

这样清屏只会清除上一帧的临时内容,历史轨迹会通过数组重绘永久保留,蓝圈每次只绘制最新位置,不会留下痕迹。

修改后完整代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Canvas basics</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <canvas id="canvas1"></canvas>
    
    <script src="script.js"></script>
</body>
</html>

CSS

#canvas1{
    position: absolute;
    top:0;
    left: 0;
    width: 100%;
    height: 100%;
}

JavaScript

const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let positionX = 100;
let positionY = 100;
let X = 50;
let Y = 50;
let angle = 0;
let mouseButtonDown = false;
// 新增:存储红圈轨迹点的数组
const trailPoints = [];

document.addEventListener('mousedown', () => mouseButtonDown = true);
document.addEventListener('mouseup', () => mouseButtonDown = false);

// 新增:绘制红圈轨迹的方法
function drawTrail() {
    ctx.fillStyle = 'rgba(255,0,0,0.3)'; // 半透明红色轨迹,也可以调整为不透明
    trailPoints.forEach(point => {
        ctx.beginPath();
        ctx.arc(point.x, point.y, 20, 0, Math.PI*2); // 轨迹点大小可自定义调整
        ctx.closePath();
        ctx.fill();
    });
}

function circle(){
    ctx.fillStyle = 'red';
    ctx.beginPath();
    ctx.arc(X, Y, 20, 0, Math.PI*2);
    ctx.closePath();
    ctx.fill();
}
function direction(){
    ctx.fillStyle = 'blue';
    ctx.beginPath();
    ctx.arc(positionX + X, positionY + Y, 10, 0, Math.PI*2);
    ctx.closePath();
    positionX = 35 * Math.sin(angle);
    positionY = 35 * Math.cos(angle);
    ctx.fill();   
}
function animate(){
    if (mouseButtonDown) {
        X += positionX / 10;
        Y += positionY / 10;
        // 新增:按住鼠标移动时,记录当前红圈坐标到轨迹数组
        trailPoints.push({x: X, y: Y});
    } else {
        angle += 0.1;
    }
    ctx.clearRect(0,0, canvas.width, canvas.height);
    // 绘制顺序:先画轨迹,再画当前红圈,最后画蓝圈,保证层级正确
    drawTrail();
    circle();
    direction();
    requestAnimationFrame(animate);   
}
animate();

如果觉得离散点组成的轨迹有锯齿,也可以把轨迹绘制逻辑改成用lineTo绘制连续线段,效果会更顺滑。

内容的提问来源于stack exchange,提问作者mahesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 10:51:05