OpenLayers RenderComplete 事件回调在回调中使用此上下文

Posted

技术标签:

【中文标题】OpenLayers RenderComplete 事件回调在回调中使用此上下文【英文标题】:OpenLayers RenderComplete event callback use of this context inside callback 【发布时间】:2021-12-20 23:50:27 【问题描述】:

我的this 对象中有一个GIF.js 对象,我想在一个循环中使用this.gif.addframe(mapcanvas),该循环通过一个日期数组,最后我this.gif.render()。我必须在回调中使用this,如果我要缓存它并使用箭头函数,我理解这是可能的,但我需要有类似的东西

for(let i = 0 ; i < this.dateArraySurface10.length-2 ; i++)

    this.setTimeSurface10();
    this.map.renderSync();
    var self = this;
    const mapCanvas = document.createElement('canvas');
    this.map.once('rendercomplete', function () 
        const divElement = document.querySelector(".map");
        mapCanvas.width = divElement.offsetWidth;//size[0];
        mapCanvas.height = divElement.offsetHeight;//size[1];
        const mapContext = mapCanvas.getContext('2d');
        Array.prototype.forEach.call(
        document.querySelectorAll('.ol-layer canvas'),
        function (canvas) 
            if (canvas.width > 0) 
            const opacity = canvas.parentNode.style.opacity;
            mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
            const transform = canvas.style.transform;
            const matrix = transform
                .match(/^matrix\(([^\(]*)\)$/)[1] //eslint-disable-line
                .split(',')
                .map(Number);
            CanvasRenderingContext2D.prototype.setTransform.apply(
                mapContext,
                matrix
            );
            mapContext.drawImage(canvas, 0, 0);
            
        
        );
        self.gif.addFrame(mapCanvas, copy:true, delay: 200);
        console.log(i);                    
    );

this.gif.on('finished', function(blob)  
    window.open(URL.createObjectURL(blob));
);
this.gif.render();


在哪里

setTimeSurface10: function () 
   if (this.currentTimeSurface10 === null) 
      this.currentTimeSurface10 = this.startTimeSurface10;
    else if (this.currentTimeSurface10 >= this.endTimeSurface10) 
      this.currentTimeSurface10 = this.startTimeSurface10;
    else 
      this.currentTimeSurface10 = new Date(
         this.currentTimeSurface10.setMinutes(
         this.currentTimeSurface10.getMinutes() + 60)
      );
   
   this.surface10.getSource().updateParams( TIME: 
   this.currentTimeSurface10.toISOString().split(".")[0] + "Z" );

这只是伪代码,因为目前我设法制作了一个非常无聊的 GIF,它使用 let vm = this 和箭头函数模式一遍又一遍地添加相同的帧。有人可以向我解释如何在循环内的回调中访问和使用它吗?

【问题讨论】:

【参考方案1】:

this 在回调内部是地图对象。如果你不能使用箭头函数(例如你必须支持旧浏览器)在设置监听器之前给this分配一个变量

for(date in dateArray) 
   this.map.setTime(date)
   var self = this;
   this.map.on('renderComplete', function() 
      self.gif.addFrame(mapcanvas)
   

this.gif.render()

【讨论】:

先生。 @Mike 谢谢你的时间。我尝试了您的建议,但似乎没有得到我正在寻找的结果,甚至没有收到可用于研究的错误消息。我相信这是因为我正在创建这个(即自我)的副本,就像我之前尝试过的那样添加框架,因此当我尝试渲染“全局”GIF时它是空的。我需要将 rendercomplete 上的框架添加到全局 this.gif 先生。

以上是关于OpenLayers RenderComplete 事件回调在回调中使用此上下文的主要内容,如果未能解决你的问题,请参考以下文章

SlickGrid 没有 renderComplete 事件。是不是有一个事件会在所有渲染完成后触发

openlayers使用百度地图瓦片偏移问题解决方案

openlayers二次简单封装 线性、点

关于openlayers的问题

openlayers6 mapserver加载地图底图

openlayers绘制多边形