UNPKG

@icanvas/renderer

Version:
117 lines (115 loc) 3.43 kB
import Extends from './extends.js'; import Canvas from '@icanvas/apis/libs/canvas.js'; import Matrix3 from '@icanvas/maths/libs/matrix3.js'; export class Update { /** * 渲染列表中间缓存 */ HandleComponents = []; /** * * @param {Component} Stage 舞台 * @param {CanvasRenderingContext2D} Context 渲染上下文 */ Update(Stage, Context, Clear) { this.PreUpdate(Stage); this.HandleComponents.sort((a, b) => a._HandleParentZIndex - b._HandleParentZIndex || a._HandleZIndex - b._HandleZIndex); this.Updating(Context, Clear); this.HandleComponents.length = 0; } /** * 渲染前 * @param {Component} Component */ PreUpdate(Component) { if (!Component) return; if (Component instanceof Array) { for (let i = 0, l = Component.length; i < l; i++) this.PreUpdate(Component[i]); } else { if (!Component._visible) return; if (Component.preUpdate) Component.preUpdate(); if (!Component.matrix) Component.matrix = new Matrix3(); Component.parent ? Component.matrix.setToArray(Component.parent.matrix) : Component.matrix.identity(); Component.matrix .translate(Component.x, Component.y) .rotate(Component.radian) .scale(Component.scaleX, Component.scaleY); if (Component.update) { Component._HandleParentZIndex = ((Component.parent && Component.parent._HandleParentZIndex) || 0) + Component.zIndex; Component._HandleZIndex = this.HandleComponents.push(Component); } if (Component.children.length) this.PreUpdate(Component.children); } } /** * 渲染中 * @param {CanvasRenderingContext2D} Context 渲染上下文 * @param {Boolean} Clear 是否清空 */ Updating(Context, Clear = true) { if (Clear) Context.Clear(); this.HandleComponents.forEach(Component => { let Alpha = Component.alpha; if (Alpha == 0) return; if (Alpha > 1) Alpha = 1; if (Alpha != Context.globalAlpha) Context.globalAlpha = Alpha; Context.SetTransform(Component.matrix); if (Component.clip) { Context.save(); Context.beginPath(); Component.clip(Context); Context.closePath(); Context.clip(); } Component.update(Context); if (Component.clip) Context.restore(); }); Context.setTransform(1, 0, 0, 1, 0, 0); } } class Clock { time = 0; //本帧时间 then = 0; //上一帧时间 change = 0; //与上一帧的时差 delta = 0; //与上一帧的时差 interval = 1000 / 60; //步长 reset(interval = this.interval) { this.interval = interval; this.then = this.time = Date.now(); } step() { this.time = Date.now(); this.change = this.time - this.then; if (this.change > this.interval) { this.delta = this.change % this.interval; this.then = this.time - this.delta; return true; } } } export default class Renderer extends Update { Clock = new Clock(); Context = Canvas('main').getContext('2d'); constructor(width, height) { super(); Object.assign(this.Context.prototype || this.Context.__proto__, Extends); this.Context.SetSize(width, height); } /** * * @param {Component} Stage 主舞台 * @param {Number} Interval 每帧间隔 * @param {Function} Callback 每帧回调 */ Run(Stage, Interval = 1000 / 60, Callback) { this.Clock.reset(Interval); let HandleUpdate = t => { requestAnimationFrame(HandleUpdate); if (!this.Clock.step()) return; this.Update(Stage, this.Context); if (Callback) Callback(t); }; HandleUpdate(); return this; } }