UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

106 lines (78 loc) 3.5 kB
/** * @author Richard Davey <rich@phaser.io> * @copyright 2013-2025 Phaser Studio Inc. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ var CanvasPool = require('../../display/canvas/CanvasPool'); var Color = require('../../display/color/Color'); var GetFastValue = require('../../utils/object/GetFastValue'); /** * Takes a snapshot of an area from the current frame displayed by a WebGL canvas. * * This is then copied to an Image object. When this loads, the results are sent * to the callback provided in the Snapshot Configuration object. * * @function Phaser.Renderer.Snapshot.WebGL * @since 3.0.0 * * @param {WebGLRenderingContext} sourceContext - The WebGL context to take a snapshot of. * @param {Phaser.Types.Renderer.Snapshot.SnapshotState} config - The snapshot configuration object. */ var WebGLSnapshot = function (sourceContext, config) { var gl = sourceContext; var callback = GetFastValue(config, 'callback'); var type = GetFastValue(config, 'type', 'image/png'); var encoderOptions = GetFastValue(config, 'encoder', 0.92); var x = Math.abs(Math.round(GetFastValue(config, 'x', 0))); var y = Math.abs(Math.round(GetFastValue(config, 'y', 0))); var getPixel = GetFastValue(config, 'getPixel', false); var isFramebuffer = GetFastValue(config, 'isFramebuffer', false); var bufferWidth = (isFramebuffer) ? GetFastValue(config, 'bufferWidth', 1) : gl.drawingBufferWidth; var bufferHeight = (isFramebuffer) ? GetFastValue(config, 'bufferHeight', 1) : gl.drawingBufferHeight; if (getPixel) { var pixel = new Uint8Array(4); var destY = (isFramebuffer) ? y : bufferHeight - y; gl.readPixels(x, destY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel); callback.call(null, new Color(pixel[0], pixel[1], pixel[2], pixel[3])); } else { var width = Math.floor(GetFastValue(config, 'width', bufferWidth)); var height = Math.floor(GetFastValue(config, 'height', bufferHeight)); var total = width * height * 4; var pixels = new Uint8Array(total); gl.readPixels(x, bufferHeight - y - height, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); var canvas = CanvasPool.createWebGL(this, width, height); var ctx = canvas.getContext('2d', { willReadFrequently: true }); var imageData = ctx.getImageData(0, 0, width, height); var data = imageData.data; for (var py = 0; py < height; py++) { for (var px = 0; px < width; px++) { var sourceIndex = ((height - py - 1) * width + px) * 4; var destIndex = (isFramebuffer) ? total - ((py * width + (width - px)) * 4) : (py * width + px) * 4; data[destIndex + 0] = pixels[sourceIndex + 0]; data[destIndex + 1] = pixels[sourceIndex + 1]; data[destIndex + 2] = pixels[sourceIndex + 2]; data[destIndex + 3] = pixels[sourceIndex + 3]; } } ctx.putImageData(imageData, 0, 0); var image = new Image(); image.onerror = function () { callback.call(null); CanvasPool.remove(canvas); }; image.onload = function () { callback.call(null, image); CanvasPool.remove(canvas); }; image.src = canvas.toDataURL(type, encoderOptions); } }; module.exports = WebGLSnapshot;