diff --git a/package-lock.json b/package-lock.json index 06c5dcc39efd4b76dbdbfab57cf0dafb4f2a5bb7..3009cd16186c6dd561ce72562430aa420572aacf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "medsurf-draw", - "version": "1.0.231", + "version": "1.0.233", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "medsurf-draw", - "version": "1.0.231", + "version": "1.0.233", "license": "MIT", "dependencies": { - "@ascii-dev-user/medsurf-lib": "^1.18.0-141", + "@ascii-dev-user/medsurf-lib": "^1.18.0-143", "@babel/core": "^7.8.4", "@pixi-essentials/cull": "^1.0.12", "debounce": "^1.2.1", @@ -91,9 +91,9 @@ } }, "node_modules/@ascii-dev-user/medsurf-lib": { - "version": "1.18.0-141", - "resolved": "https://registry.npmjs.org/@ascii-dev-user/medsurf-lib/-/medsurf-lib-1.18.0-141.tgz", - "integrity": "sha512-CUquGXjOUGVCvjwf1UEw0seSfIfYWLPh1sX7lkdL9tDbS0oxlKW4P8YyNzMIsL1W3dQ0p43bJWiU4i3bGGubjg==", + "version": "1.18.0-143", + "resolved": "https://registry.npmjs.org/@ascii-dev-user/medsurf-lib/-/medsurf-lib-1.18.0-143.tgz", + "integrity": "sha512-vpX3wbOxvtnh6KMqeUgD+Lts/9yLg3Ge+z5xAhz0Yq8YBul/w7hCpoh5QFnqgw8SdjBbqWiDgX7d7HWJ1SXniQ==", "dependencies": { "lodash.clonedeep": "^4.5.0", "tslib": "^2.3.0" @@ -12104,9 +12104,9 @@ } }, "@ascii-dev-user/medsurf-lib": { - "version": "1.18.0-141", - "resolved": "https://registry.npmjs.org/@ascii-dev-user/medsurf-lib/-/medsurf-lib-1.18.0-141.tgz", - "integrity": "sha512-CUquGXjOUGVCvjwf1UEw0seSfIfYWLPh1sX7lkdL9tDbS0oxlKW4P8YyNzMIsL1W3dQ0p43bJWiU4i3bGGubjg==", + "version": "1.18.0-143", + "resolved": "https://registry.npmjs.org/@ascii-dev-user/medsurf-lib/-/medsurf-lib-1.18.0-143.tgz", + "integrity": "sha512-vpX3wbOxvtnh6KMqeUgD+Lts/9yLg3Ge+z5xAhz0Yq8YBul/w7hCpoh5QFnqgw8SdjBbqWiDgX7d7HWJ1SXniQ==", "requires": { "lodash.clonedeep": "^4.5.0", "tslib": "^2.3.0" diff --git a/package.json b/package.json index 365c8eb9863a94079360c1ccd4793a99f86e0fd4..dd4134927836c45d5e5b2be68883799b3a2c0f7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "medsurf-draw", - "version": "1.0.232", + "version": "1.0.233", "description": "Draw annotations on jpg/zoomify images, based on PIXI.js", "keywords": [ "draw", @@ -29,7 +29,7 @@ "author": "Gottsponer Andrea Leonardo", "license": "MIT", "dependencies": { - "@ascii-dev-user/medsurf-lib": "^1.18.0-141", + "@ascii-dev-user/medsurf-lib": "^1.18.0-143", "@babel/core": "^7.8.4", "@pixi-essentials/cull": "^1.0.12", "debounce": "^1.2.1", diff --git a/src/app/index.ts b/src/app/index.ts index ee1ea0916e6e10d5c74e88723ac9a00d3c43466b..8973d19a6a7a4d73fd83e9e487a379bc51114d0c 100644 --- a/src/app/index.ts +++ b/src/app/index.ts @@ -17,7 +17,9 @@ import { PixiPlugin } from 'gsap/PixiPlugin.js'; - Rotation: convert to integer - Menu anzeigen -> Hauptmenu wird nicht immer korrekt ausgeblendet. - Toggle submenus -> change hitbox when open and reset selection when outside - Selektion der Fläche -> wird nicht geändert. scheint andere elemente zu ändern -> no events ??? + - Selektion der Fläche -> wird nicht geändert. scheint andere elemente zu ändern -> no events ??? + - Fill unset line color creates black lines -> fix this + Selftest add new element only for selftest -> use ellipse for this (make ellipse smaller once clicked) - otherwise elements like arrow / rectangle / ... will be shown (not nice) FillLine: "isPointInPolygon" and "getNearestPointForPoint" function wrong; Line: Hitbox not defined -> HOW TO ??? Interactions anpassen; siehe dazu CloneInteraction -> kann einfacher so umgesetzt werden (Scale auf Draw nicht mehr notwendig; ausbauen) -> Test: Move events in Draw / Copy / Selection Generator @@ -1202,6 +1204,7 @@ ready(() => { loader.load(async (loader: PIXI.Loader, resources: any) => { //<editor-fold desc="PIXI"> PIXI.settings.PRECISION_FRAGMENT = PIXI.PRECISION.HIGH; + PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false; // PIXI.settings.ROUND_PIXELS = true; app = new PIXI.Application({ @@ -1427,7 +1430,30 @@ buttonVirtualPointer.addEventListener("click", () => { virtualPointer.visible = !virtualPointer.visible; }); buttonTest.addEventListener("click", () => { - (elementsArray['fill1'] as MedsurfDraw.FillCollection).onColor(MedsurfDraw.ColorMode.FILL, true, 0x123456, 0.6); + const test = new PIXI.Graphics(); + + test.lineStyle(5, 0xffffff, 1); + test.moveTo(300, 300); + test.lineTo(600, 400); + + image.addChild(test); + + console.log(test); + + setTimeout(() => { + // @ts-ignore + console.log(test.geometry.graphicsData); + + // @ts-ignore + test.hitArea = new PIXI.Polygon(test.geometry.graphicsData[0].shape.points); + + test.interactive = true; + test.on('pointerover', () => { + console.log("okokokoko") + }); + }, 300); + + (elementsArray['fill1'] as MedsurfDraw.FillCollection).onColor(MedsurfDraw.ColorMode.LINE, false, undefined, undefined); /* Text add middle point button * / line1.onButtonAddMiddlePoint(image); diff --git a/src/lib/elements/basics/BezierLine.ts b/src/lib/elements/basics/BezierLine.ts index 42fa7c36842da171ca4eae809e2d3f0eb7e0ffe4..c70354a0d447098afb818ac96a5a61ff40c8d77c 100644 --- a/src/lib/elements/basics/BezierLine.ts +++ b/src/lib/elements/basics/BezierLine.ts @@ -1,7 +1,8 @@ +import * as PIXI from "pixi.js-legacy"; import * as Models from "@ascii-dev-user/medsurf-lib/models"; import {BaseGraphics} from "../../bases/elements/BaseGraphics"; import {ControlPointsModel, StraightLinePointsModel} from "./StraightLine"; -import * as PIXI from "pixi.js-legacy"; +import {Design} from "../../config/design"; import {debounce} from "debounce"; /** @@ -39,7 +40,7 @@ export class BezierLine extends BaseGraphics<BezierLineModel> { super(model); //<editor-fold desc="Methods"> - this._debounceUpdateHitAreaMethod = debounce(this.updateHitArea.bind(this), 500).bind(this); + this._debounceUpdateHitAreaMethod = debounce(this.updateHitArea.bind(this), 50).bind(this); //</editor-fold> //<editor-fold desc="Events"> @@ -81,7 +82,11 @@ export class BezierLine extends BaseGraphics<BezierLineModel> { this.clear(); // Draw line - this.lineStyle(this.lineWidth, this.options.lineColor, this.options.lineAlpha); + if (this.options.hasLine) { + this.lineStyle(this.lineWidth, this.options.lineColor, this.options.lineAlpha); + } else { + this.lineStyle(this.lineWidth, this.options.lineColor, 0.00000001); + } this.moveTo(this.points.start.x, this.points.start.y); this.bezierCurveTo(this.points.controlPointsPrevious.c2.x, this.points.controlPointsPrevious.c2.y, this.points.controlPointsNext.c1.x, this.points.controlPointsNext.c1.y, this.points.end.x, this.points.end.y); // TODO remove this.endFill(); @@ -104,12 +109,54 @@ export class BezierLine extends BaseGraphics<BezierLineModel> { * Update hit area */ public updateHitArea(): void { - if (!this._destroyed) { - // this.hitArea = this.currentPath; + if (!this._destroyed && this.geometry.graphicsData.length > 0) { // @ts-ignore - this.hitArea = new PIXI.Polygon(this.geometry.points); + this.hitArea = this.lineToPolygon(this.lineWidth * Design.line.hitboxLineWidthAddition, this.geometry.graphicsData[0].shape.points) } } + + /** + * Line zo polygon + * + * @param distance + * @param points + */ + public lineToPolygon(distance: number, points: number[]): PIXI.Polygon { + const numPoints = points.length / 2; + const output = new Array(points.length * 2); + for (let i = 0; i < numPoints; i++) { + const j = i * 2; + + // Position of current point + const x = points[j]; + const y = points[j + 1]; + + // Start + const x0 = points[j - 2] !== undefined ? points[j - 2] : x; + const y0 = points[j - 1] !== undefined ? points[j - 1] : y; + + // End + const x1 = points[j + 2] !== undefined ? points[j + 2] : x; + const y1 = points[j + 3] !== undefined ? points[j + 3] : y; + + // Get the angle of the line + const a = Math.atan2(-x1 + x0, y1 - y0); + const deltaX = distance * Math.cos(a); + const deltaY = distance * Math.sin(a); + + // Add the x, y at the beginning + output[j] = x + deltaX; + output[j + 1] = y + deltaY; + + // Add the reflected x, y at the end + output[(output.length - 1) - j - 1] = x - deltaX; + output[(output.length - 1) - j] = y - deltaY; + } + // close the shape + output.push(output[0], output[1]); + + return new PIXI.Polygon(output); + } //</editor-fold> //<editor-fold desc="Getter and Setter"> diff --git a/src/lib/elements/basics/QuadraticCurve.ts b/src/lib/elements/basics/QuadraticCurve.ts index 439e28cb2024ab1b5cf9026d20f7749e129a5996..2b0a0bb4b6c5522d347b6f45a3b72573c2792992 100644 --- a/src/lib/elements/basics/QuadraticCurve.ts +++ b/src/lib/elements/basics/QuadraticCurve.ts @@ -2,6 +2,7 @@ import * as PIXI from "pixi.js-legacy"; import * as Models from "@ascii-dev-user/medsurf-lib/models"; import {BaseGraphics} from "../../bases/elements/BaseGraphics"; import {ControlPointsModel, StraightLinePointsModel} from "./StraightLine"; +import {Design} from "../../config/design"; import {debounce} from "debounce"; /** @@ -39,7 +40,7 @@ export class QuadraticCurve extends BaseGraphics<QuadraticCurveModel> { super(model); //<editor-fold desc="Methods"> - this._debounceUpdateHitAreaMethod = debounce(this.updateHitArea.bind(this), 500).bind(this); + this._debounceUpdateHitAreaMethod = debounce(this.updateHitArea.bind(this), 50).bind(this); //</editor-fold> //<editor-fold desc="Events"> @@ -81,7 +82,11 @@ export class QuadraticCurve extends BaseGraphics<QuadraticCurveModel> { this.clear(); // Draw line - this.lineStyle(this.lineWidth, this.options.lineColor, this.options.lineAlpha); + if (this.options.hasLine) { + this.lineStyle(this.lineWidth, this.options.lineColor, this.options.lineAlpha); + } else { + this.lineStyle(this.lineWidth, this.options.lineColor, 0.00000001); + } this.moveTo(this.points.start.x, this.points.start.y); if (this.points.start.x == this.points.end.x && this.points.end.x == this.points.controlPoint.x || this.points.start.y == this.points.end.y && this.points.end.y == this.points.controlPoint.y @@ -115,11 +120,53 @@ export class QuadraticCurve extends BaseGraphics<QuadraticCurveModel> { * Update hit area */ public updateHitArea(): void { - if (!this._destroyed) { - // this.hitArea = this.currentPath; + if (!this._destroyed && this.geometry.graphicsData.length > 0) { // @ts-ignore - this.hitArea = new PIXI.Polygon(this.geometry.points); + this.hitArea = this.lineToPolygon(this.lineWidth * Design.line.hitboxLineWidthAddition, this.geometry.graphicsData[0].shape.points) + } + } + + /** + * Line zo polygon + * + * @param distance + * @param points + */ + public lineToPolygon(distance: number, points: number[]): PIXI.Polygon { + const numPoints = points.length / 2; + const output = new Array(points.length * 2); + for (let i = 0; i < numPoints; i++) { + const j = i * 2; + + // Position of current point + const x = points[j]; + const y = points[j + 1]; + + // Start + const x0 = points[j - 2] !== undefined ? points[j - 2] : x; + const y0 = points[j - 1] !== undefined ? points[j - 1] : y; + + // End + const x1 = points[j + 2] !== undefined ? points[j + 2] : x; + const y1 = points[j + 3] !== undefined ? points[j + 3] : y; + + // Get the angle of the line + const a = Math.atan2(-x1 + x0, y1 - y0); + const deltaX = distance * Math.cos(a); + const deltaY = distance * Math.sin(a); + + // Add the x, y at the beginning + output[j] = x + deltaX; + output[j + 1] = y + deltaY; + + // Add the reflected x, y at the end + output[(output.length - 1) - j - 1] = x - deltaX; + output[(output.length - 1) - j] = y - deltaY; } + // close the shape + output.push(output[0], output[1]); + + return new PIXI.Polygon(output); } //</editor-fold> diff --git a/src/lib/elements/basics/StraightLine.ts b/src/lib/elements/basics/StraightLine.ts index 086873fd1e24db44aa9b00b159606b433054aa7c..b14a913874efc3031dfbecc7afceec93b2fd1ae1 100644 --- a/src/lib/elements/basics/StraightLine.ts +++ b/src/lib/elements/basics/StraightLine.ts @@ -49,7 +49,7 @@ export class StraightLine extends BaseGraphics<StraightLineModel> { super(model); //<editor-fold desc="Methods"> - this._debounceUpdateHitAreaMethod = debounce(this.updateHitArea.bind(this), 500).bind(this); + this._debounceUpdateHitAreaMethod = debounce(this.updateHitArea.bind(this), 50).bind(this); //</editor-fold> //<editor-fold desc="Events"> @@ -91,18 +91,24 @@ export class StraightLine extends BaseGraphics<StraightLineModel> { this.clear(); // Draw line - this.lineStyle(this.lineWidth, this.options.lineColor, this.options.lineAlpha); + if (this.options.hasLine) { + this.lineStyle(this.lineWidth, this.options.lineColor, this.options.lineAlpha); + } else { + this.lineStyle(this.lineWidth, this.options.lineColor, 0.00000001); + } this.moveTo(this.points.start.x, this.points.start.y); this.lineTo(this.points.end.x, this.points.end.y); // TODO test this: this._lineElement.drawPolygon([new PIXI.Point(points.start.x, points.start.y), new PIXI.Point(points.end.x, points.end.y)]); // TODO remove this.endFill(); // Hit area update + /* TODO find better solution for this * / this.lineStyle(this.lineWidth + Design.line.hitboxLineWidthAddition, this.options.lineColor, 0.00000001); this.moveTo(this.points.start.x, this.points.start.y); this.lineTo(this.points.end.x, this.points.end.y); // TODO test this: this._lineElement.drawPolygon([new PIXI.Point(points.start.x, points.start.y), new PIXI.Point(points.end.x, points.end.y)]); // TODO remove this.endFill(); + /**/ // Ensure geometry points are set this.emit("debouncedUpdateHitArea"); @@ -113,27 +119,53 @@ export class StraightLine extends BaseGraphics<StraightLineModel> { * Update hit area */ public updateHitArea(): void { - if (!this._destroyed) { - /* - console.log("-----"); - console.log(this.currentPath); - console.log(this.geometry); - console.log(this._localBounds); - console.log(this._bounds); - console.log(this.vertexData); - // const rectangle = new PIXI.Polygon([new PIXI.Point(this._bounds.minX, this._bounds.minY), new PIXI.Point(this._bounds.maxX, this._bounds.maxY)]); - const rectangle = new PIXI.Rectangle(this._bounds.minX, this._bounds.minY, this._bounds.maxX - this._bounds.minX, this._bounds.maxY - this._bounds.minY); - rectangle.pad(5, 5); - console.log(rectangle) - this.hitArea = rectangle; - - this.hitArea = this.currentPath; - this.hitArea = new PIXI.Polygon(this.currentPath.points); - */ - + if (!this._destroyed && this.geometry.graphicsData.length > 0) { // @ts-ignore - this.hitArea = new PIXI.Polygon(this.geometry.points); + this.hitArea = this.lineToPolygon(this.lineWidth * Design.line.hitboxLineWidthAddition, this.geometry.graphicsData[0].shape.points) + } + } + + /** + * Line zo polygon + * + * @param distance + * @param points + */ + public lineToPolygon(distance: number, points: number[]): PIXI.Polygon { + const numPoints = points.length / 2; + const output = new Array(points.length * 2); + for (let i = 0; i < numPoints; i++) { + const j = i * 2; + + // Position of current point + const x = points[j]; + const y = points[j + 1]; + + // Start + const x0 = points[j - 2] !== undefined ? points[j - 2] : x; + const y0 = points[j - 1] !== undefined ? points[j - 1] : y; + + // End + const x1 = points[j + 2] !== undefined ? points[j + 2] : x; + const y1 = points[j + 3] !== undefined ? points[j + 3] : y; + + // Get the angle of the line + const a = Math.atan2(-x1 + x0, y1 - y0); + const deltaX = distance * Math.cos(a); + const deltaY = distance * Math.sin(a); + + // Add the x, y at the beginning + output[j] = x + deltaX; + output[j + 1] = y + deltaY; + + // Add the reflected x, y at the end + output[(output.length - 1) - j - 1] = x - deltaX; + output[(output.length - 1) - j] = y - deltaY; } + // close the shape + output.push(output[0], output[1]); + + return new PIXI.Polygon(output); } //</editor-fold> diff --git a/src/lib/elements/connections/Line.ts b/src/lib/elements/connections/Line.ts index 744131fb45a43434326433af2275724aa1fa74cc..529fe29bf27784cdbc9b5e1a656794e04b1fda3c 100644 --- a/src/lib/elements/connections/Line.ts +++ b/src/lib/elements/connections/Line.ts @@ -445,29 +445,34 @@ export class Line extends BaseElementContainer<Models.Line, BaseElementContainer const oldType = this.type; // Get line model - const points = this._getLinePointsModel(); - if (points) { - // -- Line control point element - this._lineControlPointElement.points = points; - - // Check type change - if (this.type !== oldType) { - // Elements - // -- Line element - this._lineElement.destroy(); - - // Get line object - const result = this._getLineObject(points); - if (result) { - this._lineElement = result; - this.addChild(this._lineElement); + try { + const points = this._getLinePointsModel(); + if (points) { + // -- Line control point element + this._lineControlPointElement.points = points; + + // Check type change + if (this.type !== oldType) { + // Elements + // -- Line element + this._lineElement.destroy(); + + // Get line object + const result = this._getLineObject(points); + if (result) { + this._lineElement = result; + this.addChild(this._lineElement); + } + } else { + // -- Line element + this._lineElement.points = points; } - } else { - // -- Line element - this._lineElement.points = points; } + this._lineElement.draw(); + } + catch (e) { + this.emit("debounceDraw"); } - this._lineElement.draw(); } // -- Line corner element if (this._lineCornerElement) { diff --git a/src/lib/elements/fills/FillCollection.ts b/src/lib/elements/fills/FillCollection.ts index d1f178a16c71833fe53a1d412ab08e3ee39d36d7..f522cd9f75ad96bde2d6b19315f7b96cdb76eefb 100644 --- a/src/lib/elements/fills/FillCollection.ts +++ b/src/lib/elements/fills/FillCollection.ts @@ -1,16 +1,16 @@ -import * as PIXI from "pixi.js-legacy"; -import * as MedsurfDraw from "../../public-api"; +import * as PIXI from 'pixi.js-legacy'; +import * as MedsurfDraw from '../../public-api'; import * as Models from '@ascii-dev-user/medsurf-lib/models'; import { v4 as uuidv4 } from 'uuid'; -import {Design} from "../../config/design"; +import { Design } from '../../config/design'; import { BaseElementContainer, BaseElementContainerModel, ColorMode, NumberMode -} from "../../bases/elements/BaseElementContainer"; -import {BaseGraphics} from "../../bases/elements/BaseGraphics"; -import {debounce} from "debounce"; +} from '../../bases/elements/BaseElementContainer'; +import { BaseGraphics } from '../../bases/elements/BaseGraphics'; +import { debounce } from 'debounce'; /** * Fill collection @@ -671,11 +671,11 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection, let rY: number; // @ts-ignore - for (let i = 0; i < line._lineElement.geometry.points.length; i = i + 2) { + for (let i = 0; i < line._lineElement.geometry.graphicsData[0].shape.points.length; i = i + 2) { // @ts-ignore - const tmpX = line._lineElement.geometry.points[i]; + const tmpX = line._lineElement.geometry.graphicsData[0].shape.points[i]; // @ts-ignore - const tmpY = line._lineElement.geometry.points[i + 1]; + const tmpY = line._lineElement.geometry.graphicsData[0].shape.points[i + 1]; const tmpDelta = Math.abs(point.x - tmpX) + Math.abs(point.y - tmpY); @@ -1480,7 +1480,12 @@ export class FillCollection extends BaseElementContainer<Models.FillCollection, //<editor-fold desc="Bezier"> public onButtonBezier(override?: boolean): void { this.lines.forEach((line) => line.onButtonBezier(override)); - // TODO event. call again line.draw(); + + // Draw + this.emit("debounceDraw"); + + // Control update elements + this.getImage().controlUpdateElements(); } //</editor-fold> //<editor-fold desc="Color">