echarts-wordcloud
echarts-wordcloud copied to clipboard
可能存在maskImage底层没有绘制完,就执行updateCanvasMask,得到的是一片空白的情况
7093行
if (maskImage) { try { ctx.drawImage(maskImage, 0, 0, canvas.width, canvas.height); updateCanvasMask(canvas); } catch (e) { console.error('Invalid mask image'); console.error(e.toString()); } }
我这里出现一个情况,画布上得到的是一片空白,在updateCanvasMask这个地方加上断点后就好了,不知道要怎么处理
请问你这个问题解决了吗?我也遇到了相同的问题
遇到了相同的问题
https://www.cnblogs.com/padding1015/p/9717845.html 结合echarts-wordcloud的源码和这篇文章分析,找到了原因是drawImage的时机不对
除了没加载完就绘制以外,还有一个可能的原因:
太长不看的解决方案:使用前景色为白色(#ffffffff
),背景色为透明(#xxxxxx00
)的maskImage
(实测svg
格式可行)
原因分析:
-
registerLayout
中当maskImage
存在时调用updateCanvasMask
更新canvas
。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L75-L85
2.updateCanvasMask
中创建了一份ImageData
副本newImageData
。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L13-L18
-
toneSum
计算所有像素点上RGB值的和,toneCnt
计算像素点数。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L20-L31
- 每个像素点上RGB的平均值即为RGB阈值
threshold
。 https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L32
5.由于backgroundColor
规定是#ffffffff
,所以应绘制区域上的像素点上的Alpha
必须小于128,RGB
必须小于threshold
。坑点来了:假设传入图像是纯色块,由于传入图像在getImageData
中经历了栅格化操作以及浮点误差的存在,导致图像有一些像素点因为略微小于threshold
而被错误归入非绘制区域。最后更新canvas
。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L34-L58
-
start
中根据gridSize
将全图划分ngx * ngy
个区域存放在数组grid
中,网格grid[gx][gy]
是可绘制的(grid[gx][gy]===true
),当且仅当imageData[gx*g .. (gx+1)*g-1][gy*g .. (gy+1)*g-1]
里的像素全部都位于可绘制的区域内(!==backgroundColor
),但是由于第5点中有一些像素点被错误分类了,所以很可能导致没有区域满足这个条件(因为要求全部像素点可绘制),于是你就得到了一个全为false
的grid
。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/layout.js#L1035-L1065
- 然后你调用
putWord->tryToPutWordAtPoint->canFitText
就会提前返回而不绘制,最后得到一片空白。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/layout.js#L896-L906
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/layout.js#L658-L679
- 所以为什么改成全白就好了?因为这样就可以使得
tone > threshold
永真,从而根据Alpha
判断是否将像素归入可绘制区域,从而避免浮点误差。
https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L40
- 解决方法:新增一个传入参数
maskImageMethod: {alpha: null | number | 'belowAvg' | 'aboveAvg', rgb: null | number | 'belowAvg' | 'aboveAvg' }
,null
表示不起作用,number
表示采用传入的参数number
作为阈值,'belowAvg', 'aboveAvg'
表示低于/高于平均值 +3/-3 (避免浮点误差)。
新增一个参数 新增到哪里了
新增一个参数 新增到哪里了
这只是提供一个可能的改进方案,显然官方并没有修这个bug的想法。
在图片加载完成后执行渲染就行了,onload事件里面写渲染操作