在Canvas上通过imageData绘制灰色画布全白,遗漏了什么步骤?
Canvas渲染全白问题修复方案
代码存在3个核心错误,导致无法正常渲染预期的#808080灰色画布:
- 像素坐标换算逻辑错误:遍历ImageData时,像素序号转x/y坐标的公式写错,y坐标误用乘法计算,导致绝大多数像素点读取二维数组
grid[x][y]时得到undefined,无法写入正确颜色值。正确坐标换算逻辑:const pixelIndex = index / 4; // 当前遍历到的像素序号 const y = Math.floor(pixelIndex / width); // 纵向行坐标 const x = pixelIndex % width; // 横向列坐标 - 未设置Alpha透明度通道:ImageData中每个像素占4个字节,顺序为R(红)、G(绿)、B(蓝)、A(透明度),代码仅赋值了前三个颜色通道,A通道默认值为0(完全透明),会透出页面底层的白色背景,视觉上呈现全白效果。需要给每个像素的第4位赋值
255,即完全不透明。 - 冗余无效操作:
image_data.data是Uint8ClampedArray引用类型,直接修改data数组内容就会同步更新ImageData本身,image_data.data = data;属于多余代码,无实际作用。
修正后可运行代码
;(function() { var context = null; var grid = []; var height = null; var image_data = null; var width = null; var draw = function() { var data = image_data.data; for (var index = 0; index < data.length; index += 4) { var pixelIndex = index / 4; var y = Math.floor(pixelIndex / width); var x = pixelIndex % width; data[index] = grid[x][y][0]; data[index + 1] = grid[x][y][1]; data[index + 2] = grid[x][y][2]; data[index + 3] = 255; } context.putImageData(image_data, 0, 0); } var init = function() { height = jQuery(window).height(); width = jQuery(window).width(); jQuery('#container').html('<canvas id="map" height="' + height + '" width="' + width + '"></canvas>') context = document.getElementById('map').getContext('2d'); image_data = context.getImageData(0, 0, width, height); for (var outer = 0; outer < width; outer += 1) { grid[outer] = []; for (var inner = 0; inner < height; inner += 1) { grid[outer][inner] = [128, 128, 128]; } } } var start_drawing = function() { draw(); setTimeout(start_drawing, 1); }; init(); start_drawing(); })();
配套HTML代码无需调整:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <div id="container"></div>
替换后即可正常渲染全屏灰色画布。
内容的提问来源于stack exchange,提问作者Christos Hayward
相关产品推荐
相关产品推荐

