簡體   English   中英

如何刪除畫布html中的點?

[英]how remove dots in canvas html?

首先,我嘗試了與此主題相關的所有問題和答案。 此外,我嘗試了相關問題並嘗試解決它,但沒有成功。 所以請仔細閱讀我的問題。

問題:在沒有清晰畫布的情況下僅刪除點。

我只想刪除 Red Dotes 而不是 Full Canvas Remove 或 Reload 。

 const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); context.beginPath(); context.arc(100, 100, 3, 0, Math.PI * 2, true); // Outer circle context.lineWidth = 0; context.fillStyle = "red"; context.fill(); context.beginPath(); context.arc(36, 100, 3, 0, Math.PI * 2, true); // Outer circle context.lineWidth = 0; context.fillStyle = "Orange"; context.fill(); context.beginPath(); context.arc(123, 100, 3, 0, Math.PI * 2, true); // Outer circle context.lineWidth = 0; context.fillStyle = "Green"; context.fill(); function removeRedDot(){ // remove code alert('Remove Red Dot'); }
 #canvas{ border:1px solid black; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <h4>Approach the circle with the mouse</h4> <button onclick="removeRedDot()"> Red Remove Dot</button> <canvas id="canvas" width=300 height=200></canvas>

由於您在 ( x , y ) 位置 ( 100px , 100px ) 處6px了直徑為6px的紅色圓圈,因此它占用的區域為:

x      : 100 - (6 / 2)
y      : 100 - (6 / 2)
width  : 6
height : 6

您可以使用clearRect方法清除畫布的clearRect

context.clearRect(97, 97, 6, 6);

如果您的畫布有背景,您將需要清除整個畫布並重繪除紅點之外的所有內容,或者您​​可以調用fillRect ...假設context.fillStyle設置為背景顏色。

context.fillRect(97, 97, 6, 6);

在繪制之前,您必須以某種方式知道紅點的繪制位置(以及它的大小)。

編輯:在下面的演示之后查看我的 OOP 示例!


演示

 const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); context.beginPath(); context.arc(100, 100, 3, 0, Math.PI * 2, true); // Outer circle context.lineWidth = 0; context.fillStyle = "red"; context.fill(); context.beginPath(); context.arc(36, 100, 3, 0, Math.PI * 2, true); // Outer circle context.lineWidth = 0; context.fillStyle = "Orange"; context.fill(); context.beginPath(); context.arc(123, 100, 3, 0, Math.PI * 2, true); // Outer circle context.lineWidth = 0; context.fillStyle = "Green"; context.fill(); function removeRedDot() { context.clearRect(97, 97, 6, 6); alert('Removed Red Dot'); }
 #canvas { border: 1px solid black; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <h4>Approach the circle with the mouse</h4> <button onclick="removeRedDot()"> Red Remove Dot</button> <canvas id="canvas" width=300 height=200></canvas>


OOP 來救援!

更好的方法是了解畫布渲染外的紅點。 您可以將畫布上下文包裝在管理圖層和可繪制對象的類中。

 const ctx = document.getElementById('canvas').getContext('2d'); const main = () => { const canvas = new Canvas(ctx); const layer = canvas.addLayer(); const circles = [ new Circle({ x: 50, y: 50 }, 3, 'red'), new Circle({ x: 100, y: 100 }, 6, 'green'), new Circle({ x: 150, y: 150 }, 12, 'blue') ]; layer.add(...circles); canvas.render(); // After 2 second, remove the red dot and re-render. setTimeout(() => { alert('Removing "red" circle, and adding a "cyan" circle...'); layer.remove(circles[0]); layer.add(new Circle({ x: 150, y: 50 }, 8, 'cyan')); canvas.render(); }, 2000); }; class Drawable { constructor(origin) { this.origin = origin; } draw(ctx) { } } class Layer { constructor(name) { this.name = name; this.drawables = []; } add(...drawables) { drawables.forEach(drawable => this.drawables.push(drawable)); } remove(drawableOrIndex) { if (isNaN(drawableOrIndex)) { drawableOrIndex = this.drawables.indexOf(drawableOrIndex); } if (drawableOrIndex > -1) { this.drawables.splice(drawableOrIndex, 1); } } render(ctx) { this.drawables.forEach(drawable => drawable.render(ctx)); } } class Canvas { constructor(ctx) { this.ctx = ctx; this.layers = []; } addLayer(name) { const newLayer = new Layer(name || 'layer-' + this.layers.length); this.layers.push(newLayer); return newLayer; } getLayer(nameOrIndex) { return isNaN(nameOrIndex) ? this.layers.find(layer => layer.name === nameOrIndex) : this.layers[nameOrIndex]; } render() { const { width, height } = this.ctx.canvas; this.ctx.clearRect(0, 0, width, height); this.layers.forEach(layer => layer.render(this.ctx)); } } class Circle extends Drawable { constructor(origin, radius, color) { super(origin); this.radius = radius; this.color = color; } render(ctx) { const { x, y } = this.origin; const diameter = this.radius * 2; ctx.save(); ctx.beginPath(); ctx.arc(x, y, this.radius, 0, Math.PI * 2, true); ctx.lineWidth = 0; ctx.fillStyle = this.color; ctx.fill(); ctx.restore(); } } main();
 #canvas { border: 1px solid black; }
 <canvas id="canvas" width=300 height=200></canvas>

由於現有答案已經證明了 OO 格言......

  • “我要了一根香蕉,但在叢林中得到了一只拿着香蕉的大猩猩。” ,

我添加了這個答案來演示更簡潔的 JavaScript 獨特的 OO 方法。

原因:與復雜性的斗爭。

復雜性是編碼人員的頭號敵人,添加不需要的抽象層、復制現有行為、預測未定義的需求,所有這些都會增加復雜性。

認為只有不到 100 行可能沒有關系,對於大型項目,額外的代碼加起來很快,每一行都是錯誤的額外來源。

JavaScript 提供了一個簡單且非常靈活的 OO 模型,強調通過臨時對象構造和擴展實現的多態性。 它還具有大量的編碼快捷方式,可以大大減少實現行為所需的行數

結果是功能幾乎相同的代碼減少了一半,

例子

  • 使用Array原型來實現層
  • circle通過將類型傳遞給構造函數來繼承drawable
  • color刪除,而不是索引或引用

 const ctx = canvas.getContext("2d"); const P2 = (x = 0, y = 0) => ({x,y}); const Drawable = (pos, color, size = 10, type = Circle) => ({pos, size, color, ...type}); const Circle = { draw(ctx) { ctx.fillStyle = this.color; ctx.beginPath(); ctx.arc(this.pos.x, this.pos.y, this.size, 0, Math.PI * 2); ctx.fill(); } }; const drawables = Object.assign([], { draw(ctx) { for (const d of this) { d.draw(ctx) } }, remove(color) { const idx = this.findIndex(d => d.color === color); return (idx > -1 && (this.splice(idx, 1)[0])) || undefined; }, } ); drawables.push(...[...document.querySelectorAll("#buttons button")].map((but, idx)=> Drawable(P2(100 + idx * 100, 50), but.dataset.color) )); drawables.draw(ctx); buttons.addEventListener("click", e => { if (drawables.remove(e.target.dataset.color)) { ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); drawables.draw(ctx); } });
 <canvas id="canvas" width="400" height="100"></canvas> <div id="buttons"> <button data-color="red">Remove Red</button> <button data-color="green">Remove Green</button> <button data-color="blue">Remove Blue</button> </div>

(我要補充一點, Polywhirl 先生的代碼沒有任何問題)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM