From 7311cf24870d7b5a22dc074cb3aadc56be95cbd5 Mon Sep 17 00:00:00 2001 From: Samson Christopher <91219719+Maghwyn@users.noreply.github.com> Date: Sun, 11 Jun 2023 18:57:21 +0200 Subject: [PATCH 01/21] feat(resize): Add the resize type into a separate file --- .../lib/pixi-tools-v2/types/pixi-resize.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 front-end/src/lib/pixi-tools-v2/types/pixi-resize.ts diff --git a/front-end/src/lib/pixi-tools-v2/types/pixi-resize.ts b/front-end/src/lib/pixi-tools-v2/types/pixi-resize.ts new file mode 100644 index 00000000..3c1fd849 --- /dev/null +++ b/front-end/src/lib/pixi-tools-v2/types/pixi-resize.ts @@ -0,0 +1,43 @@ +import { ResizeHandle } from "./pixi-enums"; + +export interface InitialResizeOptions { + parentInitialWidth: number; + parentInitialHeight: number; + childInitialX?: number; + childInitialY?: number; + childInitialWidth?: number; + childInitialHeight?: number; +} + +export interface PrimeOptions { + parentPrimeWidth: number; + parentPrimeHeight: number; +} + +export interface ProportionScaleOptions extends InitialResizeOptions, PrimeOptions { + anchorX: number; + anchorY: number; +} + +export interface ParentOrthogonalPrimeOptions { + handleId: ResizeHandle; + initialWidth: number; + initialHeight: number; + dx: number; + dy: number; +} +export interface ParentPrimeOptions extends ParentOrthogonalPrimeOptions { + ratioA: number; + ratioB: number; + isShift: boolean; +} + +export interface ResizeMetrics { + dx: number; + dy: number; +} + +export interface ResizeRatioMetrics extends ResizeMetrics { + ratioA: number; + ratioB: number; +} \ No newline at end of file From 18ecdef6c4c131dbe1c4ae6066304d7fcb973e5d Mon Sep 17 00:00:00 2001 From: Samson Christopher <91219719+Maghwyn@users.noreply.github.com> Date: Sun, 11 Jun 2023 18:57:55 +0200 Subject: [PATCH 02/21] refacto(resize): Refacto the resize plugin to be a bit more readable instead of having a big switch --- .../plugins/containerResizePlugin.ts | 489 +++++++++--------- .../src/lib/pixi-tools-v2/types/pixi-enums.ts | 3 + 2 files changed, 240 insertions(+), 252 deletions(-) diff --git a/front-end/src/lib/pixi-tools-v2/plugins/containerResizePlugin.ts b/front-end/src/lib/pixi-tools-v2/plugins/containerResizePlugin.ts index 74c1c939..4cc9d46f 100644 --- a/front-end/src/lib/pixi-tools-v2/plugins/containerResizePlugin.ts +++ b/front-end/src/lib/pixi-tools-v2/plugins/containerResizePlugin.ts @@ -11,23 +11,14 @@ import { LeftWall, TopWall, BottomWall, + GenericResize, + OrthogonalResize, } from '../types/pixi-enums'; import type { CanvasContainer, PluginContainer } from '../types/pixi-aliases'; import type { ContainerSize, InitialGraphicState } from '../types/pixi-container'; import { dragAttachedLines } from '../utils/dragAttachedLines'; - -export interface ProportionScaleOptions { - parentInitialWidth: number; - parentInitialHeight: number; - parentPrimeWidth: number; - parentPrimeHeight: number; - anchorX: number; - anchorY: number; - childInitialX: number; - childInitialY: number; - childInitialWidth: number; - childInitialHeight: number; -} +import { ModelGraphics } from '../types/pixi-class'; +import { ResizeRatioMetrics, ResizeMetrics, InitialResizeOptions, ParentOrthogonalPrimeOptions, ParentPrimeOptions, ProportionScaleOptions } from '../types/pixi-resize'; export class ResizePlugin { protected readonly viewport: ViewportUI; @@ -109,6 +100,163 @@ export class ResizePlugin { this.viewport.on('pointermove', this._updateResizeTransform); }; + private _getParentPrimeSize = (options: ParentPrimeOptions) => { + if(this.handleId === ResizeHandle.LT || this.handleId === ResizeHandle.RT) { + if (this.handleId === ResizeHandle.LT) { + return { + parentPrimeWidth: options.initialWidth - options.dx, + parentPrimeHeight: options.isShift + ? (options.initialWidth - options.dx) * options.ratioA + : options.initialHeight - options.dy + } + } else { + return { + parentPrimeWidth: options.initialWidth + options.dx, + parentPrimeHeight: options.isShift + ? (options.initialWidth + options.dx) * options.ratioA + : options.initialHeight - options.dy + } + } + } else if (this.handleId === ResizeHandle.LB || this.handleId === ResizeHandle.RB) { + if (this.handleId === ResizeHandle.LB) { + return { + parentPrimeWidth: options.initialWidth - options.dx, + parentPrimeHeight: options.isShift + ? (options.initialWidth - options.dx) / options.ratioB + : options.initialHeight + options.dy + } + } else { + return { + parentPrimeWidth: options.initialWidth + options.dx, + parentPrimeHeight: options.isShift + ? (options.initialWidth + options.dx) / options.ratioB + : options.initialHeight + options.dy + } + } + } + + return null; + } + + private _getParentOrthogonalPrimeSize = (options: ParentOrthogonalPrimeOptions) => { + if (this.handleId === ResizeHandle.T) { + return { + parentPrimeWidth: options.initialWidth, + parentPrimeHeight: options.initialHeight - options.dy, + } + } else if (this.handleId === ResizeHandle.R) { + return { + parentPrimeWidth: options.initialWidth + options.dx, + parentPrimeHeight: options.initialHeight, + } + } else if (this.handleId === ResizeHandle.B) { + return { + parentPrimeWidth: options.initialWidth, + parentPrimeHeight: options.initialHeight + options.dy, + } + } else if (this.handleId === ResizeHandle.L) { + return { + parentPrimeWidth: options.initialWidth - options.dx, + parentPrimeHeight: options.initialHeight, + } + } + + return null; + } + + private _genericResize = ( + child: ModelGraphics, + initialOptions: InitialResizeOptions, + resizeMetrics: ResizeRatioMetrics, + isShift: boolean, + ) => { + const anchorX = this.handleId === ResizeHandle.LT || this.handleId === ResizeHandle.LB + ? this.container.absMaxX + : this.container.absMinX + + const anchorY = this.handleId === ResizeHandle.LT || this.handleId === ResizeHandle.RT + ? this.container.absMaxY + : this.container.absMinY + + const anchor = { anchorX, anchorY }; + const prime = this._getParentPrimeSize({ + ...resizeMetrics, + initialWidth: initialOptions.parentInitialWidth, + initialHeight: initialOptions.parentInitialHeight, + handleId: this.handleId, + isShift, + }) + + const { x, y, width, height } = this._proportionalScale({ + ...initialOptions, + ...anchor, + ...prime, + }); + + child.width = width; + child.height = height; + child.x = x; + child.y = y; + } + + private _orthogonalResize = ( + child: ModelGraphics, + initialOptions: InitialResizeOptions, + resizeMetrics: ResizeMetrics, + ) => { + const anchor = this.handleId === ResizeHandle.T || this.handleId === ResizeHandle.L + ? { anchorX: this.container.absMaxX, anchorY: this.container.absMaxY } + : { anchorX: this.container.absMinX, anchorY: this.container.absMinY } + + const prime = this._getParentOrthogonalPrimeSize({ + ...resizeMetrics, + initialWidth: initialOptions.parentInitialWidth, + initialHeight: initialOptions.parentInitialHeight, + handleId: this.handleId, + }) + + const { x, y, width, height } = this._proportionalScale({ + ...initialOptions, + ...anchor, + ...prime, + }); + + child.width = width; + child.height = height; + child.x = x; + child.y = y; + } + + private _assignNewGraphicState = (isXAxis: boolean) => { + const newHandleId = isXAxis + ? ResizeHandleOppositeOf[this.handleId].x + : ResizeHandleOppositeOf[this.handleId].y; + this.handleId = newHandleId; + + this.initialGraphicsState.length = 0; + const graphics = this.container.getGraphicChildren(); + for (const element of graphics) { + this.initialGraphicsState.push({ + child: element, + width: element.width, + height: element.height, + x: element.x, + y: element.y, + }); + } + + const { width, height, absMinX, absMaxY, absMaxX, absMinY } = this.container; + this.initialContainerSize = { width, height, absMinX, absMaxY, absMaxX, absMinY }; + + if (this.handleId < 4) { + const { x, y } = this.viewport.resizeHandles[this.handleId]; + this.initialCursorPosition = new Point(x, y); + } else { + const { x, y } = this.viewport.resizeHitAreas[this.handleId - 4]; + this.initialCursorPosition = new Point(x, y); + } + } + private _updateResizeTransform = (e: FederatedPointerEvent) => { if (e) e.stopPropagation(); if (this.container === null) return; @@ -120,237 +268,69 @@ export class ResizePlugin { const cursorPosition = this.viewport.toWorld(e.global.clone()); const dx = cursorPosition.x - this.initialCursorPosition.x; const dy = cursorPosition.y - this.initialCursorPosition.y; + + const { width: initialCtnWidth, height: initialCtnHeight, absMinX, absMaxX, absMinY, absMaxY } = this.initialContainerSize; + const ratioA = initialCtnHeight / initialCtnWidth; + const ratioB = initialCtnWidth / initialCtnHeight; + const initialOptions: InitialResizeOptions = { + parentInitialWidth: initialCtnWidth, + parentInitialHeight: initialCtnHeight, + } - const isPastLeft = - LeftWall.includes(this.handleId) && cursorPosition.x < this.initialContainerSize.absMinX; - const isPastRight = - RightWall.includes(this.handleId) && cursorPosition.x > this.initialContainerSize.absMaxX; - const isPastTop = - TopWall.includes(this.handleId) && cursorPosition.y < this.initialContainerSize.absMinY; - const isPastBottom = - BottomWall.includes(this.handleId) && cursorPosition.y > this.initialContainerSize.absMaxY; + const isPastLeft = LeftWall.includes(this.handleId) && cursorPosition.x < absMinX; + const isPastRight = RightWall.includes(this.handleId) && cursorPosition.x > absMaxX; + const isPastTop = TopWall.includes(this.handleId) && cursorPosition.y < absMinY; + const isPastBottom = BottomWall.includes(this.handleId) && cursorPosition.y > absMaxY; const isPastBounds = isPastLeft || isPastRight || isPastBottom || isPastTop; - const ratioA = this.initialContainerSize.height / this.initialContainerSize.width; - const ratioB = this.initialContainerSize.width / this.initialContainerSize.height; - for (let n = 0; n < this.initialGraphicsState.length; n++) { - const updates = { ...this.initialGraphicsState[n] }; // create a new object reference - - if (isPastLeft) { + const { child } = this.initialGraphicsState[n]; + + if(isPastBounds) { + const sizeAndPos = isPastLeft || isPastRight ? [child.x, child.width] : [child.y, child.height]; + const anchor = isPastLeft ? absMinX : isPastRight ? absMaxX : isPastTop ? absMinY : absMaxY; const mirror = this._proportionalMirrorPosition({ - anchor: this.initialContainerSize.absMinX, - childCurrentPos: updates.child.x, - childCurrentSize: updates.child.width, + anchor: anchor, + childCurrentPos: sizeAndPos[0], + childCurrentSize: sizeAndPos[1], }); - this.initialGraphicsState[n].child.x = mirror; - } else if (isPastRight) { - const mirror = this._proportionalMirrorPosition({ - anchor: this.initialContainerSize.absMaxX, - childCurrentPos: updates.child.x, - childCurrentSize: updates.child.width, - }); - this.initialGraphicsState[n].child.x = mirror; - } else if (isPastTop) { - const mirror = this._proportionalMirrorPosition({ - anchor: this.initialContainerSize.absMinY, - childCurrentPos: updates.child.y, - childCurrentSize: updates.child.height, - }); - this.initialGraphicsState[n].child.y = mirror; - } else if (isPastBottom) { - const mirror = this._proportionalMirrorPosition({ - anchor: this.initialContainerSize.absMaxY, - childCurrentPos: updates.child.y, - childCurrentSize: updates.child.height, - }); - this.initialGraphicsState[n].child.y = mirror; + + if (isPastLeft || isPastRight) child.x = mirror; + else child.y = mirror; + continue; } - if (isPastBounds) continue; - - const sharedOptions = { - parentInitialWidth: this.initialContainerSize.width, - parentInitialHeight: this.initialContainerSize.height, - childInitialX: updates.x, - childInitialY: updates.y, - childInitialWidth: updates.width, - childInitialHeight: updates.height, - }; - - switch (this.handleId) { - case ResizeHandle.LT: { - const heightRatio = shift - ? (this.initialContainerSize.width - dx) * ratioA - : this.initialContainerSize.height - dy; - - const { x, y, width, height } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width - dx, - parentPrimeHeight: heightRatio, - anchorX: this.container.absMaxX, - anchorY: this.container.absMaxY, - }); - updates.width = width; - updates.height = height; - updates.x = x; - updates.y = updates.y === this.container.absMaxY ? updates.y : y; - break; - } - case ResizeHandle.RT: { - const heightRatio = shift - ? (this.initialContainerSize.width + dx) * ratioA - : this.initialContainerSize.height - dy; - - const { x, y, width, height } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width + dx, - parentPrimeHeight: heightRatio, - anchorX: this.container.absMinX, - anchorY: this.container.absMaxY, - }); - updates.width = width; - updates.height = height; - updates.x = x; - updates.y = updates.y + updates.height === this.container.absMaxY ? updates.y : y; - break; - } - case ResizeHandle.LB: { - const heightRatio = shift - ? (this.initialContainerSize.width - dx) / ratioB - : this.initialContainerSize.height + dy; - - const { x, y, width, height } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width - dx, - parentPrimeHeight: heightRatio, - anchorX: this.container.absMaxX, - anchorY: this.container.absMinY, - }); - updates.width = width; - updates.height = height; - updates.x = updates.x === this.container.absMaxX ? updates.x : x; - updates.y = updates.y === this.container.absMinY ? updates.y : y; - break; - } - case ResizeHandle.RB: { - const heightRatio = shift - ? (this.initialContainerSize.width + dx) / ratioB - : this.initialContainerSize.height + dy; - - const { x, y, width, height } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width + dx, - parentPrimeHeight: heightRatio, - anchorX: this.container.absMinX, - anchorY: this.container.absMinY, - }); - updates.width = width; - updates.height = height; - updates.x = x; - updates.y = updates.y === this.container.absMinY ? updates.y : y; - break; - } - case ResizeHandle.T: { - const { y, height } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width, - parentPrimeHeight: this.initialContainerSize.height - dy, - anchorX: this.container.absMaxX, - anchorY: this.container.absMaxY, - }); - updates.height = height; - updates.y = y; - break; - } - case ResizeHandle.R: { - const { x, width } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width + dx, - parentPrimeHeight: this.initialContainerSize.height, - anchorX: this.container.absMinX, - anchorY: this.container.absMinY, - }); - updates.width = width; - updates.x = x; - break; - } - case ResizeHandle.B: { - const { y, height } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width, - parentPrimeHeight: this.initialContainerSize.height + dy, - anchorX: this.container.absMinX, - anchorY: this.container.absMinY, - }); - updates.height = height; - updates.y = y; - break; - } - case ResizeHandle.L: { - const { x, width } = this._proportionalScale({ - ...sharedOptions, - parentPrimeWidth: this.initialContainerSize.width - dx, - parentPrimeHeight: this.initialContainerSize.height, - anchorX: this.container.absMaxX, - anchorY: this.container.absMaxY, - }); - updates.width = width; - updates.x = x; - break; - } - } + const { x, y, width, height } = { ...this.initialGraphicsState[n] }; + + initialOptions.childInitialX = x; + initialOptions.childInitialY = y; + initialOptions.childInitialWidth = width; + initialOptions.childInitialHeight = height; - this.initialGraphicsState[n].child.width = updates.width; - this.initialGraphicsState[n].child.x = updates.x; - this.initialGraphicsState[n].child.height = updates.height; - this.initialGraphicsState[n].child.y = updates.y; + if(GenericResize.includes(this.handleId)) { + this._genericResize(child, initialOptions, { + dx, dy, ratioA, ratioB + }, shift); + } else if (OrthogonalResize.includes(this.handleId)) { + this._orthogonalResize(child, initialOptions, { + dx, dy + }); + } - if (this.initialGraphicsState[n].child.typeId === 'framebox') { - const frame = this.initialGraphicsState[n].child.parent?.parent; + if (child.typeId === 'framebox') { + const frame = child.parent?.parent; if (frame instanceof FramedContainer) { dragAttachedLines(frame, this.viewport.socketPlugin); continue; } } - const parent = this.initialGraphicsState[n].child.parent as CanvasContainer; - + const parent = child.parent as CanvasContainer; if (parent.typeId === 'wrap') continue; - dragAttachedLines(parent, this.viewport.socketPlugin); } - if (this.container instanceof WrappedContainer) { - for (const element of this.container.absoluteChildren) { - if (element instanceof FramedContainer) { - element.emit('moved', null); - } - } - } else { - if (this.container instanceof FramedContainer) { - this.container.emit('moved', null); - } - - dragAttachedLines(this.container, this.viewport.socketPlugin); - } - - if (this.viewport.socketPlugin) { - const containers = - this.container instanceof WrappedContainer - ? this.container.absoluteChildren - : [this.container]; - - for (const container of containers) { - container.getGeometry(); - this.viewport.socketPlugin.emit( - 'ws-element-updated', - container.uuid, - container.serializeBounds(), - ); - } - } - + this._syncResize(); const geometry = this.container.getGeometry(); this.viewport.destroyBorder(); this.viewport.createBorder({ ...geometry, scale: this.viewport.scaled }); @@ -359,34 +339,7 @@ export class ResizePlugin { this.viewport.updateBezierHandles(geometry, false); if (isPastBounds) { - const isXAxis = isPastLeft || isPastRight; - const newHandleId = isXAxis - ? ResizeHandleOppositeOf[this.handleId].x - : ResizeHandleOppositeOf[this.handleId].y; - this.handleId = newHandleId; - - this.initialGraphicsState.length = 0; - const graphics = this.container.getGraphicChildren(); - for (const element of graphics) { - this.initialGraphicsState.push({ - child: element, - width: element.width, - height: element.height, - x: element.x, - y: element.y, - }); - } - - const { width, height, absMinX, absMaxY, absMaxX, absMinY } = this.container; - this.initialContainerSize = { width, height, absMinX, absMaxY, absMaxX, absMinY }; - - if (this.handleId < 4) { - const { x, y } = this.viewport.resizeHandles[this.handleId]; - this.initialCursorPosition = new Point(x, y); - } else { - const { x, y } = this.viewport.resizeHitAreas[this.handleId - 4]; - this.initialCursorPosition = new Point(x, y); - } + this._assignNewGraphicState(isPastLeft || isPastRight); } } catch (err) { if (err instanceof Error) { @@ -397,6 +350,38 @@ export class ResizePlugin { } }; + private _syncResize = () => { + if (this.container instanceof WrappedContainer) { + for (const element of this.container.absoluteChildren) { + if (element instanceof FramedContainer) { + element.emit('moved', null); + } + } + } else { + if (this.container instanceof FramedContainer) { + this.container.emit('moved', null); + } + + dragAttachedLines(this.container, this.viewport.socketPlugin); + } + + if (this.viewport.socketPlugin) { + const containers = + this.container instanceof WrappedContainer + ? this.container.absoluteChildren + : [this.container]; + + for (const container of containers) { + container.getGeometry(); + this.viewport.socketPlugin.emit( + 'ws-element-updated', + container.uuid, + container.serializeBounds(), + ); + } + } + } + private _endResizeTransform = (e: FederatedPointerEvent) => { if (e) e.stopPropagation(); if (this.container === null) return; diff --git a/front-end/src/lib/pixi-tools-v2/types/pixi-enums.ts b/front-end/src/lib/pixi-tools-v2/types/pixi-enums.ts index e5c86097..bf61b68a 100644 --- a/front-end/src/lib/pixi-tools-v2/types/pixi-enums.ts +++ b/front-end/src/lib/pixi-tools-v2/types/pixi-enums.ts @@ -73,6 +73,9 @@ export const ResizeHandleOppositeOf = { [ResizeHandle.L]: { x: ResizeHandle.R, y: null }, }; +export const GenericResize = [ResizeHandle.LT, ResizeHandle.RT, ResizeHandle.RB, ResizeHandle.LB]; +export const OrthogonalResize = [ResizeHandle.T, ResizeHandle.B, ResizeHandle.R, ResizeHandle.L]; + export const LeftWall = [ResizeHandle.RT, ResizeHandle.RB, ResizeHandle.R]; export const RightWall = [ResizeHandle.LT, ResizeHandle.LB, ResizeHandle.L]; export const TopWall = [ResizeHandle.LB, ResizeHandle.RB, ResizeHandle.B]; From cb4d334e576d81a92107253af6d6b14a954fc5f7 Mon Sep 17 00:00:00 2001 From: Samson Christopher <91219719+Maghwyn@users.noreply.github.com> Date: Mon, 12 Jun 2023 07:32:49 +0200 Subject: [PATCH 03/21] fix(modal): Fix an issue with the modal condition --- .../src/components/agility/UI/ToolsEditor.vue | 4 ++-- .../src/components/agility/modals/Blueprint.vue | 14 ++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/front-end/src/components/agility/UI/ToolsEditor.vue b/front-end/src/components/agility/UI/ToolsEditor.vue index d86d924b..39aac2b0 100644 --- a/front-end/src/components/agility/UI/ToolsEditor.vue +++ b/front-end/src/components/agility/UI/ToolsEditor.vue @@ -124,7 +124,7 @@ /> -
+
diff --git a/front-end/src/components/agility/modals/Blueprint.vue b/front-end/src/components/agility/modals/Blueprint.vue index 846cad1a..b446803f 100644 --- a/front-end/src/components/agility/modals/Blueprint.vue +++ b/front-end/src/components/agility/modals/Blueprint.vue @@ -1,5 +1,5 @@ @@ -20,10 +21,12 @@ import { useProjectStore } from '@/store/modules/project.store'; import { useAgilityStore } from '@/store/modules/agility.store'; import AgilityCanvasUI from '@/components/agility/AgilityCanvasUI.vue'; import CanvasLoader from '@/components/agility/UI/CanvasLoader.vue'; -import { LineContainer } from '../../lib/pixi-tools-v2/class/lineContainer'; +import { LineContainer } from '@/lib/pixi-tools-v2/class/lineContainer'; import { CanvasContainer } from '@/lib/pixi-tools-v2/types/pixi-aliases'; import { useThemeStore } from '@/store/modules/theme.store'; import { config } from '@/config/config'; +import { CursorScene } from '@/lib/pixi-tools-v2/cursorScene'; +import { useAuthStore } from '../../store/modules/auth.store'; const route = useRoute(); const projectStore = useProjectStore(); @@ -33,19 +36,35 @@ const themeStore = useThemeStore(); const isDark = computed(() => themeStore.theme); const scene = computed(() => projectStore.scene); const projectLoading = computed(() => agilityStore.projectLoading); +const viewportBounds = computed(() => projectStore.getViewportBounds); const project = computed(() => agilityStore.currentProject); const canvas = ref(); +const cursorCanvas = ref(); const roomId = ref(route.path.match(/[^/]+(?=\?)|[^/]+$/)[0]); const loading = computed(() => projectLoading.value || projectStore.internalLoading); let timeout: NodeJS.Timeout = null; let rawScene: Scene = null; +let rawCursorScene: CursorScene = null; watch(isDark, val => { if(scene.value) { scene.value.changeTheme(val); } -}) +}); + +watch(viewportBounds, val => { + rawCursorScene.viewport.x = val.x; + rawCursorScene.viewport.y = val.y; + + if(val.scaleX !== undefined && val.scaleY !== undefined) { + rawCursorScene.viewport.scale.set(val.scaleX, val.scaleY); + } + + if(val.mouseX !== undefined && val.mouseY !== undefined) { + rawCursorScene.viewport.updateMousePosition({ x: val.mouseX, y: val.mouseY }); + } +}, { deep: true }); onMounted(() => { document.addEventListener('fullscreenchange', onFullscreenChange); @@ -60,12 +79,17 @@ onMounted(() => { }, }; + const authStore = useAuthStore(); + const firstName = authStore.user?.profile?.firstName ?? 'unknown'; + // 84 represent the offset height due to tabs + const cursorScene = new CursorScene(cursorCanvas.value as HTMLCanvasElement, 84, firstName, socketOptions); const scene = new Scene(canvas.value as HTMLCanvasElement, 84, isDark.value, socketOptions); projectStore.scene = scene; projectStore.canvas = canvas.value; projectStore.enableSelectionBox(); rawScene = scene; + rawCursorScene = cursorScene; }) const autoFillProject = async () => { @@ -144,6 +168,7 @@ const onFullscreenChange = () => { onBeforeRouteLeave(() => { const vp = projectStore.scene.viewport; vp.socketPlugin.disconnect(); + rawCursorScene.viewport.socketCursorManager._close(); if (document.exitFullscreen && projectStore.onFullscreen) { projectStore.onFullscreen = false; diff --git a/front-end/src/lib/pixi-tools-v2/class/socketManager.ts b/front-end/src/lib/pixi-tools-v2/class/socketManager.ts index c71534fc..08f5c71f 100644 --- a/front-end/src/lib/pixi-tools-v2/class/socketManager.ts +++ b/front-end/src/lib/pixi-tools-v2/class/socketManager.ts @@ -10,12 +10,11 @@ import { } from '../types/pixi-serialize'; import { Normalizer } from './normalyzer'; import { temporaryNotification } from '../utils/temporary.notification'; -import { ElementPosition } from '../types/pixi-container'; import { GenericContainer } from './genericContainer'; import { FramedContainer } from './framedContainer'; import { CanvasContainer } from '../types/pixi-aliases'; import { LineContainer } from './lineContainer'; -import { LineBezier, Rectangle, TextArea } from '../model/template'; +import { Rectangle, TextArea } from '../model/template'; import { TextContainer } from './textContainer'; export class SocketManager extends Manager { @@ -130,10 +129,6 @@ export class SocketManager extends Manager { } }); - this.canvasSocket.on('peer-mouse-moved', (peerId: string, position: ElementPosition) => { - console.info(`Peer ${peerId} mouse mooved at position: ${position.x},${position.y}`); - }); - this.canvasSocket.on( 'element-colorimetry-updated', (uuid: string, serializedColorimetry: SerializedColorimetry) => { @@ -272,10 +267,6 @@ export class SocketManager extends Manager { this.canvasSocket.emit('delete-element', { uuid, uuidFrame }); } - public updateMouseMoved(position: ElementPosition) { - this.canvasSocket.emit('update-mouse-moved', position); - } - public updateFrameOnChildAdded(uuid: string, uuidChild: string, serialized: SerializedContainer) { this.canvasSocket.emit('add-frame-children', { uuid, uuidChild, serialized }); } diff --git a/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts b/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts index 8373c9a3..b33bbaa0 100644 --- a/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts +++ b/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts @@ -23,7 +23,6 @@ interface CanvasSocketEvents { 'ws-element-updated': (uuid: string, serializedBounds: SerializedContainerBounds) => void; 'ws-line-updated': (uuid: string, serializedBounds: SerializedControl) => void; 'ws-element-modified': () => void; - 'ws-mouse-moved': (position: ElementPosition) => void; 'ws-frame-child-added': ( uuid: string, uuidChild: string, @@ -71,10 +70,6 @@ export class ViewportSocketPlugin extends utils.EventEmitter this.socketManager.updateElementBounds(uuid, serializedBounds); }); - this.on('ws-mouse-moved', (position) => { - this.socketManager.updateMouseMoved(position); - }); - this.on('ws-frame-child-added', (uuid, uuidChild, serialized) => { this.socketManager.updateFrameOnChildAdded(uuid, uuidChild, serialized); }); diff --git a/front-end/src/lib/pixi-tools-v2/plugins/viewportZoomPlugin.ts b/front-end/src/lib/pixi-tools-v2/plugins/viewportZoomPlugin.ts index 0dfd0df4..9a9cafa5 100644 --- a/front-end/src/lib/pixi-tools-v2/plugins/viewportZoomPlugin.ts +++ b/front-end/src/lib/pixi-tools-v2/plugins/viewportZoomPlugin.ts @@ -1,9 +1,10 @@ import { reactive } from 'vue'; import { ContainerManager } from '../class/containerManager'; import { ViewportUI } from '../viewportUI'; +import { ViewportCursor } from '../viewportCursor'; export class ViewportZoomPlugin { - protected readonly viewport: ViewportUI; + protected readonly viewport: ViewportUI | ViewportCursor; protected readonly manager: ContainerManager; protected readonly MAX_ZOOM: number; protected readonly MIN_ZOOM: number; @@ -14,7 +15,7 @@ export class ViewportZoomPlugin { protected CURRENT_STEP: number; public ZOOM = reactive({ value: 0 }); - constructor(viewport: ViewportUI, manager: ContainerManager) { + constructor(viewport: ViewportUI | ViewportCursor, manager?: ContainerManager) { this.viewport = viewport; this.manager = manager; @@ -63,21 +64,23 @@ export class ViewportZoomPlugin { } public updateZoomStep(value: -1 | 1) { - const isInBounds = value + this.CURRENT_STEP <= this.MAX_STEP && value + this.CURRENT_STEP >= 0; - if (!isInBounds) return; + if(this.viewport instanceof ViewportUI) { + const isInBounds = value + this.CURRENT_STEP <= this.MAX_STEP && value + this.CURRENT_STEP >= 0; + if (!isInBounds) return; - const gotoStep = value > 0 ? this.NEXT_STEP : this.PREV_STEP; + const gotoStep = value > 0 ? this.NEXT_STEP : this.PREV_STEP; - let scale = this.MIN_ZOOM; - for (let n = 0; n < gotoStep; n++) { - scale *= this.MULTIPLICATOR; - } + let scale = this.MIN_ZOOM; + for (let n = 0; n < gotoStep; n++) { + scale *= this.MULTIPLICATOR; + } - const point = this.manager.getSelectedCenter(); - if (point) this.viewport.center = point; + const point = this.manager.getSelectedCenter(); + if (point) this.viewport.center = point; - this.viewport.setZoom(scale, true); - this.viewport.emit('zoomed', null); - this.viewport.drawGrid(); + this.viewport.setZoom(scale, true); + this.viewport.emit('zoomed', null); + this.viewport.drawGrid(); + } } } diff --git a/front-end/src/lib/pixi-tools-v2/scene.ts b/front-end/src/lib/pixi-tools-v2/scene.ts index 499158b0..185f3930 100644 --- a/front-end/src/lib/pixi-tools-v2/scene.ts +++ b/front-end/src/lib/pixi-tools-v2/scene.ts @@ -12,7 +12,7 @@ export class Scene extends Application { canvas: HTMLCanvasElement, heightOffset: number, isDark: boolean, - socketOptions?: CanvasSocketOptions, + socketOptions?: CanvasSocketOptions ) { super({ view: canvas, diff --git a/front-end/src/lib/pixi-tools-v2/viewportUI.ts b/front-end/src/lib/pixi-tools-v2/viewportUI.ts index 07a0c993..cc8bb007 100644 --- a/front-end/src/lib/pixi-tools-v2/viewportUI.ts +++ b/front-end/src/lib/pixi-tools-v2/viewportUI.ts @@ -25,6 +25,7 @@ import { GenericContainer } from './class/genericContainer'; import { decimToHex } from './utils/colorsConvertor'; import { dragAttachedLines } from './utils/dragAttachedLines'; import { TextContainer } from './class/textContainer'; +import { MovedEvent } from 'pixi-viewport/dist/types'; export interface TextEditorOptions { text: string; @@ -47,6 +48,15 @@ export interface TextEditorOptions { lineHeight: number; } +export interface ViewportBounds { + x: number; + y: number; + mouseX: number; + mouseY: number; + scaleX: number; + scaleY: number; +} + export class ViewportUI extends Viewport { public readonly scene: Scene; private _isHiddenUI = false; @@ -71,6 +81,7 @@ export class ViewportUI extends Viewport { public readonly activeFrames: Array = reactive([]); public readonly childFrames: Array = shallowReactive([]); + public viewportBounds = reactive>({}); constructor( scene: Scene, @@ -100,6 +111,8 @@ export class ViewportUI extends Viewport { this.grid = new Grid({ color: isDark ? 0x27282d : 0xd9d9d9 }); this.addChildAt(this.grid, 0); + this.viewportBounds.x = this.x; + this.viewportBounds.y = this.y; window.addEventListener('resize', this._onWindowResized.bind(this)); this.on('moved', this._onViewportMoved); @@ -108,10 +121,9 @@ export class ViewportUI extends Viewport { this.on('pointerdown', this._onViewportUnselect); this.on('pointermove', (e: FederatedPointerEvent) => { this.mouse = e.global; - - if (this.socketPlugin) { - this.socketPlugin.emit('ws-mouse-moved', this.mouse); - } + const worldPos = this.toWorld(e.global); + this.viewportBounds.mouseX = worldPos.x; + this.viewportBounds.mouseY = worldPos.y; }); this.on('childAdded', (child: CanvasContainer) => { @@ -242,6 +254,8 @@ export class ViewportUI extends Viewport { } private _onViewportMoved() { + this.viewportBounds.x = this.x; + this.viewportBounds.y = this.y; this.drawGrid(); } @@ -273,6 +287,11 @@ export class ViewportUI extends Viewport { this.updateUI(size); } + + this.viewportBounds.x = this.x; + this.viewportBounds.y = this.y; + this.viewportBounds.scaleX = this.scale.x; + this.viewportBounds.scaleY = this.scale.y; } private updateUI(size: ElementSize) { diff --git a/front-end/src/store/modules/project.store.ts b/front-end/src/store/modules/project.store.ts index ddbffff6..247389ae 100644 --- a/front-end/src/store/modules/project.store.ts +++ b/front-end/src/store/modules/project.store.ts @@ -43,6 +43,9 @@ export const useProjectStore = defineStore('project', { getSelected(this: ProjectStore) { return this.scene?.viewport?.manager?.selectedContainers || []; }, + getViewportBounds(this: ProjectStore) { + return this.scene?.viewport.viewportBounds; + }, getImages(this: ProjectStore) { if (!this.pdfViewerOpen) return []; this.refreshPdfViewer; From 51ef84cdff1e40a1a2416716048a9a1ad58ab396 Mon Sep 17 00:00:00 2001 From: codefactor-io Date: Fri, 16 Jun 2023 05:01:39 +0000 Subject: [PATCH 20/21] [CodeFactor] Apply fixes --- front-end/src/lib/pixi-tools-v2/viewportCursor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/front-end/src/lib/pixi-tools-v2/viewportCursor.ts b/front-end/src/lib/pixi-tools-v2/viewportCursor.ts index 51b2818a..f10b4f16 100644 --- a/front-end/src/lib/pixi-tools-v2/viewportCursor.ts +++ b/front-end/src/lib/pixi-tools-v2/viewportCursor.ts @@ -92,8 +92,8 @@ export class ViewportCursor extends Viewport { } getRandomSoftColor() { - var softColors = ["#F5A9A9", "#F5D0A9", "#F5F6CE", "#D0F5A9", "#A9F5A9", "#A9F5F2", "#A9D0F5", "#A9A9F5", "#D0A9F5", "#F5A9F2"]; - var randomIndex = Math.floor(Math.random() * softColors.length); + const softColors = ["#F5A9A9", "#F5D0A9", "#F5F6CE", "#D0F5A9", "#A9F5A9", "#A9F5F2", "#A9D0F5", "#A9A9F5", "#D0A9F5", "#F5A9F2"]; + const randomIndex = Math.floor(Math.random() * softColors.length); return hexToDecim(softColors[randomIndex]); } From 761344f77b67e4345828be45a4e1ae594d6fedcf Mon Sep 17 00:00:00 2001 From: Samson Christopher <91219719+Maghwyn@users.noreply.github.com> Date: Fri, 16 Jun 2023 07:02:48 +0200 Subject: [PATCH 21/21] fix(import): Remove unused import --- front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts | 1 - front-end/src/lib/pixi-tools-v2/viewportUI.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts b/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts index b33bbaa0..d4786a40 100644 --- a/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts +++ b/front-end/src/lib/pixi-tools-v2/plugins/viewportSocketPlugin.ts @@ -3,7 +3,6 @@ import { ManagerOptions } from 'socket.io-client'; import { ViewportUI } from '../viewportUI'; import { CanvasContainer } from '../types/pixi-aliases'; -import { ElementPosition } from '../types/pixi-container'; import { SocketManager } from '../class/socketManager'; import { ModelGraphics } from '../types/pixi-class'; import { FramedContainer } from '../class/framedContainer'; diff --git a/front-end/src/lib/pixi-tools-v2/viewportUI.ts b/front-end/src/lib/pixi-tools-v2/viewportUI.ts index cc8bb007..fc8db79c 100644 --- a/front-end/src/lib/pixi-tools-v2/viewportUI.ts +++ b/front-end/src/lib/pixi-tools-v2/viewportUI.ts @@ -25,7 +25,6 @@ import { GenericContainer } from './class/genericContainer'; import { decimToHex } from './utils/colorsConvertor'; import { dragAttachedLines } from './utils/dragAttachedLines'; import { TextContainer } from './class/textContainer'; -import { MovedEvent } from 'pixi-viewport/dist/types'; export interface TextEditorOptions { text: string;