git add clock basic renderer
This commit is contained in:
parent
a7aae62233
commit
2550e2e14f
143
source/GLRender/BasicRenderer.ts
Normal file
143
source/GLRender/BasicRenderer.ts
Normal file
@ -0,0 +1,143 @@
|
||||
import { AbstractRenderer, IRendererParam, IAnyObject } from "@Model/Renderer";
|
||||
import { EventType } from "@Model/Emitter";
|
||||
import { GLCanvas, GLCanvasOption } from "./GLCanvas";
|
||||
import { GLContext } from "./GLContext";
|
||||
import { Clock } from "@Model/Clock";
|
||||
|
||||
interface IRendererOwnParams {}
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
type IRendererParams = IRendererOwnParams & GLCanvasOption;
|
||||
|
||||
abstract class BasicRenderer<
|
||||
P extends IRendererParam = {},
|
||||
M extends IAnyObject = {},
|
||||
E extends Record<EventType, any> = {}
|
||||
> extends AbstractRenderer<P, M & IRendererParams, E> {
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
public param: Partial<M & IRendererParams> = {};
|
||||
|
||||
/**
|
||||
* 使用的画布
|
||||
*/
|
||||
public canvas: GLCanvas;
|
||||
|
||||
/**
|
||||
* 渲染时钟
|
||||
*/
|
||||
protected clock: Clock;
|
||||
|
||||
public constructor(canvas: HTMLCanvasElement, param: Partial<M & IRendererParams> = {}) {
|
||||
super();
|
||||
|
||||
// 初始化参数
|
||||
this.param = {
|
||||
autoResize: param.autoResize ?? true,
|
||||
mouseEvent: param.autoResize ?? true,
|
||||
eventLog: param.eventLog ?? false,
|
||||
className: param.className ?? ""
|
||||
} as M & IRendererParams;
|
||||
|
||||
// 实例化画布对象
|
||||
this.canvas = new GLCanvas(canvas, this.param);
|
||||
|
||||
// 尝试 webgl2
|
||||
this.gl = this.canvas.can.getContext("webgl2") as any;
|
||||
if (this.gl) {
|
||||
this.glVersion = 2;
|
||||
console.log("Render: Using WebGL2 :)");
|
||||
} else {
|
||||
|
||||
// 尝试 WebGL1
|
||||
this.gl = this.canvas.can.getContext("webgl") as any;
|
||||
if (this.gl){
|
||||
this.glVersion = 1;
|
||||
console.log("Render: Using WebGL1 :(");
|
||||
}
|
||||
|
||||
// 获取失败发出警告
|
||||
else {
|
||||
console.error("Render: Not supported WebGL!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实例化时钟
|
||||
*/
|
||||
this.clock = new Clock();
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
this.onLoad(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行渲染
|
||||
*/
|
||||
protected run() {
|
||||
this.clock.setFn(this.loop.bind(this));
|
||||
this.clock.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* 大小变化
|
||||
*/
|
||||
protected resize() {
|
||||
this.loop(0);
|
||||
this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启自动大小调整
|
||||
*/
|
||||
protected autoResize() {
|
||||
this.canvas.on("resize", this.resize.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清屏颜色
|
||||
*/
|
||||
public cleanColor: [number, number, number, number] = [.1, .1, .1, 1.];
|
||||
|
||||
/**
|
||||
* 清屏
|
||||
*/
|
||||
public cleanCanvas(){
|
||||
this.gl.clearColor(
|
||||
this.cleanColor[0], this.cleanColor[1],
|
||||
this.cleanColor[2], this.cleanColor[3]
|
||||
);
|
||||
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* GL 上下文
|
||||
*/
|
||||
public gl: GLContext;
|
||||
|
||||
/**
|
||||
* WebGL 版本
|
||||
*/
|
||||
public glVersion: (0 | 1 | 2) = 0;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
* @param param 渲染器参数
|
||||
*/
|
||||
abstract onLoad(param: Partial<M & IRendererParams>): void;
|
||||
|
||||
/**
|
||||
* 渲染器执行
|
||||
*/
|
||||
abstract loop(dur: number): void;
|
||||
|
||||
}
|
||||
|
||||
export default BasicRenderer;
|
||||
export { BasicRenderer, IRendererParams };
|
@ -1,49 +1,30 @@
|
||||
import { AbstractRenderer, ObjectID, ObjectData, ICommonParam } from "@Model/Renderer";
|
||||
import { GLCanvas, GLCanvasOption } from "./GLCanvas";
|
||||
import { ObjectID, ObjectData, ICommonParam } from "@Model/Renderer";
|
||||
import { BasicRenderer, IRendererParams } from "./BasicRenderer";
|
||||
|
||||
interface IRendererOwnParams {}
|
||||
interface IClassicRendererParams {}
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
type IRendererParams = IRendererOwnParams & GLCanvasOption;
|
||||
class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
||||
|
||||
class ClassicRenderer extends AbstractRenderer<{}, IRendererParams> {
|
||||
onLoad(param: Partial<IClassicRendererParams & IRendererParams>): void {
|
||||
this.run();
|
||||
this.autoResize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
public param: IRendererParams;
|
||||
clean(id?: ObjectID | ObjectID[]): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用的画布
|
||||
*/
|
||||
public canvas: GLCanvas;
|
||||
points(id: ObjectID, position: ObjectData, param?: ICommonParam): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
public constructor(canvas: HTMLCanvasElement, param: IRendererParams = {}) {
|
||||
super();
|
||||
cube(id: ObjectID, position: ObjectData, param?: ICommonParam): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
// 初始化参数
|
||||
this.param = {
|
||||
autoResize: param.autoResize ?? true,
|
||||
mouseEvent: param.autoResize ?? true,
|
||||
eventLog: param.eventLog ?? false,
|
||||
clasName: param.clasName ?? ""
|
||||
}
|
||||
|
||||
// 实例化画布对象
|
||||
this.canvas = new GLCanvas(canvas, this.param);
|
||||
}
|
||||
|
||||
clean(id?: ObjectID | ObjectID[]): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
points(id: ObjectID, position: ObjectData, param?: ICommonParam): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
cube(id: ObjectID, position: ObjectData, param?: ICommonParam): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
loop(): void {
|
||||
this.cleanCanvas();
|
||||
}
|
||||
}
|
||||
|
||||
export default ClassicRenderer;
|
||||
|
@ -27,7 +27,7 @@ interface GLCanvasOption {
|
||||
/**
|
||||
* 节点类名
|
||||
*/
|
||||
clasName?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
type GLCanvasEvent = {
|
||||
@ -270,7 +270,7 @@ class GLCanvas extends Emitter<GLCanvasEvent> {
|
||||
this.canvas = ele ?? document.createElement("canvas");
|
||||
|
||||
this.div = document.createElement("div");
|
||||
this.div.className = opt.clasName ?? "";
|
||||
this.div.className = opt.className ?? "";
|
||||
this.div.appendChild(this.canvas);
|
||||
|
||||
this.canvas.style.width = "100%";
|
||||
|
75
source/Model/Clock.ts
Normal file
75
source/Model/Clock.ts
Normal file
@ -0,0 +1,75 @@
|
||||
export {Clock, LoopFunction};
|
||||
|
||||
type LoopFunction = (t: number)=>void;
|
||||
|
||||
/**
|
||||
* 时钟
|
||||
*/
|
||||
class Clock {
|
||||
|
||||
/**
|
||||
* 总用时
|
||||
*/
|
||||
private allTime: number = 0;
|
||||
|
||||
/**
|
||||
* 速率
|
||||
*/
|
||||
public speed: number = 1;
|
||||
|
||||
/**
|
||||
* 主函数
|
||||
*/
|
||||
private fn: LoopFunction;
|
||||
|
||||
/**
|
||||
* 动画循环
|
||||
* @param fn 循环函数
|
||||
*/
|
||||
public constructor(fn?: LoopFunction){
|
||||
this.fn = fn ?? ((t) => {});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置函数
|
||||
* @param fn 循环函数
|
||||
*/
|
||||
public setFn(fn:LoopFunction){
|
||||
this.fn = fn;
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始
|
||||
*/
|
||||
public run(){
|
||||
|
||||
// 主循环
|
||||
let loop = (t:number)=>{
|
||||
|
||||
// 时差
|
||||
let dur = (t - this.allTime) * this.speed / 1000;
|
||||
|
||||
// 检测由于失焦导致的丢帧
|
||||
if (t - this.allTime < 100) {
|
||||
this.fn(dur);
|
||||
}
|
||||
|
||||
// 更新时间
|
||||
this.allTime = t;
|
||||
|
||||
// 继续循环
|
||||
requestAnimationFrame(loop);
|
||||
|
||||
}
|
||||
|
||||
// 获取时间
|
||||
requestAnimationFrame((t)=>{
|
||||
|
||||
// 记录初始时间
|
||||
this.allTime = t;
|
||||
|
||||
// 开启循环
|
||||
requestAnimationFrame(loop);
|
||||
})
|
||||
}
|
||||
}
|
@ -57,6 +57,9 @@ interface IRendererConstructor<
|
||||
|
||||
/**
|
||||
* 渲染器 API
|
||||
* @template P 渲染器绘制参数
|
||||
* @template M 渲染器参数
|
||||
* @template E 渲染器事件
|
||||
*/
|
||||
abstract class AbstractRenderer<
|
||||
P extends IRendererParam = {},
|
||||
@ -67,7 +70,7 @@ abstract class AbstractRenderer<
|
||||
/**
|
||||
* 渲染器参数
|
||||
*/
|
||||
abstract param: M;
|
||||
abstract param: Partial<M>;
|
||||
|
||||
/**
|
||||
* 类型断言
|
||||
@ -119,4 +122,8 @@ abstract class AbstractRenderer<
|
||||
}
|
||||
|
||||
export default AbstractRenderer;
|
||||
export { AbstractRenderer, ObjectID, ICommonParam, ObjectData, IRendererConstructor };
|
||||
export {
|
||||
AbstractRenderer, ObjectID, IAnyObject,
|
||||
ICommonParam, IRendererParam,
|
||||
ObjectData, IRendererConstructor
|
||||
};
|
@ -2,6 +2,7 @@ div.main-canvas {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba($color: #000000, $alpha: .9);
|
||||
|
||||
div.canvas {
|
||||
width: 100%;
|
||||
|
@ -23,7 +23,7 @@ class Laboratory extends Component {
|
||||
const canvas = document.createElement("canvas");
|
||||
|
||||
const renderer = new ClassicRenderer(canvas, {
|
||||
clasName: "canvas"
|
||||
className: "canvas"
|
||||
});
|
||||
|
||||
console.log(renderer);
|
||||
|
Loading…
Reference in New Issue
Block a user