123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- import { SvgHelper } from '../../renderer/SvgHelper';
- import { BaseMarker } from '../BaseMarker';
- import { RectangularMarkerGrips } from './RectangularMarkerGrips';
- import { ResizeGrip } from '../BaseMarker/ResizeGrip';
- import { PositionType } from 'fc-whiteboard/src/event/Event';
-
- export class RectangularMarker extends BaseMarker {
- public static createMarker = (): RectangularMarker => {
- const marker = new RectangularMarker();
- marker.setup();
- return marker;
- };
-
- protected MIN_SIZE = 5;
-
- private controlBox: SVGGElement;
- private readonly CB_DISTANCE: number = 10;
- private controlRect: SVGRectElement;
-
- private controlGrips: RectangularMarkerGrips;
- private activeGrip: ResizeGrip | null;
-
- public endManipulation() {
- super.endManipulation();
- this.isResizing = false;
- this.activeGrip = null;
- }
-
- public select() {
- super.select();
- this.controlBox.style.display = '';
- }
-
- public deselect() {
- super.deselect();
- this.controlBox.style.display = 'none';
- }
-
- protected setup() {
- super.setup();
-
- this.addControlBox();
- }
-
- protected resizeByEvent(x: number, y: number, pos: PositionType) {
- this.activeGrip = this.controlGrips[pos];
- this.resize(x, y);
- }
-
- protected resize(x: number, y: number, onPosition?: (pos: PositionType) => void) {
- let translateX = 0;
- let translateY = 0;
-
- switch (this.activeGrip) {
- case this.controlGrips.topLeft:
- this.width -= x;
- this.height -= y;
- translateX += x;
- translateY += y;
- if (onPosition) {
- onPosition('topLeft');
- }
- break;
- case this.controlGrips.bottomLeft:
- this.width -= x;
- this.height += y;
- translateX += x;
- if (onPosition) {
- onPosition('bottomLeft');
- }
- break;
- case this.controlGrips.topRight:
- this.width += x;
- this.height -= y;
- translateY += y;
- if (onPosition) {
- onPosition('topRight');
- }
- break;
- case this.controlGrips.bottomRight:
- this.width += x;
- this.height += y;
- if (onPosition) {
- onPosition('bottomRight');
- }
- break;
- case this.controlGrips.centerLeft:
- this.width -= x;
- translateX += x;
- if (onPosition) {
- onPosition('centerLeft');
- }
- break;
- case this.controlGrips.centerRight:
- this.width += x;
- if (onPosition) {
- onPosition('centerRight');
- }
- break;
- case this.controlGrips.topCenter:
- this.height -= y;
- translateY += y;
- if (onPosition) {
- onPosition('topCenter');
- }
- break;
- case this.controlGrips.bottomCenter:
- this.height += y;
- if (onPosition) {
- onPosition('bottomCenter');
- }
- break;
- default:
- break;
- }
-
- if (this.width < this.MIN_SIZE) {
- const offset = this.MIN_SIZE - this.width;
- this.width = this.MIN_SIZE;
- if (translateX !== 0) {
- translateX -= offset;
- }
- }
- if (this.height < this.MIN_SIZE) {
- const offset = this.MIN_SIZE - this.height;
- this.height = this.MIN_SIZE;
- if (translateY !== 0) {
- translateY -= offset;
- }
- }
-
- if (translateX !== 0 || translateY !== 0) {
- const translate = this.visual.transform.baseVal.getItem(0);
- translate.setMatrix(translate.matrix.translate(translateX, translateY));
- this.visual.transform.baseVal.replaceItem(translate, 0);
- }
-
- this.adjustControlBox();
- }
-
- protected onTouch(ev: TouchEvent) {
- super.onTouch(ev);
- }
-
- private addControlBox = () => {
- this.controlBox = SvgHelper.createGroup([['class', 'fc-whiteboard-rect-control-box']]);
- const translate = SvgHelper.createTransform();
- translate.setTranslate(-this.CB_DISTANCE / 2, -this.CB_DISTANCE / 2);
- this.controlBox.transform.baseVal.appendItem(translate);
-
- this.addToVisual(this.controlBox);
-
- this.controlRect = SvgHelper.createRect(
- this.width + this.CB_DISTANCE,
- this.height + this.CB_DISTANCE,
- [['class', 'fc-whiteboard-rect-control-rect']]
- );
-
- this.controlBox.appendChild(this.controlRect);
-
- this.controlGrips = new RectangularMarkerGrips();
- this.addControlGrips();
- };
-
- private adjustControlBox = () => {
- this.controlRect.setAttribute('width', (this.width + this.CB_DISTANCE).toString());
- this.controlRect.setAttribute('height', (this.height + this.CB_DISTANCE).toString());
-
- this.positionGrips();
- };
-
- private addControlGrips = () => {
- this.controlGrips.topLeft = this.createGrip();
- this.controlGrips.topCenter = this.createGrip();
- this.controlGrips.topRight = this.createGrip();
- this.controlGrips.centerLeft = this.createGrip();
- this.controlGrips.centerRight = this.createGrip();
- this.controlGrips.bottomLeft = this.createGrip();
- this.controlGrips.bottomCenter = this.createGrip();
- this.controlGrips.bottomRight = this.createGrip();
-
- this.positionGrips();
- };
-
- private createGrip = (): ResizeGrip => {
- const grip = new ResizeGrip();
- grip.visual.transform.baseVal.appendItem(SvgHelper.createTransform());
- this.controlBox.appendChild(grip.visual);
-
- grip.visual.addEventListener('mousedown', this.gripMouseDown);
- grip.visual.addEventListener('mousemove', this.gripMouseMove);
- grip.visual.addEventListener('mouseup', this.gripMouseUp);
-
- grip.visual.addEventListener('touchstart', this.onTouch, { passive: false });
- grip.visual.addEventListener('touchend', this.onTouch, { passive: false });
- grip.visual.addEventListener('touchmove', this.onTouch, { passive: false });
-
- return grip;
- };
-
- private positionGrips = () => {
- const gripSize = this.controlGrips.topLeft.GRIP_SIZE;
-
- const left = -gripSize / 2;
- const top = left;
- const cx = (this.width + this.CB_DISTANCE) / 2 - gripSize / 2;
- const cy = (this.height + this.CB_DISTANCE) / 2 - gripSize / 2;
- const bottom = this.height + this.CB_DISTANCE - gripSize / 2;
- const right = this.width + this.CB_DISTANCE - gripSize / 2;
-
- this.positionGrip(this.controlGrips.topLeft.visual, left, top);
- this.positionGrip(this.controlGrips.topCenter.visual, cx, top);
- this.positionGrip(this.controlGrips.topRight.visual, right, top);
- this.positionGrip(this.controlGrips.centerLeft.visual, left, cy);
- this.positionGrip(this.controlGrips.centerRight.visual, right, cy);
- this.positionGrip(this.controlGrips.bottomLeft.visual, left, bottom);
- this.positionGrip(this.controlGrips.bottomCenter.visual, cx, bottom);
- this.positionGrip(this.controlGrips.bottomRight.visual, right, bottom);
- };
-
- private positionGrip = (grip: SVGGraphicsElement, x: number, y: number) => {
- const translate = grip.transform.baseVal.getItem(0);
- translate.setTranslate(x, y);
- grip.transform.baseVal.replaceItem(translate, 0);
- };
-
- private gripMouseDown = (ev: MouseEvent) => {
- this.isResizing = true;
- this.activeGrip = this.controlGrips.findGripByVisual(ev.target as SVGGraphicsElement) || null;
- this.previousMouseX = ev.screenX;
- this.previousMouseY = ev.screenY;
- ev.stopPropagation();
- };
-
- private gripMouseUp = (ev: MouseEvent) => {
- this.isResizing = false;
- this.activeGrip = null;
- ev.stopPropagation();
- };
-
- private gripMouseMove = (ev: MouseEvent) => {
- if (this.isResizing) {
- this.manipulate(ev);
- }
- };
- }
|