画布:删除图像上的对象后还原图像 [英] Canvas: Restore Image after removing object on it

查看:47
本文介绍了画布:删除图像上的对象后还原图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const image = new Image(60, 45); // Using optional size for image
image.onload = drawImageActualSize; // Draw when image has loaded

// Load an image of intrinsic size 300x227 in CSS pixels
image.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';

function drawImageActualSize() {
  // Use the intrinsic size of image in CSS pixels for the canvas element
  canvas.width = this.naturalWidth;
  canvas.height = this.naturalHeight;

  // Will draw the image as 300x227, ignoring the custom size of 60x45
  // given in the constructor
  ctx.drawImage(this, 0, 0);

  // To use the custom size we'll have to specify the scale parameters 
  // using the element's width and height properties - lets draw one 
  // on top in the corner:
  ctx.drawImage(this, 0, 0, this.width, this.height);
  ctx.save();
  ctx.fillStyle = 'green';
ctx.fillRect(10, 10, 150, 100);

ctx.restore();
ctx.clearRect(10, 10, 150, 100);
}

<canvas id="canvas" width=300 height=200></canvas>

这里ctx.clearRect(10,10,150,100)方法,除去绿色部分和图像,并显示白色画布.

Here ctx.clearRect(10, 10, 150, 100) method, removes green part as well as image and shows white canvas.

我只希望删除绿色部分并恢复以前的图像.

I want to remove only green part and restore previous image.

我该如何实现?

推荐答案

重画

添加和删除动态内容的标准方法是在每次更改时重新渲染画布.这就是运行速度为60fps的HTML画布游戏的工作方式,并且每帧可以更改100项内容.

Redraw

The standard way to add and remove dynamic content is to re render the canvas every time there is a change. This is how HTML canvas games running at 60fps do it and they can have 100s of items changing per frame.

还有其他方法需要在每次绘制矩形时都对其进行复制,然后在要删除矩形时在矩形上绘制副本.

There are other methods that require making a copy of what is under the rectangle each time it is drawn, and then drawing the copy over the rectangle when you want it removed.

这很复杂,并且每个动态对象至少需要绘制一个额外的画布,因此是一个内存消耗.或使用 getImageData putImageData 也是一个内存消耗,速度很慢,将导致大量的GC操作,并且不适用于不安全的内容(跨域或本地文件存储的图像).

This is complex and requires at least one extra canvas per dynamic object being drawn and is thus a memory hog. Or use getImageData and putImageData also a memory hog, is supa slow, will result in a lot of GC action, and is not available for unsecured content (images across domains, or from local file store).

重绘是迄今为止最简单的方法.仅在花费300ms以上的时间渲染所有内容(对于非动画内容)时,您才会考虑其他方法

Redraw is by far the simplest way. You would only consider other methods if it took more than a few 100ms to render all content (for non animated content)

在示例中,变量 rectOn 如果为true,则向画布添加一个绿色矩形(同时绘制图像和矩形).如果不正确,则删除矩形(仅绘制图像).

In the example the variable rectOn if true add a green rectangle to the canvas (Draws both the image and the rectangle). If not true then the rectangle is removed (only the image is drawn).

函数 draw 根据变量 rectOn

单击按钮添加/删除矩形.

Click button to add/remove rectangle.

const ctx = canvas.getContext('2d');
var rectOn = false; 
const image = new Image();
image.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
image.addEventListener("load", ready, {once:true});
function ready() {
    canvas.width = this.naturalWidth;
    canvas.height = this.naturalHeight;
    loading.classList.add("hide");
    addRemove.classList.remove("hide");
    addRemove.addEventListener("click", toggle);
    draw();
}
function draw() {
    ctx.drawImage(image, 0, 0);
    if (rectOn) {
        ctx.fillStyle = "#0F0";
        ctx.fillRect(10, 50, 150, 100);    
    }
}
function toggle() {
    rectOn = !rectOn;     
    addRemove.textContent = (rectOn ? "Remove": "Add" ) + " rect";
    draw();
}

button { cursor: pointer; width: 120px }
.hide {display:none}
canvas { position: absolute; top: 0px; left: 0px; z-index:-1; }

<span id="loading">Loading image</span><button id="addRemove" class="hide">Add green rect</button><br>
<canvas id="canvas"></canvas>

这篇关于画布:删除图像上的对象后还原图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆