如何点击按钮替换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()函数中循环条件的<被转义,需要改回< - 原
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
相关产品推荐
相关产品推荐

