UNPKG

@visactor/vrender-animate

Version:

This module provides a graph-based animation system for VRender.

139 lines (134 loc) 7.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.DisappearAnimateBase = void 0; const vrender_core_1 = require("@visactor/vrender-core"), custom_animate_1 = require("../../custom-animate"); class DisappearAnimateBase extends custom_animate_1.AStageAnimate { constructor(from, to, duration, easing, params) { super(from, to, duration, easing, params), this.webglCanvas = null, this.gl = null, this.program = null, this.currentAnimationRatio = 0, this.animationTime = 0; } onUpdate(end, ratio, out) { super.onUpdate(end, ratio, out), this.currentAnimationRatio = ratio, this.animationTime = ratio * Math.PI * 2; } getAnimationTime() { return this.currentAnimationRatio > 0 ? this.animationTime : Date.now() / 1e3; } getDurationFromParent() { return this.duration || 1e3; } initWebGL(canvas) { try { if (this.webglCanvas = vrender_core_1.vglobal.createCanvas({ width: canvas.width, height: canvas.height, dpr: vrender_core_1.vglobal.devicePixelRatio }), !this.webglCanvas) return console.warn("WebGL canvas creation failed"), !1; this.webglCanvas.style.width = canvas.style.width || `${canvas.width}px`, this.webglCanvas.style.height = canvas.style.height || `${canvas.height}px`; let glContext = null; try { glContext = this.webglCanvas.getContext("webgl"), glContext || (glContext = this.webglCanvas.getContext("experimental-webgl")); } catch (e) { console.warn("Failed to get WebGL context:", e); } if (this.gl = glContext, !this.gl) return console.warn("WebGL not supported"), !1; const shaders = this.getShaderSources(); return this.program = this.createShaderProgram(shaders.vertex, shaders.fragment), null !== this.program; } catch (error) { return console.warn("Failed to initialize WebGL:", error), !1; } } createShaderProgram(vertexSource, fragmentSource) { if (!this.gl) return null; const vertexShader = this.createShader(this.gl.VERTEX_SHADER, vertexSource), fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, fragmentSource); if (!vertexShader || !fragmentShader) return null; const program = this.gl.createProgram(); return program ? (this.gl.attachShader(program, vertexShader), this.gl.attachShader(program, fragmentShader), this.gl.linkProgram(program), this.gl.getProgramParameter(program, this.gl.LINK_STATUS) ? program : (console.error("Shader program link error:", this.gl.getProgramInfoLog(program)), null)) : null; } createShader(type, source) { if (!this.gl) return null; const shader = this.gl.createShader(type); return shader ? (this.gl.shaderSource(shader, source), this.gl.compileShader(shader), this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS) ? shader : (console.error("Shader compile error:", this.gl.getShaderInfoLog(shader)), this.gl.deleteShader(shader), null)) : null; } setupWebGLState(canvas) { this.gl && this.webglCanvas && (this.webglCanvas.width === canvas.width && this.webglCanvas.height === canvas.height || (this.webglCanvas.width = canvas.width, this.webglCanvas.height = canvas.height), this.gl.viewport(0, 0, this.webglCanvas.width, this.webglCanvas.height), this.gl.clearColor(0, 0, 0, 0), this.gl.clear(this.gl.COLOR_BUFFER_BIT)); } createFullScreenQuad() { if (!this.gl) return null; const vertices = new Float32Array([ -1, -1, 0, 1, 1, -1, 1, 1, -1, 1, 0, 0, 1, 1, 1, 0 ]), vertexBuffer = this.gl.createBuffer(); return this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer), this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW), vertexBuffer; } createTextureFromCanvas(canvas) { if (!this.gl) return null; const texture = this.gl.createTexture(); return this.gl.activeTexture(this.gl.TEXTURE0), this.gl.bindTexture(this.gl.TEXTURE_2D, texture), this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, canvas), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR), this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR), texture; } setupVertexAttributes() { if (!this.gl || !this.program) return; const positionLocation = this.gl.getAttribLocation(this.program, "a_position"), texCoordLocation = this.gl.getAttribLocation(this.program, "a_texCoord"); this.gl.enableVertexAttribArray(positionLocation), this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, !1, 16, 0), this.gl.enableVertexAttribArray(texCoordLocation), this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, !1, 16, 8); } createOutputCanvas(canvas) { const outputCanvas = vrender_core_1.vglobal.createCanvas({ width: canvas.width, height: canvas.height, dpr: vrender_core_1.vglobal.devicePixelRatio }), ctx = outputCanvas.getContext("2d"); return ctx ? (ctx.clearRect(0, 0, canvas.width, canvas.height), ctx.drawImage(canvas, 0, 0), { canvas: outputCanvas, ctx: ctx }) : null; } getShaderSources() { return null; } applyWebGLEffect(canvas) { return null; } applyCanvas2DEffect(canvas) { return null; } supportsWebGL() { return null !== this.getShaderSources(); } supportsCanvas2D() { return this.applyCanvas2DEffect !== DisappearAnimateBase.prototype.applyCanvas2DEffect; } release() { super.release(), this.gl && (this.program && (this.gl.deleteProgram(this.program), this.program = null), this.gl = null), this.webglCanvas && (this.webglCanvas = null), this.currentAnimationRatio = 0, this.animationTime = 0; } afterStageRender(stage, canvas) { let result = null; if (this.supportsWebGL() && (this.gl || this.initWebGL(canvas) || console.warn("WebGL初始化失败,尝试Canvas 2D回退"), this.gl)) { if (result = this.applyWebGLEffect(canvas), result) return result; console.warn("WebGL特效执行失败,尝试Canvas 2D回退"); } if (this.supportsCanvas2D()) { if (result = this.applyCanvas2DEffect(canvas), result) return result; console.warn("Canvas 2D特效执行失败"); } return this.supportsWebGL() || this.supportsCanvas2D() || console.error(`特效类 ${this.constructor.name} 未实现任何渲染方法。请实现 applyWebGLEffect 或 applyCanvas2DEffect 方法。`), canvas; } } exports.DisappearAnimateBase = DisappearAnimateBase; //# sourceMappingURL=DisappearAnimateBase.js.map