mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 01:58:27 +00:00
feat: rename board
This commit is contained in:
parent
f242fe28da
commit
8689dae54c
17 changed files with 375 additions and 21 deletions
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"packages": [
|
||||
"packages/types",
|
||||
"packages/canvas",
|
||||
"packages/board",
|
||||
"packages/idraw"
|
||||
],
|
||||
"version": "0.0.1"
|
||||
"version": "0.0.3"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
<style></style>
|
||||
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
<style>
|
||||
#drag canvas {
|
||||
#mount canvas {
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="drag"></div>
|
||||
<div id="mount"></div>
|
||||
|
||||
<script src="./../dist/index.global.js"></script>
|
||||
<script src="./main.js"></script>
|
||||
9
packages/board/example/main.js
Normal file
9
packages/board/example/main.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
const { Board } = window.iDraw;
|
||||
|
||||
const mount = document.querySelector('#mount');
|
||||
const board = new Board(mount, {
|
||||
width: 600,
|
||||
height: 400,
|
||||
devicePixelRatio: 4
|
||||
});
|
||||
board.render();
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@idraw/canvas",
|
||||
"version": "0.0.1",
|
||||
"name": "@idraw/board",
|
||||
"version": "0.0.3",
|
||||
"description": "",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.es.js",
|
||||
64
packages/board/src/index.ts
Normal file
64
packages/board/src/index.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// import { TypePoint } from '@idraw/types';
|
||||
import { setStyle } from './util/style';
|
||||
// import { Watcher } from './util/watcher';
|
||||
|
||||
type Options = {
|
||||
width: number;
|
||||
height: number;
|
||||
devicePixelRatio?: number;
|
||||
}
|
||||
|
||||
type PrivateOptions = Options & {
|
||||
devicePixelRatio: number
|
||||
}
|
||||
|
||||
class Drag {
|
||||
private _canvas: HTMLCanvasElement;
|
||||
private _mount: HTMLDivElement;
|
||||
private _opts: PrivateOptions;
|
||||
private _hasRendered: boolean = false;
|
||||
// private _watcher: Watcher;
|
||||
|
||||
constructor(mount: HTMLDivElement, opts: Options) {
|
||||
this._mount = mount;
|
||||
this._canvas = document.createElement('canvas');
|
||||
this._mount.appendChild(this._canvas);
|
||||
this._opts = this._parsePrivateOptions(opts);
|
||||
// this._watcher = new Watcher(this._canvas);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this._hasRendered === true) {
|
||||
return;
|
||||
}
|
||||
const { width, height, devicePixelRatio } = this._opts;
|
||||
this._canvas.width = width * devicePixelRatio;
|
||||
this._canvas.height = height * devicePixelRatio;
|
||||
setStyle(this._canvas, {
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
});
|
||||
// this._watcher.onMove(this._onMove.bind(this));
|
||||
// this._watcher.onMoveStart(this._onMoveStart.bind(this));
|
||||
// this._watcher.onMoveEnd(this._onMoveEnd.bind(this));
|
||||
// this._hasRendered = true;
|
||||
}
|
||||
|
||||
draw() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
|
||||
private _parsePrivateOptions(opts: Options): PrivateOptions {
|
||||
const defaultOpts = {
|
||||
devicePixelRatio: 1,
|
||||
}
|
||||
return { ...defaultOpts, ...opts }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default Drag;
|
||||
|
||||
59
packages/board/src/util/istype.ts
Normal file
59
packages/board/src/util/istype.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
function parsePrototype (data: any) {
|
||||
const typeStr = Object.prototype.toString.call(data) || '';
|
||||
const result = typeStr.replace(/(\[object|\])/ig, '').trim();
|
||||
return result;
|
||||
};
|
||||
const istype = {
|
||||
|
||||
type(data: any, lowerCase?: boolean) {
|
||||
let result = parsePrototype(data);
|
||||
return lowerCase === true ? result.toLocaleLowerCase() : result;
|
||||
},
|
||||
|
||||
array (data: any) {
|
||||
return parsePrototype(data) === 'Array';
|
||||
},
|
||||
|
||||
json (data: any) {
|
||||
return parsePrototype(data) === 'Object';
|
||||
},
|
||||
|
||||
function (data: any) {
|
||||
return parsePrototype(data) === 'Function';
|
||||
},
|
||||
|
||||
asyncFunction (data: any) {
|
||||
return parsePrototype(data) === 'AsyncFunction';
|
||||
},
|
||||
|
||||
string (data: any) {
|
||||
return parsePrototype(data) === 'String';
|
||||
},
|
||||
|
||||
number (data: any) {
|
||||
return parsePrototype(data) === 'Number';
|
||||
},
|
||||
|
||||
undefined (data: any) {
|
||||
return parsePrototype(data) === 'Undefined';
|
||||
},
|
||||
|
||||
null (data: any) {
|
||||
return parsePrototype(data) === 'Null';
|
||||
},
|
||||
|
||||
promise (data: any) {
|
||||
return parsePrototype(data) === 'Promise';
|
||||
},
|
||||
|
||||
nodeList (data: any) {
|
||||
return parsePrototype(data) === 'NodeList';
|
||||
},
|
||||
|
||||
imageData(data: any) {
|
||||
return parsePrototype(data) === 'ImageData';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default istype;
|
||||
94
packages/board/src/util/style.ts
Normal file
94
packages/board/src/util/style.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import istype from './istype';
|
||||
|
||||
export const mergeCSS2StyleAttr = function(
|
||||
cssMap: {[key: string]: string} = {}
|
||||
): string {
|
||||
const cssList = [];
|
||||
if (istype.json(cssMap) === true) {
|
||||
for (const key in cssMap) {
|
||||
let cssKey: string = `${key}`;
|
||||
let cssVal: string = `${cssMap[key]}`;
|
||||
cssKey = cssKey.trim();
|
||||
cssVal = cssVal.trim();
|
||||
cssList.push(`${cssKey}:${cssVal}`);
|
||||
}
|
||||
}
|
||||
const styleAttr = cssList.join('; ');
|
||||
return styleAttr;
|
||||
}
|
||||
|
||||
|
||||
export function setStyle(
|
||||
dom: HTMLElement,
|
||||
style: {[key: string]: string} ) {
|
||||
const originStyle = getStyle(dom);
|
||||
const _style = {...originStyle, ...style}
|
||||
const keys: string[] = Object.keys(_style);
|
||||
let styleStr = '';
|
||||
keys.forEach((key: string) => {
|
||||
styleStr += `${key}:${_style[key] || ''};`
|
||||
});
|
||||
dom.setAttribute('style', styleStr);
|
||||
}
|
||||
|
||||
export function getStyle(dom: HTMLElement): {[key: string]: string} {
|
||||
const styleObj: {[key: string]: string} = {};
|
||||
const style = dom.getAttribute('style') || '';
|
||||
const styleList = style.split(';');
|
||||
styleList.forEach((item: string) => {
|
||||
const dataList = item.split(':');
|
||||
if (dataList[0] && typeof dataList[0] === 'string') {
|
||||
styleObj[dataList[0]] = dataList[1] || '';
|
||||
}
|
||||
})
|
||||
|
||||
return styleObj;
|
||||
}
|
||||
|
||||
export function getDomTransform(dom: HTMLElement): {
|
||||
scaleX: number;
|
||||
skewY: number;
|
||||
skewX: number;
|
||||
scaleY: number;
|
||||
translateX: number;
|
||||
translateY: number;
|
||||
} {
|
||||
// transform: matrix( scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY() )
|
||||
// matrix(1, 0, 0, 1, 0, 0)
|
||||
const style = getComputedStyle(dom) || {};
|
||||
const { transform } = style;
|
||||
const matrixStr = transform.replace(/^matrix\(|\)$/ig, '');
|
||||
const matrixList = matrixStr.split(',').map((str, i) => {
|
||||
const val = parseFloat(str);
|
||||
if ([0, 3].indexOf(i) >= 0) {
|
||||
return isNaN(val) ? 1 : val;
|
||||
} else {
|
||||
return isNaN(val) ? 0 : val;
|
||||
}
|
||||
});
|
||||
const matrix = {
|
||||
scaleX: matrixList[0],
|
||||
skewY: matrixList[1] || 0,
|
||||
skewX: matrixList[2] || 0,
|
||||
scaleY: matrixList[3] || 1,
|
||||
translateX: matrixList[4] || 0,
|
||||
translateY: matrixList[5] || 0,
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
|
||||
export function setDomTransform(dom: HTMLElement, matrix: {
|
||||
scaleX: number;
|
||||
skewY: number;
|
||||
skewX: number;
|
||||
scaleY: number;
|
||||
translateX: number;
|
||||
translateY: number;
|
||||
}) {
|
||||
// transform: matrix( scaleX(), skewY(), skewX(), scaleY(), translateX(), translateY() )
|
||||
// matrix(1, 2, -1, 1, 80, 80)
|
||||
|
||||
const transform = `matrix(${matrix.scaleX}, ${matrix.skewY}, ${matrix.skewX}, ${matrix.scaleY}, ${matrix.translateX}, ${matrix.translateY})`;
|
||||
dom.style.setProperty('transform', transform);
|
||||
}
|
||||
126
packages/board/src/util/watcher.ts
Normal file
126
packages/board/src/util/watcher.ts
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
type TypeDataPosition = {
|
||||
x: number,
|
||||
y: number,
|
||||
t: number,
|
||||
}
|
||||
|
||||
interface TypeWatcher {
|
||||
onMove(callback: TypeWatchCallback): void,
|
||||
onMoveEnd(callback: TypeWatchCallback): void,
|
||||
onMoveEnd(callback: TypeWatchCallback): void,
|
||||
}
|
||||
|
||||
|
||||
type TypeWatchCallback = (p: TypeDataPosition) => void
|
||||
|
||||
export class Watcher implements TypeWatcher {
|
||||
|
||||
private _canvas: HTMLCanvasElement;
|
||||
private _isPainting: boolean = false;
|
||||
private _onMove?: TypeWatchCallback;
|
||||
private _onMoveStart?: TypeWatchCallback;
|
||||
private _onMoveEnd?: TypeWatchCallback;
|
||||
|
||||
constructor(canvas: HTMLCanvasElement) {
|
||||
this._canvas = canvas;
|
||||
this._isPainting = false;
|
||||
this._initEvent();
|
||||
}
|
||||
|
||||
onMove(callback: TypeWatchCallback) {
|
||||
this._onMove = callback;
|
||||
}
|
||||
|
||||
onMoveEnd(callback: TypeWatchCallback) {
|
||||
this._onMoveEnd = callback;
|
||||
}
|
||||
|
||||
onMoveStart(callback: TypeWatchCallback) {
|
||||
this._onMoveStart = callback;
|
||||
}
|
||||
|
||||
_initEvent() {
|
||||
const canvas = this._canvas;
|
||||
canvas.addEventListener('mousedown', this._listenStart.bind(this));
|
||||
canvas.addEventListener('mousemove', this._listenMove.bind(this));
|
||||
canvas.addEventListener('mouseup', this._listenEnd.bind(this));
|
||||
|
||||
canvas.addEventListener('touchstart', this._listenStart.bind(this));
|
||||
canvas.addEventListener('touchmove', this._listenMove.bind(this));
|
||||
canvas.addEventListener('touchend', this._listenEnd.bind(this));
|
||||
|
||||
const mouseupEvent = new MouseEvent('mouseup');
|
||||
document.querySelector('body')?.addEventListener('mousemove', (e) => {
|
||||
// @ts-ignore
|
||||
if (e && e.path && e.path[0] !== canvas) {
|
||||
if (this._isPainting === true) {
|
||||
canvas.dispatchEvent(mouseupEvent);
|
||||
}
|
||||
}
|
||||
}, false)
|
||||
}
|
||||
|
||||
_listenStart(e: MouseEvent|TouchEvent) {
|
||||
e.preventDefault();
|
||||
this._isPainting = true;
|
||||
if (typeof this._onMoveStart === 'function') {
|
||||
const p = this._getPosition(e);
|
||||
if (this._isVaildPosition(p)) {
|
||||
this._onMoveStart(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_listenMove(e: MouseEvent|TouchEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (this._isPainting === true) {
|
||||
if (typeof this._onMove === 'function') {
|
||||
const p = this._getPosition(e);
|
||||
if (this._isVaildPosition(p)) {
|
||||
this._onMove(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_listenEnd(e: MouseEvent|TouchEvent) {
|
||||
e.preventDefault();
|
||||
this._isPainting = false;
|
||||
if (typeof this._onMoveEnd === 'function') {
|
||||
const p = this._getPosition(e);
|
||||
if (this._isVaildPosition(p)) {
|
||||
this._onMoveEnd(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getPosition(e: MouseEvent|TouchEvent) {
|
||||
const canvas = this._canvas;
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
|
||||
if (e instanceof TouchEvent) {
|
||||
const touch: Touch = e.touches[0];
|
||||
if (touch) {
|
||||
x = touch.clientX;
|
||||
y = touch.clientY;
|
||||
}
|
||||
} else {
|
||||
x = e.clientX;
|
||||
y = e.clientY;
|
||||
}
|
||||
|
||||
const p = {
|
||||
x: x - canvas.getBoundingClientRect().left,
|
||||
y: y - canvas.getBoundingClientRect().top,
|
||||
t: Date.now(),
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
private _isVaildPosition(p: TypeDataPosition) {
|
||||
return ( p.x > 0 && p.y > 0 && p.t > 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
console.log('hello world')
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
class Canvas {
|
||||
render() {
|
||||
console.log('hello world')
|
||||
}
|
||||
}
|
||||
|
||||
export default Canvas;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@idraw/canvas",
|
||||
"version": "0.0.1",
|
||||
"name": "idraw",
|
||||
"version": "0.0.3",
|
||||
"description": "",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.es.js",
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
export * from './lib/data';
|
||||
export * from './lib/data';
|
||||
export * from './lib/board';
|
||||
8
packages/types/src/lib/board.ts
Normal file
8
packages/types/src/lib/board.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
type TypePoint = {
|
||||
x: number;
|
||||
y: number;
|
||||
}
|
||||
|
||||
export {
|
||||
TypePoint
|
||||
}
|
||||
|
|
@ -1 +1,3 @@
|
|||
|
||||
|
||||
export {}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
module.exports = {
|
||||
packages: [
|
||||
{
|
||||
dirName: 'canvas',
|
||||
globalName: 'iDraw.Canvas',
|
||||
dirName: 'board',
|
||||
globalName: 'iDraw.Board',
|
||||
},
|
||||
{
|
||||
dirName: 'idraw',
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ const resolveFile = function(names = []) {
|
|||
}
|
||||
|
||||
const modules = [];
|
||||
const external = [ '@idraw/idraw-types'];
|
||||
const external = [ '@idraw/types'];
|
||||
|
||||
for(let i = 0; i < packages.length; i++) {
|
||||
const pkg = packages[i];
|
||||
|
|
|
|||
Loading…
Reference in a new issue