@arcgis/core
Version:
ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API
3 lines (2 loc) • 3.93 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0.8/LICENSE.txt */
import{createResolver as e}from"../../../../core/promiseUtils.js";import{clone as t}from"../../../../core/libs/gl-matrix-2/factories/vec4f64.js";import{resampleHermite as r}from"../../../support/screenshotUtils.js";import{DataType as s}from"../../../webgl/enums.js";import{ensureAttachmentMaxSize as i}from"../../../webgl/FramebufferObject.js";import{createEmptyImageData as n}from"../../../../core/imageUtils.js";class o{constructor(e,t){this.parameters=e,this.fbos=t}}class a{constructor(e,t,r){this._rctx=e,this._renderFunctions=t,this._forceCameraHook=r,this.supersample=!0,this._screenshotQueue=new Array}destroy(){this._rctx=null}async takeScreenshot(t){await this._renderFunctions.prepareOverlay(),this._renderFunctions.requestRenderScene(0);const r=e();return this._screenshotQueue.push({settings:t,resolver:r}),r.promise}update(e,t){for(const r of this._screenshotQueue){if(null==this._rctx){r.resolver.reject();continue}const s={...r.settings,pixelRatio:r.settings.pixelRatio*e.parameters.camera.pixelRatio},i=this._renderScreenshot(e,s,t);r.resolver(i)}this._screenshotQueue.length=0}_renderScreenshotOverlay(e,t,r){e.width=t.width,e.height=t.height;const s=e.getContext("2d",{willReadFrequently:!0}),i=r.pixelRatio;return s.save(),s.translate(0,t.height),s.scale(1,-1),r.region&&s.translate(-r.region.x,-r.region.y),s.scale(i,i),t=this._renderFunctions.renderOverlay(e,r.disableDecorations,t),s.restore(),t}_readbackScreenshot(e,t){return e.resample?this._readbackScreenshotResampled({...e,resample:e.resample},t):this._readbackScreenshotImmediate(e,t)}_readbackScreenshotResampled(e,t){const{framebufferWidth:i,framebufferHeight:o,region:a,resample:h}=e,c=this._ensureScreenshotEncodeCanvas();let l=n(i,o,c);this._rctx.gl.readPixels(0,0,i,o,6408,s.UNSIGNED_BYTE,new Uint8Array(l.data.buffer)),t(),l=this._renderScreenshotOverlay(c,l,{...e,region:void 0});const d=n(a.width,a.height,c);return r(l,d,!0,h.region.x,o-(h.region.y+h.region.height),h.region.width,h.region.height)}_readbackScreenshotImmediate(e,t){const{framebufferHeight:r,region:i}=e,o=this._ensureScreenshotEncodeCanvas(),a=n(i.width,i.height,o);return this._rctx.gl.readPixels(i.x,r-(i.y+i.height),i.width,i.height,6408,s.UNSIGNED_BYTE,new Uint8Array(a.data.buffer)),t(),this._renderScreenshotOverlay(o,a,e)}_renderScreenshot(e,r,s){const n=e.parameters.camera,{framebufferWidth:o,framebufferHeight:a,ignorePadding:h,pixelRatio:c,disableDecorations:l,olidColor:d}=r,f={width:o,height:a};i(f,Math.min(this._rctx.parameters.maxTextureSize,this._rctx.parameters.maxRenderbufferSize));let u=!1;const m=f.width!==n.fullWidth||f.height!==n.fullHeight,g=h&&n.pixelRatio!==c,_=m||l||g||d;let p=null,b=null;if(_){const e=n.clone();if(h){const r=t(e.padding);for(let t=0;t<4;t++)r[t]=Math.round(r[t]/e.pixelRatio*c);e.padding=r}e.fullWidth=f.width,e.fullHeight=f.height,e.pixelRatio=c;const r=n.fovX-e.fovX,i=n.fovY-e.fovY;r<0&&r<i?e.fovX=n.fovX:i<0&&i<r&&(e.fovY=n.fovY);const o={camera:e,contentCamera:e,mode:2,alignPixelEnabled:!0,contentPixelRatio:e.pixelRatio};this._forceCameraHook(o),u=!0;const a=this._renderFunctions.renderScene(o,s,d?2:1,l);b=a.screen,p=a.olid}const x=()=>{this._rctx.bindFramebuffer(null),b?.release()};this._rctx.bindFramebuffer(b?.fbo);const v=this._readbackScreenshot(r,x);let S=null;if(d){const e=()=>{this._rctx.bindFramebuffer(null),p?.release()};this._rctx.bindFramebuffer(p?.fbo),S=this._readbackScreenshot(r,e),this._rctx.bindFramebuffer(null)}if(_&&!this._rctx.contextAttributes.alpha)for(let t=3;t<v.data.length;t+=4)v.data[t]=255;if(S&&!this._rctx.contextAttributes.alpha)for(let t=3;t<S.data.length;t+=4)S.data[t]=255;return u&&this._forceCameraHook(e.parameters),[v,S]}_ensureScreenshotEncodeCanvas(){return this._screenshotEncodeCanvas??=document.createElement("canvas"),this._screenshotEncodeCanvas}}export{o as ScreenshotContext,a as ScreenshotManager};