diff --git a/packages/board/examples/test/wheel.html b/packages/board/examples/test/wheel.html
new file mode 100644
index 0000000..fc26fa1
--- /dev/null
+++ b/packages/board/examples/test/wheel.html
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/board/src/index.ts b/packages/board/src/index.ts
index 837ec20..d6cb6e8 100644
--- a/packages/board/src/index.ts
+++ b/packages/board/src/index.ts
@@ -4,12 +4,28 @@ import { setStyle } from './util/style';
import Context from './util/context';
import { TypeBoardEventArgMap } from './util/event';
+
+const _canvas = Symbol('_canvas');
+const _displayCanvas = Symbol('_displayCanvas');
+const _mount = Symbol('_mount');
+const _opts = Symbol('_opts');
+const _hasRendered = Symbol('_hasRendered');
+const _ctx = Symbol('_ctx');
+const _displayCtx = Symbol('_displayCtx');
+const _originCtx = Symbol('_originCtx');
+const _watcher = Symbol('_watcher');
+const _render = Symbol('_render');
+const _calcScreen = Symbol('_calcScreen');
+const _parsePrivateOptions = Symbol('_parsePrivateOptions');
+
+
type Options = {
width: number;
height: number;
contextWidth: number;
contextHeight: number;
devicePixelRatio?: number;
+ canScroll?: boolean;
}
type PrivateOptions = Options & {
@@ -17,53 +33,50 @@ type PrivateOptions = Options & {
}
class Board {
- private _canvas: HTMLCanvasElement;
- private _displayCanvas: HTMLCanvasElement;
- private _mount: HTMLDivElement;
- private _opts: PrivateOptions;
- private _hasRendered = false;
- private _ctx: Context;
- private _displayCtx: CanvasRenderingContext2D;
- private _originCtx: CanvasRenderingContext2D;
- // private _scaleRatio = 1;
- // private _scrollX = 0;
- // private _scrollY = 0;
- private _watcher: Watcher;
+ private [_canvas]: HTMLCanvasElement;
+ private [_displayCanvas]: HTMLCanvasElement;
+ private [_mount]: HTMLDivElement;
+ private [_opts]: PrivateOptions;
+ private [_hasRendered] = false;
+ private [_ctx]: Context;
+ private [_displayCtx]: CanvasRenderingContext2D;
+ private [_originCtx]: CanvasRenderingContext2D;
+ private [_watcher]: Watcher;
constructor(mount: HTMLDivElement, opts: Options) {
- this._mount = mount;
- this._canvas = document.createElement('canvas');
- this._displayCanvas = document.createElement('canvas');
- this._mount.appendChild(this._displayCanvas);
- this._opts = this._parsePrivateOptions(opts);
- this._originCtx = this._canvas.getContext('2d') as CanvasRenderingContext2D;
- this._displayCtx = this._displayCanvas.getContext('2d') as CanvasRenderingContext2D;
- this._ctx = new Context(this._originCtx, this._opts);
- this._watcher = new Watcher(this._displayCanvas);
- this._render();
+ this[_mount] = mount;
+ this[_canvas] = document.createElement('canvas');
+ this[_displayCanvas] = document.createElement('canvas');
+ this[_mount].appendChild(this[_displayCanvas]);
+ this[_opts] = this[_parsePrivateOptions](opts);
+ this[_originCtx] = this[_canvas].getContext('2d') as CanvasRenderingContext2D;
+ this[_displayCtx] = this[_displayCanvas].getContext('2d') as CanvasRenderingContext2D;
+ this[_ctx] = new Context(this[_originCtx], this[_opts]);
+ this[_watcher] = new Watcher(this[_displayCanvas]);
+ this[_render]();
}
getDisplayContext(): CanvasRenderingContext2D {
- return this._displayCtx;
+ return this[_displayCtx];
}
getOriginContext(): CanvasRenderingContext2D {
- return this._displayCtx;
+ return this[_displayCtx];
}
getContext(): Context {
- return this._ctx;
+ return this[_ctx];
}
createContext(canvas: HTMLCanvasElement) {
- const opts = this._opts;
+ const opts = this[_opts];
canvas.width = opts.contextWidth * opts.devicePixelRatio;
canvas.height = opts.contextHeight * opts.devicePixelRatio;
- return new Context(canvas.getContext('2d') as CanvasRenderingContext2D, this._opts);
+ return new Context(canvas.getContext('2d') as CanvasRenderingContext2D, this[_opts]);
}
createCanvas() {
- const opts = this._opts;
+ const opts = this[_opts];
const canvas = document.createElement('canvas');
canvas.width = opts.contextWidth * opts.devicePixelRatio;
canvas.height = opts.contextHeight * opts.devicePixelRatio;
@@ -72,75 +85,72 @@ class Board {
scale(scaleRatio: number): TypeScreenContext {
if (scaleRatio > 0) {
- this._ctx.setTransform({ scale: scaleRatio });
+ this[_ctx].setTransform({ scale: scaleRatio });
}
- const { position, size } = this._calculateScreen();
+ const { position, size } = this[_calcScreen]();
return { position, size};
}
scrollX(x: number) {
if (x >= 0 || x < 0) {
- this._ctx.setTransform({ scrollX: x });
+ this[_ctx].setTransform({ scrollX: x });
}
- const { position, size } = this._calculateScreen();
+ const { position, size } = this[_calcScreen]();
return { position, size};
}
scrollY(y: number): TypeScreenContext {
if (y >= 0 || y < 0) {
- this._ctx.setTransform({ scrollY: y });
+ this[_ctx].setTransform({ scrollY: y });
}
- const { position, size } = this._calculateScreen();
+ const { position, size } = this[_calcScreen]();
return { position, size};
}
getTransform() {
- return this._ctx.getTransform();
+ return this[_ctx].getTransform();
}
draw(): TypeScreenContext {
this.clear();
- const { position, deviceSize, size } = this._calculateScreen();
- this._displayCtx.drawImage(
- this._canvas, deviceSize.x, deviceSize.y, deviceSize.w, deviceSize.h
+ const { position, deviceSize, size } = this[_calcScreen]();
+ this[_displayCtx].drawImage(
+ this[_canvas], deviceSize.x, deviceSize.y, deviceSize.w, deviceSize.h
);
return { position, size};
}
clear() {
- this._displayCtx.clearRect(0, 0, this._displayCanvas.width, this._displayCanvas.height);
+ this[_displayCtx].clearRect(0, 0, this[_displayCanvas].width, this[_displayCanvas].height);
}
on(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
- this._watcher.on(name, callback);
+ this[_watcher].on(name, callback);
}
off(name: T, callback: (p: TypeBoardEventArgMap[T]) => void) {
- this._watcher.off(name, callback);
+ this[_watcher].off(name, callback);
}
- private _render() {
- if (this._hasRendered === true) {
+ private [_render]() {
+ if (this[_hasRendered] === true) {
return;
}
- const { width, height, contextWidth, contextHeight, devicePixelRatio } = this._opts;
- this._canvas.width = contextWidth * devicePixelRatio;
- this._canvas.height = contextHeight * devicePixelRatio;
+ const { width, height, contextWidth, contextHeight, devicePixelRatio } = this[_opts];
+ this[_canvas].width = contextWidth * devicePixelRatio;
+ this[_canvas].height = contextHeight * devicePixelRatio;
- this._displayCanvas.width = width * devicePixelRatio;
- this._displayCanvas.height = height * devicePixelRatio;
+ this[_displayCanvas].width = width * devicePixelRatio;
+ this[_displayCanvas].height = height * devicePixelRatio;
- setStyle(this._displayCanvas, {
+ setStyle(this[_displayCanvas], {
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;
+ this[_hasRendered] = true;
}
- private _parsePrivateOptions(opts: Options): PrivateOptions {
+ private [_parsePrivateOptions](opts: Options): PrivateOptions {
const defaultOpts = {
devicePixelRatio: 1,
};
@@ -148,59 +158,59 @@ class Board {
}
- private _calculateScreen(): {
+ private [_calcScreen](): {
size: TypeScreenSize,
position: TypeScreenPosition,
deviceSize: TypeScreenSize,
} {
- const scaleRatio = this._ctx.getTransform().scale;
+ const scaleRatio = this[_ctx].getTransform().scale;
const {
width, height, contextWidth, contextHeight,
devicePixelRatio: pxRatio,
- } = this._opts;
+ } = this[_opts];
// init scroll
if (contextWidth * scaleRatio <= width) {
// make context center
- this._ctx.setTransform({
+ this[_ctx].setTransform({
scrollX: (width - contextWidth * scaleRatio) / 2,
})
}
if (contextHeight * scaleRatio <= height) {
// make context center
- this._ctx.setTransform({
+ this[_ctx].setTransform({
scrollY: (height - contextHeight * scaleRatio) / 2,
})
}
- if (contextWidth * scaleRatio >= width && this._ctx.getTransform().scrollX > 0) {
- this._ctx.setTransform({
+ if (contextWidth * scaleRatio >= width && this[_ctx].getTransform().scrollX > 0) {
+ this[_ctx].setTransform({
scrollX: 0,
})
}
- if (contextHeight * scaleRatio >= height && this._ctx.getTransform().scrollY > 0) {
- this._ctx.setTransform({
+ if (contextHeight * scaleRatio >= height && this[_ctx].getTransform().scrollY > 0) {
+ this[_ctx].setTransform({
scrollY: 0,
})
}
- const { scrollX: _scrollX, scrollY: _scrollY } = this._ctx.getTransform();
+ const { scrollX: _scrollX, scrollY: _scrollY } = this[_ctx].getTransform();
// reset scroll
if (_scrollX < 0 && Math.abs(_scrollX) > Math.abs(contextWidth * scaleRatio - width)) {
- this._ctx.setTransform({
+ this[_ctx].setTransform({
scrollX: 0 - Math.abs(contextWidth * scaleRatio - width)
})
}
if (_scrollY < 0 && Math.abs(_scrollY) > Math.abs(contextHeight * scaleRatio - height)) {
- this._ctx.setTransform({
+ this[_ctx].setTransform({
scrollY: 0 - Math.abs(contextHeight * scaleRatio - height)
})
}
// result size
- const { scrollX, scrollY } = this._ctx.getTransform();
+ const { scrollX, scrollY } = this[_ctx].getTransform();
const size = {
x: scrollX * scaleRatio,
y: scrollY * scaleRatio,
@@ -224,7 +234,6 @@ class Board {
size, position, deviceSize
};
}
-
}
export default Board;
diff --git a/packages/board/src/util/event.ts b/packages/board/src/util/event.ts
index 22f6543..c17a929 100644
--- a/packages/board/src/util/event.ts
+++ b/packages/board/src/util/event.ts
@@ -5,9 +5,8 @@ export interface TypeBoardEventArgMap {
'move': TypePoint;
'moveStart': TypePoint;
'moveEnd': TypePoint;
- // 'scale': number;
- // 'scrollX': number;
- // 'scrollY': number;
+ 'wheelX': number;
+ 'wheelY': number;
}
export interface TypeBoardEvent {
diff --git a/packages/board/src/util/watcher.ts b/packages/board/src/util/watcher.ts
index f2b1a91..41cff3d 100644
--- a/packages/board/src/util/watcher.ts
+++ b/packages/board/src/util/watcher.ts
@@ -28,13 +28,14 @@ export class Watcher {
_initEvent(): void {
const canvas = this._canvas;
- canvas.addEventListener('mousedown', this._listenMoveStart.bind(this));
- canvas.addEventListener('mousemove', this._listenMove.bind(this));
- canvas.addEventListener('mouseup', this._listenMoveEnd.bind(this));
+ canvas.addEventListener('mousedown', this._listenMoveStart.bind(this), true);
+ canvas.addEventListener('mousemove', this._listenMove.bind(this), true);
+ canvas.addEventListener('mouseup', this._listenMoveEnd.bind(this), true);
+ canvas.addEventListener('wheel', this._listenWheel.bind(this), true);
- canvas.addEventListener('touchstart', this._listenMoveStart.bind(this));
- canvas.addEventListener('touchmove', this._listenMove.bind(this));
- canvas.addEventListener('touchend', this._listenMoveEnd.bind(this));
+ canvas.addEventListener('touchstart', this._listenMoveStart.bind(this), true);
+ canvas.addEventListener('touchmove', this._listenMove.bind(this), true);
+ canvas.addEventListener('touchend', this._listenMoveEnd.bind(this), true);
// const mouseupEvent = new MouseEvent('mouseup');
// document.querySelector('body')?.addEventListener('mousemove', (e) => {
@@ -81,6 +82,16 @@ export class Watcher {
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);
+ }
+ }
+
_getPosition(e: MouseEvent|TouchEvent): TypePoint {
const canvas = this._canvas;
let x = 0;