【问题标题】:Offscreen-Canvas not rendering some of the timeOffscreen-Canvas 有时不渲染
【发布时间】:2021-07-31 14:37:27
【问题描述】:

我正在尝试为扩展传单GridLayer api 的传单库实现一个浏览器光栅绘图插件。基本上对于每个图块都有一个函数createTile,它返回一个带有一些绘图的画布。并且传单显示了正确位置的瓷砖。

    
    initialize: function(raster_data){


        this.raster_data = raster_data;
        
    },

    createTile: function (tile_coords) {

        let _tile = document.createElement('canvas');
        
        let _tile_ctx = _tile.getContext('2d');

        // do some drawing here with values from this.raster_data

        return _tile;
    }

到目前为止,此实现运行良好。比我想在 webworker 中使用 offscreen-canvas 卸载绘图。所以我像这样重组了代码

    
    initialize: function(raster_data){


        this.raster_data = raster_data;
        this.tile_worker = new Worker('tile_renderer.js')
        
    },

    createTile: function (tile_coords) {

        let _tile = document.createElement('canvas').transferControlToOffscreen();
        
        this.tile_worker.postMessage({
            _tile: _tile,
            _raster_data: this.raster_data
        },[_tile])

        

        return _tile;
    }

这可行,但我时不时地看到一个空白的画布。那件事很随机,我不知道从哪里开始以及如何调试它。这可能是我使用单个工作人员渲染每个图块的问题吗?任何帮助表示赞赏。这是一个空白画布的示例。

【问题讨论】:

  • 您可以尝试创建minimal reproducible example 吗?这听起来非常crbug.com/1202481 也许您可以尝试在一条消息中批量处理对您的 Worker 的所有调用,因为这显然可以避免上述问题。
  • 这里有一个example,如果你放大和缩小最终你会得到一个。 @凯多
  • 就是这样,您可以通过将所有屏幕外画布存储在一个数组中并使用简单的 setTimeout(fn, 0) 节流器一次性批处理 postMessage 来解决这个问题。 artistic-quill-tote.glitch.meglitch.com/edit/#!/artistic-quill-tote 但我应该注意,如果你对这些画布所做的只是设置噪点,那么创建单个噪点图像并将其用作 tileLayer 可能会更高效(尽管我几乎知道没有传单):longing-humble-rainbow.glitch.meglitch.com/edit/#!/longing-humble-rainbow
  • 至于这个 Q/A 我希望 Chrome 的 bug 能尽快得到修复,我不确定答案会有多大用处......
  • 创建噪声仅用于示例,主要目的是根据与问题中的图像相似的值渲染栅格网格。顺便说一句,谢谢你,我一直在想我做错了什么。

标签: javascript canvas leaflet web-worker offscreen-canvas


【解决方案1】:

这是一个已知的错误:https://crbug.com/1202481

当过多的 OffscreenCanvases 串行发送到 Worker 时会出现此问题。

解决方法是通过一次调用将所有这些 OffscreenCanvases 批量发送到 postMessage()
在您的代码中,您可以通过存储所有要发送的对象并使用简单的去抖动策略(使用 0 超时)一次性发送它们来实现这一点:

createTile: function (tile_coords) {

  let _tile = document.createElement('canvas');

  _tile.setAttribute('width', 512);
  _tile.setAttribute('height', 512);

  let _off_tile = _tile.transferControlToOffscreen();


  this.tiles_to_add.push( _off_tile ); // store for later
  clearTimeout( this.batch_timeout_id ); // so that the callback is called only once
  this.batch_timeout_id = setTimeout( () => { 
    // send them all at once
    this.tileWorker.postMessage( { tiles: this.tiles_to_add }, this.tiles_to_add );
    this.tiles_to_add.length = 0;
  });

  return _tile;

}

现场示例:https://artistic-quill-tote.glitch.me/

【讨论】:

    猜你喜欢
    • 2023-03-26
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 2012-05-13
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    相关资源
    最近更新 更多