mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 01:58:27 +00:00
feat: init core render
This commit is contained in:
parent
53935a884b
commit
d04cc215b4
12 changed files with 168 additions and 35 deletions
|
|
@ -9,7 +9,8 @@
|
|||
"init": "lerna bootstrap --npm-client=cnpm",
|
||||
"clear": "rm -rf ./packages/*/dist/ & rm -rf ./packages/*/node_modules/",
|
||||
"jest": "jest --config jest.config.js",
|
||||
"test": "lerna bootstrap --no-ci && npm run build && npm run jest && npm run e2e"
|
||||
"test": "lerna bootstrap --no-ci && npm run build && npm run jest && npm run e2e",
|
||||
"serve": "http-server ./"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.14",
|
||||
|
|
|
|||
|
|
@ -9,6 +9,4 @@ const core = new Core(mount, {
|
|||
devicePixelRatio: 4
|
||||
});
|
||||
core.setData(data);
|
||||
core.draw();
|
||||
|
||||
console.log('hello world =', Core);
|
||||
core.draw();
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { TypeData } from '@idraw/types';
|
||||
import Board from '@idraw/board';
|
||||
import Renderer from './lib/renderer';
|
||||
|
||||
type Options = {
|
||||
width: number;
|
||||
|
|
@ -12,31 +13,17 @@ class Core {
|
|||
private _board: Board;
|
||||
private _data: TypeData;
|
||||
private _opts: Options;
|
||||
private _renderer: Renderer;
|
||||
|
||||
constructor(mount: HTMLDivElement, opts: Options) {
|
||||
this._data = { elements: [] };
|
||||
this._opts = opts;
|
||||
this._board = new Board(mount, this._opts);
|
||||
this._renderer = new Renderer(this._board);
|
||||
}
|
||||
|
||||
draw() {
|
||||
const board = this._board;
|
||||
const ctx = board.getContext();
|
||||
const data = this.getData();
|
||||
const { width, height } = this._opts;
|
||||
board.clear();
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.setFillStyle('#ffffff');
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
data.elements.forEach(ele => {
|
||||
// @ts-ignore
|
||||
if (ele.type === 'rect' && typeof ele.desc.color === 'string') {
|
||||
// @ts-ignore
|
||||
ctx.setFillStyle(ele.desc.color);
|
||||
}
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
});
|
||||
board.draw();
|
||||
this._renderer.render(this._data);
|
||||
}
|
||||
|
||||
getData() {
|
||||
|
|
|
|||
22
packages/core/src/lib/draw.ts
Normal file
22
packages/core/src/lib/draw.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { TypeContext, TypeData, TypeElement, TypeElemDesc } from '@idraw/types';
|
||||
|
||||
export function drawContext(ctx: TypeContext, data: TypeData) {
|
||||
for (let i = 0; i < data.elements.length; i++) {
|
||||
const ele = data.elements[i];
|
||||
switch (ele.type) {
|
||||
case 'rect': {
|
||||
drawRect<'rect'>(ctx, ele as TypeElement<'rect'>);
|
||||
};
|
||||
default: {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function drawRect<T extends keyof TypeElemDesc>(ctx: TypeContext, ele: TypeElement<T>) {
|
||||
const desc = ele.desc as TypeElemDesc['rect'];
|
||||
ctx.setFillStyle(desc.color);
|
||||
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||
}
|
||||
21
packages/core/src/lib/renderer.ts
Normal file
21
packages/core/src/lib/renderer.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { TypeContext, TypeData } from '@idraw/types';
|
||||
import { drawContext } from './draw';
|
||||
import Board from '@idraw/board';
|
||||
|
||||
export default class Renderer {
|
||||
|
||||
private _board: Board;
|
||||
private _ctx: TypeContext;
|
||||
private _data: TypeData = { elements: [] };
|
||||
|
||||
constructor(board: Board) {
|
||||
this._board = board;
|
||||
this._ctx = this._board.getContext();
|
||||
}
|
||||
|
||||
render(data: TypeData) {
|
||||
this._data = data;
|
||||
drawContext(this._ctx, this._data);
|
||||
this._board.draw();
|
||||
}
|
||||
}
|
||||
7
packages/core/src/util/color.ts
Normal file
7
packages/core/src/util/color.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export function toColorHexNum(color: string): number {
|
||||
return parseInt(color.replace(/^\#/, '0x'));
|
||||
}
|
||||
|
||||
export function toColorHexStr(color: number): string {
|
||||
return '#' + color.toString(16);
|
||||
}
|
||||
16
packages/core/src/util/file.ts
Normal file
16
packages/core/src/util/file.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
type ImageType = 'image/jpeg' | 'image/png';
|
||||
|
||||
export function downloadImageFromCanvas (
|
||||
canvas: HTMLCanvasElement,
|
||||
opts: { filename: string, type: ImageType }
|
||||
) {
|
||||
const { filename, type = 'image/jpeg' } = opts;
|
||||
const stream = canvas.toDataURL(type);
|
||||
const downloadLink = document.createElement('a');
|
||||
downloadLink.href = stream;
|
||||
downloadLink.download = filename;
|
||||
const downloadClickEvent = document.createEvent('MouseEvents');
|
||||
downloadClickEvent.initEvent('click', true, false);
|
||||
downloadLink.dispatchEvent(downloadClickEvent);
|
||||
}
|
||||
22
packages/core/src/util/index.ts
Normal file
22
packages/core/src/util/index.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { loadImage } from './loader';
|
||||
import { delay, compose, throttle } from './time';
|
||||
import { downloadImageFromCanvas } from './file';
|
||||
import { toColorHexStr, toColorHexNum } from './color';
|
||||
|
||||
export default {
|
||||
time: {
|
||||
delay,
|
||||
compose,
|
||||
throttle,
|
||||
},
|
||||
loader: {
|
||||
loadImage
|
||||
},
|
||||
file: {
|
||||
downloadImageFromCanvas,
|
||||
},
|
||||
color: {
|
||||
toColorHexStr,
|
||||
toColorHexNum,
|
||||
}
|
||||
}
|
||||
13
packages/core/src/util/loader.ts
Normal file
13
packages/core/src/util/loader.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
|
||||
export function loadImage(src: string): Promise<HTMLImageElement> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image;
|
||||
img.onload = function() {
|
||||
resolve(img);
|
||||
};
|
||||
img.onabort = reject;
|
||||
img.onerror = reject;
|
||||
img.src = src;
|
||||
});
|
||||
}
|
||||
44
packages/core/src/util/time.ts
Normal file
44
packages/core/src/util/time.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
export function compose (middleware: Function[]) {
|
||||
return function (context: any, next?: Function) {
|
||||
// let index = -1;
|
||||
return dispatch(0);
|
||||
|
||||
function dispatch (i: number): Promise<any> {
|
||||
// index = i
|
||||
let fn = middleware[i]
|
||||
if (i === middleware.length && next) {
|
||||
fn = next;
|
||||
}
|
||||
if (!fn) return Promise.resolve()
|
||||
try {
|
||||
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
|
||||
} catch (err) {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function delay(time: number): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve();
|
||||
}, time);
|
||||
})
|
||||
}
|
||||
|
||||
export function throttle(fn: Function, timeout: number) {
|
||||
let timer: any = -1;
|
||||
return function(...args: any[]) {
|
||||
if (timer > 0) {
|
||||
return;
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn(...args);
|
||||
timer = -1;
|
||||
}, timeout)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,21 +1,12 @@
|
|||
import { TypeElementsDesc } from './element';
|
||||
import { TypeElemDesc, TypeElement } from './element';
|
||||
|
||||
|
||||
type TypeDataElement<T extends keyof TypeElementsDesc> = {
|
||||
uuid?: string;
|
||||
x: number;
|
||||
y: number;
|
||||
w: number;
|
||||
h: number;
|
||||
type: T;
|
||||
desc: TypeElementsDesc[T];
|
||||
}
|
||||
|
||||
type TypeData = {
|
||||
elements: TypeDataElement<keyof TypeElementsDesc>[]
|
||||
elements: TypeElement<keyof TypeElemDesc>[]
|
||||
selectedElements?: string[] // uuids
|
||||
}
|
||||
|
||||
export {
|
||||
TypeDataElement,
|
||||
TypeData
|
||||
}
|
||||
|
|
@ -1,6 +1,16 @@
|
|||
import { TypePaintData } from './paint';
|
||||
|
||||
type TypeElementsDesc = {
|
||||
type TypeElement<T extends keyof TypeElemDesc> = {
|
||||
uuid?: string;
|
||||
x: number;
|
||||
y: number;
|
||||
w: number;
|
||||
h: number;
|
||||
type: T;
|
||||
desc: TypeElemDesc[T];
|
||||
}
|
||||
|
||||
type TypeElemDesc = {
|
||||
text: TypeElemDescText,
|
||||
rect: TypeElemDescRect,
|
||||
circle: TypeElemDescCircle,
|
||||
|
|
@ -33,5 +43,6 @@ export {
|
|||
TypeElemDescText,
|
||||
TypeElemDescRect,
|
||||
TypeElemDescCircle,
|
||||
TypeElementsDesc,
|
||||
TypeElemDesc,
|
||||
TypeElement,
|
||||
}
|
||||
Loading…
Reference in a new issue