echarts-wordcloud icon indicating copy to clipboard operation
echarts-wordcloud copied to clipboard

可能存在maskImage底层没有绘制完,就执行updateCanvasMask,得到的是一片空白的情况

Open Immanding opened this issue 6 years ago • 7 comments

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这个地方加上断点后就好了,不知道要怎么处理

Immanding avatar Sep 30 '18 03:09 Immanding

请问你这个问题解决了吗?我也遇到了相同的问题

cocotaken avatar Oct 15 '18 02:10 cocotaken

遇到了相同的问题

zhukai78 avatar Nov 14 '18 06:11 zhukai78

https://www.cnblogs.com/padding1015/p/9717845.html 结合echarts-wordcloud的源码和这篇文章分析,找到了原因是drawImage的时机不对

darlk avatar Apr 30 '19 02:04 darlk

除了没加载完就绘制以外,还有一个可能的原因:

太长不看的解决方案:使用前景色为白色(#ffffffff),背景色为透明(#xxxxxx00)的maskImage(实测svg格式可行)

原因分析:

  1. 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

  1. toneSum计算所有像素点上RGB值的和,toneCnt计算像素点数。

https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L20-L31

  1. 每个像素点上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

  1. 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点中有一些像素点被错误分类了,所以很可能导致没有区域满足这个条件(因为要求全部像素点可绘制),于是你就得到了一个全为falsegrid

https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/layout.js#L1035-L1065

  1. 然后你调用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

  1. 所以为什么改成全白就好了?因为这样就可以使得tone > threshold永真,从而根据Alpha判断是否将像素归入可绘制区域,从而避免浮点误差。

https://github.com/ecomfe/echarts-wordcloud/blob/52ce56c5a939e9ccbc6045ce79ceeb2073de8394/src/wordCloud.js#L40

  1. 解决方法:新增一个传入参数maskImageMethod: {alpha: null | number | 'belowAvg' | 'aboveAvg', rgb: null | number | 'belowAvg' | 'aboveAvg' }null表示不起作用,number表示采用传入的参数number作为阈值,'belowAvg', 'aboveAvg' 表示低于/高于平均值 +3/-3 (避免浮点误差)。

Tanimodori avatar Nov 14 '19 18:11 Tanimodori

新增一个参数 新增到哪里了

liuyongly avatar Jan 28 '21 07:01 liuyongly

新增一个参数 新增到哪里了

这只是提供一个可能的改进方案,显然官方并没有修这个bug的想法。

Tanimodori avatar Feb 07 '21 15:02 Tanimodori

image 在图片加载完成后执行渲染就行了,onload事件里面写渲染操作

ldongrui avatar Jan 17 '24 03:01 ldongrui