@visactor/vrender-animate
Version:
This module provides a graph-based animation system for VRender.
139 lines (134 loc) • 7.29 kB
JavaScript
"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