mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 10:08:34 +00:00
feat: add screen-watcher
This commit is contained in:
parent
9cb70a4d59
commit
ea5e7f81ce
4 changed files with 197 additions and 6 deletions
|
|
@ -11,7 +11,11 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<iframe src="./main.html" frameBorder="0" class="preview"
|
||||
width="500", height="500"></iframe>
|
||||
<!-- <iframe src="./main.html"
|
||||
frameBorder="0" class="preview" width="500", height="500"></iframe> -->
|
||||
|
||||
<iframe src="http://127.0.0.1:8081/packages/board/examples/features/main.html"
|
||||
frameBorder="0" class="preview"
|
||||
width="600", height="500"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -3,6 +3,14 @@
|
|||
<style></style>
|
||||
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
|
||||
<style>
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
background: #f0f0f088;
|
||||
}
|
||||
#mount {
|
||||
margin-top: 50px;
|
||||
margin-left: 60px;
|
||||
}
|
||||
#mount canvas {
|
||||
border-right: 1px solid #aaaaaa40;
|
||||
border-bottom: 1px solid #aaaaaa40;
|
||||
|
|
@ -12,6 +20,7 @@
|
|||
linear-gradient(#aaa 1px, transparent 0),
|
||||
linear-gradient(90deg, #aaa 1px, transparent 0);
|
||||
background-size: 10px 10px, 10px 10px, 50px 50px, 50px 50px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
|
@ -52,5 +61,11 @@
|
|||
|
||||
<script src="./../../dist/index.global.js"></script>
|
||||
<script type="module" src="./main.js"></script>
|
||||
<script>
|
||||
// console.log(parent.window.location);
|
||||
// parent.document.addEventListener('click', (e) => {
|
||||
// console.log('xxxxxxx: ', e);
|
||||
// })
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2,7 +2,8 @@ import {
|
|||
TypeScreenPosition, TypeScreenSize, TypeScreenContext, TypePoint, TypePointCursor,
|
||||
TypeBoardOptions, TypeBoardSizeOptions, } from '@idraw/types';
|
||||
import util from '@idraw/util';
|
||||
import { Watcher } from './lib/watcher';
|
||||
// import { Watcher } from './lib/watcher';
|
||||
import { ScreenWatcher } from './lib/screen-watcher';
|
||||
import { setStyle } from './lib/style';
|
||||
import Context from './lib/context';
|
||||
import { TypeBoardEventArgMap } from './lib/event';
|
||||
|
|
@ -31,7 +32,8 @@ class Board {
|
|||
private [_ctx]: Context;
|
||||
private [_displayCtx]: CanvasRenderingContext2D;
|
||||
private [_originCtx]: CanvasRenderingContext2D;
|
||||
private [_watcher]: Watcher;
|
||||
// private [_watcher]: Watcher;
|
||||
private [_watcher]: ScreenWatcher;
|
||||
private [_scroller]: Scroller;
|
||||
private [_screen]: Screen;
|
||||
|
||||
|
|
@ -45,7 +47,8 @@ class Board {
|
|||
this[_displayCtx] = this[_displayCanvas].getContext('2d') as CanvasRenderingContext2D;
|
||||
this[_ctx] = new Context(this[_originCtx], this[_opts]);
|
||||
this[_screen] = new Screen(this[_ctx], this[_opts]);
|
||||
this[_watcher] = new Watcher(this[_displayCanvas]);
|
||||
// this[_watcher] = new Watcher(this[_displayCanvas]);
|
||||
this[_watcher] = new ScreenWatcher(this[_displayCanvas]);
|
||||
this[_scroller] = new Scroller(
|
||||
this[_displayCtx], {
|
||||
width: opts.width,
|
||||
|
|
@ -109,7 +112,8 @@ class Board {
|
|||
}
|
||||
|
||||
clear() {
|
||||
this[_displayCtx].clearRect(0, 0, this[_displayCanvas].width, this[_displayCanvas].height);
|
||||
this[_displayCtx].clearRect(0, 0, this[_canvas].width, this[_canvas].height)
|
||||
// this[_displayCtx].clearRect(0, 0, this[_displayCanvas].width, this[_displayCanvas].height);
|
||||
}
|
||||
|
||||
on<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
|
||||
|
|
|
|||
168
packages/board/src/lib/screen-watcher.ts
Normal file
168
packages/board/src/lib/screen-watcher.ts
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
import { TypePoint } from '@idraw/types';
|
||||
import { BoardEvent, TypeBoardEventArgMap } from './event';
|
||||
import { TempData } from './watcher-temp';
|
||||
|
||||
// const isInIframe = window.self === window.top;
|
||||
|
||||
export class ScreenWatcher {
|
||||
|
||||
private _canvas: HTMLCanvasElement;
|
||||
private _isMoving = false;
|
||||
// private _onMove?: TypeWatchCallback;
|
||||
// private _onMoveStart?: TypeWatchCallback;
|
||||
// private _onMoveEnd?: TypeWatchCallback;
|
||||
private _event: BoardEvent;
|
||||
private _temp: TempData = new TempData;
|
||||
private _container: HTMLElement | Window = window;
|
||||
|
||||
constructor(canvas: HTMLCanvasElement) {
|
||||
this._canvas = canvas;
|
||||
this._isMoving = false;
|
||||
this._initEvent();
|
||||
this._event = new BoardEvent;
|
||||
}
|
||||
|
||||
on<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void): void {
|
||||
this._event.on(name, callback);
|
||||
}
|
||||
|
||||
off<T extends keyof TypeBoardEventArgMap >(name: T, callback: (p: TypeBoardEventArgMap[T]) => void): void {
|
||||
this._event.off(name, callback);
|
||||
}
|
||||
|
||||
_initEvent(): void {
|
||||
const canvas = this._canvas;
|
||||
const container = this._container;
|
||||
container.addEventListener('mousemove', this._listenHover.bind(this), true);
|
||||
container.addEventListener('mousedown', this._listenMoveStart.bind(this), true);
|
||||
container.addEventListener('mousemove', this._listenMove.bind(this), true);
|
||||
container.addEventListener('mouseup', this._listenMoveEnd.bind(this), true);
|
||||
container.addEventListener('mouseleave', this._listenMoveEnd.bind(this), true);
|
||||
container.addEventListener('mouseleave', this._listenLeave.bind(this), true);
|
||||
container.addEventListener('click', this._listenClick.bind(this), true);
|
||||
|
||||
canvas.addEventListener('wheel', this._listenWheel.bind(this), true);
|
||||
|
||||
container.addEventListener('touchstart', this._listenMoveStart.bind(this), true);
|
||||
container.addEventListener('touchmove', this._listenMove.bind(this), true);
|
||||
container.addEventListener('touchend', this._listenMoveEnd.bind(this), true);
|
||||
}
|
||||
|
||||
_listenHover(e: MouseEvent|TouchEvent|Event): void {
|
||||
e.preventDefault();
|
||||
const p = this._getPosition(e as MouseEvent|TouchEvent);
|
||||
if (this._isVaildPoint(p)) {
|
||||
if (this._event.has('hover')) {
|
||||
this._event.trigger('hover', p);
|
||||
}
|
||||
}
|
||||
this._isMoving = true;
|
||||
}
|
||||
|
||||
_listenLeave(e: MouseEvent|TouchEvent|Event): void {
|
||||
e.preventDefault();
|
||||
if (this._event.has('leave')) {
|
||||
this._event.trigger('leave', undefined);
|
||||
}
|
||||
}
|
||||
|
||||
_listenMoveStart(e: MouseEvent|TouchEvent|Event): void {
|
||||
e.preventDefault();
|
||||
const p = this._getPosition(e as MouseEvent|TouchEvent);
|
||||
if (this._isVaildPoint(p)) {
|
||||
if (this._event.has('point')) {
|
||||
this._event.trigger('point', p);
|
||||
}
|
||||
if (this._event.has('moveStart')) {
|
||||
this._event.trigger('moveStart', p);
|
||||
}
|
||||
}
|
||||
this._isMoving = true;
|
||||
}
|
||||
|
||||
_listenMove(e: MouseEvent|TouchEvent|Event): void {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (this._event.has('move') && this._isMoving === true) {
|
||||
const p = this._getPosition(e as MouseEvent|TouchEvent);
|
||||
if (this._isVaildPoint(p)) {
|
||||
this._event.trigger('move', p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_listenMoveEnd(e: MouseEvent|TouchEvent|Event): void {
|
||||
e.preventDefault();
|
||||
if (this._event.has('moveEnd')) {
|
||||
const p = this._getPosition(e as MouseEvent|TouchEvent);
|
||||
if (this._isVaildPoint(p)) {
|
||||
this._event.trigger('moveEnd', p);
|
||||
}
|
||||
}
|
||||
this._isMoving = false;
|
||||
}
|
||||
|
||||
_listenWheel(e: WheelEvent) {
|
||||
e.preventDefault();
|
||||
if (this._event.has('wheelX') && (e.deltaX > 0 || e.deltaX < 0)) {
|
||||
this._event.trigger('wheelX', e.deltaX);
|
||||
}
|
||||
if (this._event.has('wheelY') && (e.deltaY > 0 || e.deltaY < 0)) {
|
||||
this._event.trigger('wheelY', e.deltaY);
|
||||
}
|
||||
}
|
||||
|
||||
_listenClick(e: MouseEvent|TouchEvent|Event) {
|
||||
e.preventDefault();
|
||||
const maxLimitTime = 500;
|
||||
const p = this._getPosition(e as MouseEvent|TouchEvent);
|
||||
const t = Date.now();
|
||||
if (this._isVaildPoint(p)) {
|
||||
const preClickPoint = this._temp.get('prevClickPoint');
|
||||
if (
|
||||
preClickPoint && (t - preClickPoint.t <= maxLimitTime)
|
||||
&& Math.abs(preClickPoint.x - p.x) <= 5
|
||||
&& Math.abs(preClickPoint.y - p.y) <= 5
|
||||
) {
|
||||
if (this._event.has('doubleClick')) {
|
||||
this._event.trigger('doubleClick', { x: p.x, y: p.y });
|
||||
}
|
||||
} else {
|
||||
this._temp.set('prevClickPoint', {x: p.x, y: p.y, t, })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_getPosition(e: MouseEvent|TouchEvent): TypePoint {
|
||||
const canvas = this._canvas;
|
||||
let x = 0;
|
||||
let y = 0;
|
||||
|
||||
// @ts-ignore
|
||||
if (e && e.touches && e.touches.length > 0) {
|
||||
// @ts-ignore
|
||||
const touch: Touch = e.touches[0];
|
||||
if (touch) {
|
||||
x = touch.clientX;
|
||||
y = touch.clientY;
|
||||
}
|
||||
} else {
|
||||
// @ts-ignore
|
||||
x = e.clientX;
|
||||
// @ts-ignore
|
||||
y = e.clientY;
|
||||
}
|
||||
|
||||
const p = {
|
||||
x: x - canvas.getBoundingClientRect().left,
|
||||
y: y - canvas.getBoundingClientRect().top,
|
||||
t: Date.now(),
|
||||
};
|
||||
return p;
|
||||
}
|
||||
|
||||
private _isVaildPoint(p: TypePoint): boolean {
|
||||
return ( p.x > 0 && p.y > 0);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue