@icanvas/renderer
Version:
这是icanvas的渲染模块
117 lines (115 loc) • 3.43 kB
JavaScript
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;
}
}