Determine whether the canvas shape is filled and the percentage
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.strokeStyle = "#FF0000";
ctx.rect(20,20,150,100);
ctx.stroke();
//模拟用户画笔填充
ctx.fillStyle="#FF0000";
ctx.fillRect(20,20,80,80);
//获取画布中数据
/*
* 对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
R - 红色(0-255)
G - 绿色(0-255)
B - 蓝色(0-255)
A - alpha 通道(0-255; 0 是透明的,255 是完全可见的)
*/
var imgData=ctx.getImageData(20,20,150,100);
</script>
After the drawing is completed, use ctx.getImageData()
the method to get the return format of the canvas 像素数据
: Uint8ClampedArray
.
Traverse the pixel data to determine whether the color value of each pixel is equal to the color of the brush. If they are equal, it means that the pixel was drawn by a brush;
if not, it means that the pixel was not drawn by a brush or the user did not fill it.
According to the result of the traversal, it can be judged whether the brush covers the entire canvas. If it is difficult to understand, just look at the bottom (tail) picture and then look at
it. It is similar to this, where A is 255
Here is a sample code:
// 获取绘图上下文和绘图目标
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.strokeStyle = "#FF0000";
ctx.rect(20,20,150,100);
ctx.stroke();
//模拟用户画笔填充
ctx.fillStyle="#FF0000";
ctx.fillRect(20,20,80,80);
//获取画布中数据 获取像素数据
/*
* 对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:
R - 红色(0-255)
G - 绿色(0-255)
B - 蓝色(0-255)
A - alpha 通道(0-255; 0 是透明的,255 是完全可见的)
*/
var imgData=ctx.getImageData(20,20,150,100);
let data = imageData.data;
// 遍历像素数据,判断画笔是否铺满整个画布
let isFull = true;
for (let i = 0; i < data.length; i += 4) {
if (data[i] !== 255 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 255) {
isFull = false;
break;
}
}
// 判断结果输出
console.log(isFull ? '已铺满' : '未铺满');
In the above sample code, assuming that the color of the brush is red (RGB value is 255,0,0), when traversing the pixel data, it is judged whether the RGB value of each pixel is red. If there are other colors, it means that the canvas is not blocked. Paved.
The filled pixel data is as follows:
the unfilled place is as follows:
percentage judgment:
For example, for this square, the percentage can be obtained by if (data[i] !== 255 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 255)
judging the pixel data when it meets the requirements of the user's brush, and the ratio of the total points, such as:
//满足用户在该形状中所画的图像数据点
let drawCount = 0; //满足的像素点
let total = data.length/4; //总共像素点
if (!(data[i] !== 255 || data[i + 1] !== 0 || data[i + 2] !== 0 || data[i + 3] !== 255)){
drawCount++;
}
//在区域形状内,用户画的比例
console.log((drawCount / total)*100+'%' )
The above is to obtain the getImageData method through content '2d', that is, "CanvasRenderingContext2D".
Note webgl
that there is no directly corresponding method function webgl2
WebGLRenderingContext
in the API . However, there are methods available to obtain pixel data for rendering onto a WebGL canvas.CanvasRenderingContext2D
getImageData
WebGLRenderingContext
readPixels
The basic usage of the readPixels method is as follows:
//获取WebGLRenderingContext对象:
var gl = canvas.getContext('webgl');
var pixels = new Uint8Array(canvas.width * canvas.height * 4);
gl.readPixels(0, 0, canvas.width, canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels)
The first two parameters of this method are the starting x and y coordinates, usually you can set them both to 0, because WebGL is an opaque rendering context. The next two parameters are the read width and height, you should also set both of them to the width and height of the canvas to get the pixel data for the entire canvas. The last parameter is an ArrayBufferView object used to store the read pixel data.
Note that readPixels
the method may not work in all browsers, especially some old browsers or some specific mobile devices may not support this function.
Also, note that although readPixels returns a Uint8ClampedArray with values between 0 and 255, not the pixel data format of CanvasRenderingContext2D's getImageData - a Float32Array with values between 0 and 1.
In some cases, you may need to convert WebGL pixel data to CanvasRenderingContext2D format. This can be done with:
var imageData = new ImageData(new Uint8ClampedArray(pixels), canvas.width, canvas.height);
In this example, we first create a new Uint8ClampedArray and copy the WebGL pixel data into it. We then created a new ImageData object with this new array. This new ImageData object can be used directly in CanvasRenderingContext2D methods such as putImageData.
Determine whether the canvas shape is full, determine whether the player is filled in the canvas shape, and determine the percentage of the player's painted shape