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

如何点击按钮替换Canvas中已添加的同位置SVG标记?

解决Canvas中替换SVG标记的问题

要实现点击按钮后将所有旧SVG标记替换为新SVG并保留原位置,你需要修改changesvg()函数的逻辑,直接更新现有标记的SVG资源,而不是重新创建新标记或手动绘制。以下是具体修改步骤和完整代码:

核心问题分析

原changesvg()函数存在几个关键错误:

  • 错误访问Marker的src属性(应该是marker.Sprite.src而非marker.src)
  • 手动清屏和绘制会被main()的定时重绘覆盖
  • 没有关联到已添加到Markers数组中的现有标记

修改后的实现方案

1. 修正changesvg()函数

遍历Markers数组,更新每个标记的SVG资源路径,并确保图片加载完成后触发重绘:

function changesvg() {
  // 遍历所有已添加的标记
  Markers.forEach(marker => {
    // 更新SVG资源路径
    marker.Sprite.src = "/images/2.svg";
    // 确保图片加载完成后重绘(避免SVG未加载导致不显示)
    marker.Sprite.onload = function() {
      draw();
    };
  });
}

2. 修复原代码中的其他小问题

  • 原draw()函数中循环条件的&lt;被转义,需要改回<
  • 原changesvg()中的heigth拼写错误,修改后无需手动清屏,可删除相关代码

完整代码

JavaScript部分

var canvas = document.getElementById('Canvas');
var context = canvas.getContext("2d");

// Map sprite
var mapSprite = new Image();
mapSprite.src = "http://www.retrogameguide.com/images/screenshots/snes-legend-of-zelda-link-to-the-past-8.jpg";

var Marker = function() {
  this.Sprite = new Image();
  this.Sprite.src = "/images/1.svg"
  this.Width = 12;
  this.Height = 20;
  this.XPos = 0;
  this.YPos = 0;
}

var Markers = new Array();

var mouseClicked = function(mouse) {
  // Get correct mouse coords
  var rect = canvas.getBoundingClientRect();
  var mouseXPos = (mouse.x - rect.left);
  var mouseYPos = (mouse.y - rect.top);

  console.log("Marker added");

  // Move the marker when placed to a better location
  var marker = new Marker();
  marker.XPos = mouseXPos - (marker.Width / 2);
  marker.YPos = mouseYPos - marker.Height;

  Markers.push(marker);
}

// Add mouse click event listener to canvas
canvas.addEventListener("mousedown", mouseClicked, false);

var firstLoad = function() {
  context.font = "15px Georgia";
  context.textAlign = "center";
}

firstLoad();

var main = function() {
  draw();
};

var draw = function() {
  // Clear Canvas
  context.fillStyle = "#000";
  context.fillRect(0, 0, canvas.width, canvas.height);

  // Draw map
  context.drawImage(mapSprite, 0, 0, 700, 700);

  // Draw markers
  for (var i = 0; i < Markers.length; i++) {
    var tempMarker = Markers[i];
    // Draw marker
    context.drawImage(tempMarker.Sprite, tempMarker.XPos, tempMarker.YPos, tempMarker.Width, tempMarker.Height);

    // Calculate position text
    var markerText = "Position (X:" + tempMarker.XPos + ", Y:" + tempMarker.YPos + ")";

    // Draw a simple box so you can see the position
    var textMeasurements = context.measureText(markerText);
    context.fillStyle = "#666";
    context.globalAlpha = 0.7;
    context.fillRect(tempMarker.XPos - (textMeasurements.width / 2), tempMarker.YPos - 15, textMeasurements.width, 20);
    context.globalAlpha = 1;

    // Draw position above
    context.fillStyle = "#000";
    context.fillText(markerText, tempMarker.XPos, tempMarker.YPos);
  }
};

function changesvg() {
  Markers.forEach(marker => {
    marker.Sprite.src = "/images/2.svg";
    marker.Sprite.onload = () => draw();
  });
}

setInterval(main, (1000 / 60));

HTML部分

<input id="clickMe" type="button" value="clickme" onclick="changesvg();" />

<canvas id="Canvas" width="700" height="700"></canvas>

说明

  • 点击按钮后,所有已添加的标记会自动替换为新SVG,且保持原位置不变
  • 添加onload事件确保SVG加载完成后再绘制,避免出现空白或旧资源残留
  • 利用原有的draw()函数和定时重绘机制,无需手动处理画布清空和绘制逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:53:23