feat: @idraw/core implement Cursor style

This commit is contained in:
chenshenhai 2021-06-22 12:33:14 +08:00
parent fe7217556d
commit 50c4bc1b96
6 changed files with 120 additions and 17 deletions

View file

@ -1,11 +1,13 @@
# @idraw/core
* [] Area select
* [] Keep all num two decimals
* [x] Cursor style
* [x] Can't controll element at scroll-area
* [x] Disable controll element
* [x] static check/is type declare
* [x] Force update image/svg image when element change
* [x] Reset board's size
* [] Keep all num two decimals
* [x] Limit element's angle between -360~360 deg
* [x] Check if the element and elements' attribute of desc is supported
* [x] Suport elements'desc and attribute check method

View file

@ -1,4 +1,6 @@
import { TypeScreenPosition, TypeScreenSize, TypeScreenContext, TypePoint, TypeBoardOptions, TypeBoardSizeOptions, } from '@idraw/types';
import {
TypeScreenPosition, TypeScreenSize, TypeScreenContext, TypePoint, TypePointCursor,
TypeBoardOptions, TypeBoardSizeOptions, } from '@idraw/types';
import util from '@idraw/util';
import { Watcher } from './lib/watcher';
import { setStyle } from './lib/style';
@ -17,9 +19,6 @@ type PrivateOptions = TypeBoardOptions & {
devicePixelRatio: number
}
type TypeCursor = 'auto' | 'move' | 'n-resize' | 'e-resize' | 's-resize' | 'w-resize'
| 'ne-resize' | 'nw-resize' | 'se-resize' | 'sw-resize' | 'grab';
class Board {
private [_canvas]: HTMLCanvasElement;
private [_displayCanvas]: HTMLCanvasElement;
@ -138,7 +137,7 @@ class Board {
return this[_calcScreen]();
}
setCursor(cursor: TypeCursor) {
setCursor(cursor: TypePointCursor) {
this[_displayCanvas].style.cursor = cursor;
}

View file

@ -18,8 +18,8 @@ import {
_board, _data, _opts, _config, _renderer, _element, _helper, _hasInited,
_hasInitedData, _mode, _selectedUUID, _prevPoint, _selectedDotDirection,
_coreEvent, _mapper, _initEvent, _handlePoint, _handleMoveStart, _handleMove,
_handleMoveEnd, _dragElement, _transfromElement, _emitChangeScreen, _emitChangeData,
_onlyRender,
_handleMoveEnd, _handleHover, _dragElement, _transfromElement, _emitChangeScreen,
_emitChangeData, _onlyRender, _cursorStatus,
} from './names';
const { time } = util;
@ -30,7 +30,11 @@ enum Mode {
NULL = 'null',
SELECT_ELEMENT = 'select-element',
SELECT_ELEMENT_WRAPPER_DOT = 'select-element-wrapper-dot',
PAINTING = 'painting',
}
enum CursorStatus {
DRAGGING = 'dragging',
NULL = 'null'
}
class Core {
@ -51,6 +55,7 @@ class Core {
private [_prevPoint]: TypePoint | null = null;
private [_selectedDotDirection]: TypeHelperWrapperDotDirection | null = null;
private [_onlyRender]: boolean = false;
private [_cursorStatus]: CursorStatus = CursorStatus.NULL;
static is: TypeIs = is;
static check: TypeCheck = check;
@ -72,7 +77,11 @@ class Core {
this[_renderer] = new Renderer(this[_board]);
this[_element] = new Element(this[_board].getContext());
this[_helper] = new Helper(this[_board], this[_config]);
this[_mapper] = new Mapper(this[_board]);
this[_mapper] = new Mapper({
board: this[_board],
helper: this[_helper],
element: this[_element]
});
this[_initEvent]();
this[_hasInited] = true;
}
@ -244,6 +253,7 @@ class Core {
this[_board].on('moveStart', this[_handleMoveStart].bind(this));
this[_board].on('move', time.throttle(this[_handleMove].bind(this), 16));
this[_board].on('moveEnd', this[_handleMoveEnd].bind(this));
this[_board].on('hover', time.throttle(this[_handleHover].bind(this), 32));
}
private [_handlePoint](point: TypePoint): void {
@ -284,12 +294,15 @@ class Core {
}
private [_handleMove](point: TypePoint): void {
if (typeof this[_selectedUUID] === 'string') {
if (this[_mode] === Mode.SELECT_ELEMENT) {
this[_dragElement](this[_selectedUUID] as string, point, this[_prevPoint]);
this.draw();
this[_cursorStatus] = CursorStatus.DRAGGING;
} else if (this[_mode] === Mode.SELECT_ELEMENT_WRAPPER_DOT && this[_selectedDotDirection]) {
this[_transfromElement](this[_selectedUUID] as string, point, this[_prevPoint], this[_selectedDotDirection] as TypeHelperWrapperDotDirection);
this[_cursorStatus] = CursorStatus.DRAGGING;
}
}
this[_prevPoint] = point;
@ -323,6 +336,14 @@ class Core {
}
this[_selectedUUID] = null;
this[_prevPoint] = null;
this[_cursorStatus] = CursorStatus.NULL;
}
private [_handleHover](point: TypePoint): void {
if (this[_cursorStatus] === CursorStatus.NULL) {
const cursor = this[_mapper].judgePointCursor(point, this[_data]);
this[_board].setCursor(cursor);
}
}
private [_dragElement](uuid: string, point: TypePoint, prevPoint: TypePoint|null): void {

View file

@ -1,14 +1,31 @@
import { TypePoint } from '@idraw/types';
import { TypeData, TypePoint, TypePointCursor } from '@idraw/types';
import Board from '@idraw/board';
import { Helper } from './helper';
import { Element } from './element';
const _board = Symbol('_displayCtx');
const _helper = Symbol('_helper');
const _element = Symbol('_element');
const _opts = Symbol('_opts');
type Options = {
board: Board;
element: Element;
helper: Helper
}
export class Mapper {
private [_board]: Board
private [_opts]: Options;
private [_board]: Board;
private [_helper]: Helper;
private [_element]: Element;
constructor(board: Board) {
this[_board] = board;
constructor(opts: Options) {
this[_opts] = opts;
this[_board] = this[_opts].board;
this[_element] = this[_opts].element;
this[_helper] = this[_opts].helper;
}
isEffectivePoint(p: TypePoint): boolean {
@ -19,4 +36,62 @@ export class Mapper {
}
return false;
}
judgePointCursor(p: TypePoint, data: TypeData): TypePointCursor {
let cursor: TypePointCursor = 'auto';
if (!this.isEffectivePoint(p)) {
return cursor;
}
const [uuid, direction] = this[_helper].isPointInElementWrapperDot(p);
if (uuid && direction) {
switch (direction) {
case 'top-left' : {
cursor = 'nw-resize';
break;
}
case 'top' : {
cursor = 'n-resize';
break;
}
case 'top-right' : {
cursor = 'ne-resize';
break;
}
case 'right' : {
cursor = 'e-resize';
break;
}
case 'bottom-right' : {
cursor = 'se-resize';
break;
}
case 'bottom' : {
cursor = 's-resize';
break;
}
case 'bottom-left' : {
cursor = 'sw-resize';
break;
}
case 'left' : {
cursor = 'w-resize';
break;
}
case 'rotate' : {
cursor = 'grab';
break;
}
default: {
break;
}
}
} else {
const [index] = this[_element].isPointInElement(p, data);
if (index >= 0) {
cursor = 'move';
}
}
return cursor;
}
}

View file

@ -18,16 +18,18 @@ const _handlePoint = Symbol('_handlePoint');
const _handleMoveStart = Symbol('_handleMoveStart');
const _handleMove = Symbol('_handleMove');
const _handleMoveEnd = Symbol('_handleMoveEnd');
const _handleHover = Symbol('_handleHover');
const _dragElement = Symbol('_dragElement');
const _transfromElement = Symbol('_transfromElement');
const _emitChangeScreen = Symbol('_emitChangeScreen');
const _emitChangeData = Symbol('_emitChangeData');
const _onlyRender = Symbol('onlyRender');
const _onlyRender = Symbol('_onlyRender');
const _cursorStatus = Symbol('_cursorStatus');
export {
_board, _data, _opts, _config, _renderer, _element, _helper, _hasInited,
_hasInitedData, _mode, _selectedUUID, _prevPoint, _selectedDotDirection,
_coreEvent, _mapper, _initEvent, _handlePoint, _handleMoveStart, _handleMove,
_handleMoveEnd, _dragElement, _transfromElement, _emitChangeScreen, _emitChangeData,
_onlyRender,
_handleMoveEnd, _handleHover, _dragElement, _transfromElement, _emitChangeScreen,
_emitChangeData, _onlyRender, _cursorStatus,
}

View file

@ -25,8 +25,12 @@ type TypeBoardOptions = TypeBoardSizeOptions & {
scrollConfig?: TypeBoardScrollConfig
}
type TypePointCursor = 'auto' | 'move' | 'n-resize' | 'e-resize' | 's-resize' | 'w-resize'
| 'ne-resize' | 'nw-resize' | 'se-resize' | 'sw-resize' | 'grab';
export {
TypePoint,
TypePointCursor,
TypeBoardSizeOptions,
TypeBoardOptions,
TypeBoardScrollConfig,