mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
chore: update board/example
This commit is contained in:
parent
dcf5fae055
commit
3494deec19
11 changed files with 192 additions and 77 deletions
36
packages/board/example/features/lib/action.js
Normal file
36
packages/board/example/features/lib/action.js
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { getData } from "./data.js";
|
||||||
|
import { drawData } from './draw.js';
|
||||||
|
|
||||||
|
function isPointInElement(board, p = {x, y}) {
|
||||||
|
const ctx = board.getContext();
|
||||||
|
const data = getData();
|
||||||
|
let idx = -1;
|
||||||
|
for (let i = data.elements.length - 1; i >= 0; i--) {
|
||||||
|
const ele = data.elements[i];
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.lineTo(ele.x, ele.y);
|
||||||
|
ctx.lineTo(ele.x + ele.w, ele.y);
|
||||||
|
ctx.lineTo(ele.x + ele.w, ele.y + ele.h);
|
||||||
|
ctx.lineTo(ele.x, ele.y + ele.h);
|
||||||
|
ctx.closePath();
|
||||||
|
if (ctx.isPointInPath(p.x, p.y)) {
|
||||||
|
idx = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveElement(board, idx, moveX, moveY) {
|
||||||
|
const data = getData();
|
||||||
|
if (data.elements[idx]) {
|
||||||
|
data.elements[idx].x += moveX;
|
||||||
|
data.elements[idx].y += moveY;
|
||||||
|
}
|
||||||
|
drawData(board)
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
isPointInElement,
|
||||||
|
moveElement,
|
||||||
|
}
|
||||||
53
packages/board/example/features/lib/data.js
Normal file
53
packages/board/example/features/lib/data.js
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
elements: [
|
||||||
|
{
|
||||||
|
x: 10,
|
||||||
|
y: 10,
|
||||||
|
w: 200,
|
||||||
|
h: 120,
|
||||||
|
type: 'rect',
|
||||||
|
desc: {
|
||||||
|
color: '#f0f0f0',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: 80,
|
||||||
|
y: 80,
|
||||||
|
w: 200,
|
||||||
|
h: 120,
|
||||||
|
type: 'rect',
|
||||||
|
desc: {
|
||||||
|
color: '#cccccc',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: 160,
|
||||||
|
y: 160,
|
||||||
|
w: 200,
|
||||||
|
h: 120,
|
||||||
|
type: 'rect',
|
||||||
|
desc: {
|
||||||
|
color: '#c0c0c0',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: 400 - 10,
|
||||||
|
y: 300 - 10,
|
||||||
|
w: 200,
|
||||||
|
h: 100,
|
||||||
|
type: 'rect',
|
||||||
|
desc: {
|
||||||
|
color: '#e0e0e0',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
getData
|
||||||
|
};
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
export function draw(board) {
|
import opts from './opts.js';
|
||||||
|
import { getData } from './data.js';
|
||||||
|
|
||||||
|
export function drawData(board) {
|
||||||
const ctx = board.getContext();
|
const ctx = board.getContext();
|
||||||
|
const data = getData();
|
||||||
ctx.setFillStyle('#f0f0f0');
|
board.clear();
|
||||||
ctx.fillRect(10, 10, 200, 120);
|
ctx.clearRect(0, 0, opts.width, opts.height);
|
||||||
|
data.elements.forEach(ele => {
|
||||||
ctx.setFillStyle('#cccccc');
|
ctx.setFillStyle(ele.desc.color);
|
||||||
ctx.fillRect(80, 80, 200, 120);
|
ctx.fillRect(ele.x, ele.y, ele.w, ele.h);
|
||||||
|
});
|
||||||
ctx.setFillStyle('#c0c0c0');
|
|
||||||
ctx.fillRect(160, 160, 200, 120);
|
|
||||||
|
|
||||||
ctx.setFillStyle('#e0e0e0');
|
|
||||||
ctx.fillRect(400 - 10, 300 - 10, 200, 100);
|
|
||||||
|
|
||||||
board.draw();
|
board.draw();
|
||||||
}
|
}
|
||||||
24
packages/board/example/features/lib/event.js
Normal file
24
packages/board/example/features/lib/event.js
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { isPointInElement, moveElement } from './action.js';
|
||||||
|
|
||||||
|
let selectIdx = -1;
|
||||||
|
let prevPoint = { x: null, y: null };
|
||||||
|
|
||||||
|
export function initEvent(board) {
|
||||||
|
|
||||||
|
board.on('point', (p) => {
|
||||||
|
selectIdx = isPointInElement(board, p);
|
||||||
|
});
|
||||||
|
|
||||||
|
board.on('move', (p) => {
|
||||||
|
moveElement(board, selectIdx, p.x - prevPoint.x, p.y - prevPoint.y);
|
||||||
|
prevPoint = p;
|
||||||
|
});
|
||||||
|
|
||||||
|
board.on('moveStart', (p) => {
|
||||||
|
prevPoint = p;
|
||||||
|
});
|
||||||
|
|
||||||
|
board.on('moveEnd', (p) => {
|
||||||
|
selectIdx = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
5
packages/board/example/features/lib/opts.js
Normal file
5
packages/board/example/features/lib/opts.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export default {
|
||||||
|
width: 600,
|
||||||
|
height: 400,
|
||||||
|
devicePixelRatio: 4
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const input = document.querySelector('#scale');
|
const input = document.querySelector('#scale');
|
||||||
let hasInited = false;
|
let hasInited = false;
|
||||||
|
|
||||||
export function onScale(board) {
|
export function doScale(board) {
|
||||||
if (hasInited === true) return;
|
if (hasInited === true) return;
|
||||||
input.addEventListener('change', () => {
|
input.addEventListener('change', () => {
|
||||||
const val = input.value * 1;
|
const val = input.value * 1;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const inputX = document.querySelector('#scrollX');
|
||||||
const inputY = document.querySelector('#scrollY');
|
const inputY = document.querySelector('#scrollY');
|
||||||
let hasInited = false;
|
let hasInited = false;
|
||||||
|
|
||||||
export function onScroll(board) {
|
export function doScroll(board) {
|
||||||
if (hasInited === true) return;
|
if (hasInited === true) return;
|
||||||
inputX.addEventListener('change', () => {
|
inputX.addEventListener('change', () => {
|
||||||
const val = inputX.value * 1;
|
const val = inputX.value * 1;
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
import { draw } from './lib/draw.js';
|
import opts from './lib/opts.js';
|
||||||
import { onScale } from './lib/scale.js';
|
import { drawData } from './lib/draw.js';
|
||||||
import { onScroll } from './lib/scroll.js';
|
import { doScale } from './lib/scale.js';
|
||||||
|
import { doScroll } from './lib/scroll.js';
|
||||||
|
import { initEvent } from './lib/event.js';
|
||||||
|
|
||||||
const { Board } = window.iDraw;
|
const { Board } = window.iDraw;
|
||||||
|
|
||||||
const mount = document.querySelector('#mount');
|
const mount = document.querySelector('#mount');
|
||||||
const board = new Board(mount, {
|
const board = new Board(mount, opts);
|
||||||
width: 600,
|
|
||||||
height: 400,
|
drawData(board);
|
||||||
devicePixelRatio: 4
|
|
||||||
});
|
initEvent(board);
|
||||||
|
doScale(board);
|
||||||
|
doScroll(board);
|
||||||
|
|
||||||
draw(board);
|
|
||||||
onScale(board);
|
|
||||||
onScroll(board);
|
|
||||||
|
|
||||||
// board.scale(2);
|
// board.scale(2);
|
||||||
// board.draw();
|
// board.draw();
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
// import { TypePoint } from '@idraw/types';
|
// import { TypePoint } from '@idraw/types';
|
||||||
// import { Watcher } from './util/watcher';
|
import { Watcher } from './util/watcher';
|
||||||
import { setStyle } from './util/style';
|
import { setStyle } from './util/style';
|
||||||
import Context from './util/context';
|
import Context from './util/context';
|
||||||
|
import { TypeBoardEventArgMap } from './util/event';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
width: number;
|
width: number;
|
||||||
|
|
@ -24,7 +25,7 @@ class Board {
|
||||||
private _scaleRatio: number = 1;
|
private _scaleRatio: number = 1;
|
||||||
private _scrollX: number = 0;
|
private _scrollX: number = 0;
|
||||||
private _scrollY: number = 0;
|
private _scrollY: number = 0;
|
||||||
// private _watcher: Watcher;
|
private _watcher: Watcher;
|
||||||
|
|
||||||
constructor(mount: HTMLDivElement, opts: Options) {
|
constructor(mount: HTMLDivElement, opts: Options) {
|
||||||
this._mount = mount;
|
this._mount = mount;
|
||||||
|
|
@ -36,7 +37,8 @@ class Board {
|
||||||
const displayCtx = this._displayCanvas.getContext('2d') as CanvasRenderingContext2D;
|
const displayCtx = this._displayCanvas.getContext('2d') as CanvasRenderingContext2D;
|
||||||
this._ctx = new Context(ctx, this._opts);
|
this._ctx = new Context(ctx, this._opts);
|
||||||
this._displayCtx = displayCtx;
|
this._displayCtx = displayCtx;
|
||||||
// this._watcher = new Watcher(this._canvas);
|
this._watcher = new Watcher(this._displayCanvas);
|
||||||
|
|
||||||
this._render();
|
this._render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,6 +68,14 @@ class Board {
|
||||||
this._displayCtx.clearRect(0, 0, this._displayCanvas.width, this._displayCanvas.height)
|
this._displayCtx.clearRect(0, 0, this._displayCanvas.width, this._displayCanvas.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
|
||||||
|
this._watcher.on(name, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
off<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
|
||||||
|
this._watcher.off(name, callback)
|
||||||
|
}
|
||||||
|
|
||||||
private _render() {
|
private _render() {
|
||||||
if (this._hasRendered === true) {
|
if (this._hasRendered === true) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -104,7 +114,6 @@ class Board {
|
||||||
size.h = height * pxRatio * _scaleRatio;
|
size.h = height * pxRatio * _scaleRatio;
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ class Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
isPointInPath(x: number, y: number) {
|
isPointInPath(x: number, y: number) {
|
||||||
return this._ctx.lineTo(this._doSize(x), this._doSize(y));
|
return this._ctx.isPointInPath(this._doSize(x), this._doSize(y));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _doSize(num: number) {
|
private _doSize(num: number) {
|
||||||
|
|
|
||||||
|
|
@ -1,94 +1,84 @@
|
||||||
import { TypePoint } from '@idraw/types';
|
import { TypePoint } from '@idraw/types';
|
||||||
|
import { BoardEvent, TypeBoardEventArgMap } from './event';
|
||||||
interface TypeWatcher {
|
|
||||||
onMove(callback: TypeWatchCallback): void,
|
|
||||||
onMoveEnd(callback: TypeWatchCallback): void,
|
|
||||||
onMoveEnd(callback: TypeWatchCallback): void,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
type TypeWatchCallback = (p: TypePoint) => void
|
export class Watcher {
|
||||||
|
|
||||||
export class Watcher implements TypeWatcher {
|
|
||||||
|
|
||||||
private _canvas: HTMLCanvasElement;
|
private _canvas: HTMLCanvasElement;
|
||||||
private _isPainting: boolean = false;
|
private _isMoving: boolean = false;
|
||||||
private _onMove?: TypeWatchCallback;
|
// private _onMove?: TypeWatchCallback;
|
||||||
private _onMoveStart?: TypeWatchCallback;
|
// private _onMoveStart?: TypeWatchCallback;
|
||||||
private _onMoveEnd?: TypeWatchCallback;
|
// private _onMoveEnd?: TypeWatchCallback;
|
||||||
|
private _event: BoardEvent;
|
||||||
|
|
||||||
constructor(canvas: HTMLCanvasElement) {
|
constructor(canvas: HTMLCanvasElement) {
|
||||||
this._canvas = canvas;
|
this._canvas = canvas;
|
||||||
this._isPainting = false;
|
this._isMoving = false;
|
||||||
this._initEvent();
|
this._initEvent();
|
||||||
|
this._event = new BoardEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMove(callback: TypeWatchCallback) {
|
on<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
|
||||||
this._onMove = callback;
|
this._event.on(name, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMoveEnd(callback: TypeWatchCallback) {
|
off<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
|
||||||
this._onMoveEnd = callback;
|
this._event.off(name, callback)
|
||||||
}
|
|
||||||
|
|
||||||
onMoveStart(callback: TypeWatchCallback) {
|
|
||||||
this._onMoveStart = callback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_initEvent() {
|
_initEvent() {
|
||||||
const canvas = this._canvas;
|
const canvas = this._canvas;
|
||||||
canvas.addEventListener('mousedown', this._listenStart.bind(this));
|
canvas.addEventListener('mousedown', this._listenMoveStart.bind(this));
|
||||||
canvas.addEventListener('mousemove', this._listenMove.bind(this));
|
canvas.addEventListener('mousemove', this._listenMove.bind(this));
|
||||||
canvas.addEventListener('mouseup', this._listenEnd.bind(this));
|
canvas.addEventListener('mouseup', this._listenMoveEnd.bind(this));
|
||||||
|
|
||||||
canvas.addEventListener('touchstart', this._listenStart.bind(this));
|
canvas.addEventListener('touchstart', this._listenMoveStart.bind(this));
|
||||||
canvas.addEventListener('touchmove', this._listenMove.bind(this));
|
canvas.addEventListener('touchmove', this._listenMove.bind(this));
|
||||||
canvas.addEventListener('touchend', this._listenEnd.bind(this));
|
canvas.addEventListener('touchend', this._listenMoveEnd.bind(this));
|
||||||
|
|
||||||
const mouseupEvent = new MouseEvent('mouseup');
|
const mouseupEvent = new MouseEvent('mouseup');
|
||||||
document.querySelector('body')?.addEventListener('mousemove', (e) => {
|
document.querySelector('body')?.addEventListener('mousemove', (e) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (e && e.path && e.path[0] !== canvas) {
|
if (e && e.path && e.path[0] !== canvas) {
|
||||||
if (this._isPainting === true) {
|
canvas.dispatchEvent(mouseupEvent);
|
||||||
canvas.dispatchEvent(mouseupEvent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, false)
|
}, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenStart(e: MouseEvent|TouchEvent) {
|
_listenMoveStart(e: MouseEvent|TouchEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._isPainting = true;
|
const p = this._getPosition(e);
|
||||||
if (typeof this._onMoveStart === 'function') {
|
if (this._isVaildPoint(p)) {
|
||||||
const p = this._getPosition(e);
|
if (this._event.has('point')) {
|
||||||
if (this._isVaildPoint(p)) {
|
this._event.trigger('point', p);
|
||||||
this._onMoveStart(p);
|
}
|
||||||
|
if (this._event.has('moveStart')) {
|
||||||
|
this._event.trigger('moveStart', p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this._isMoving = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenMove(e: MouseEvent|TouchEvent) {
|
_listenMove(e: MouseEvent|TouchEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (this._isPainting === true) {
|
if (this._event.has('move') && this._isMoving === true) {
|
||||||
if (typeof this._onMove === 'function') {
|
const p = this._getPosition(e);
|
||||||
const p = this._getPosition(e);
|
if (this._isVaildPoint(p)) {
|
||||||
if (this._isVaildPoint(p)) {
|
this._event.trigger('move', p);
|
||||||
this._onMove(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_listenEnd(e: MouseEvent|TouchEvent) {
|
_listenMoveEnd(e: MouseEvent|TouchEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._isPainting = false;
|
if (this._event.has('moveEnd')) {
|
||||||
if (typeof this._onMoveEnd === 'function') {
|
|
||||||
const p = this._getPosition(e);
|
const p = this._getPosition(e);
|
||||||
if (this._isVaildPoint(p)) {
|
if (this._isVaildPoint(p)) {
|
||||||
this._onMoveEnd(p);
|
this._event.trigger('moveEnd', p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this._isMoving = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_getPosition(e: MouseEvent|TouchEvent) {
|
_getPosition(e: MouseEvent|TouchEvent) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue