diff --git a/src/Components/Arc.ts b/src/Components/Arc.ts index f92eda9..0d1c180 100644 --- a/src/Components/Arc.ts +++ b/src/Components/Arc.ts @@ -188,5 +188,12 @@ class Arc extends Component { this._text.setText(Math.round((angle * 180) / Math.PI).toString() + " °"); this._text.position.set(-60 / cameraZoom, 0, this._text.position.z); } + + public getAngle(unit = "radians"): number { + if (unit === "degrees") { + return this._calcAngle() * (180 / Math.PI); + } + return this._calcAngle(); + } } export default Arc; diff --git a/src/Components/Label.ts b/src/Components/Label.ts index 95dd946..9e4534e 100644 --- a/src/Components/Label.ts +++ b/src/Components/Label.ts @@ -1,4 +1,4 @@ -import { Vector2, Vector3, Object3D, Group, OrthographicCamera } from "three"; +import { Vector2, Object3D, Group, OrthographicCamera } from "three"; import { toVector3 } from "../utils"; import Line from "./Line"; import Text from "./Text"; @@ -8,26 +8,33 @@ import { InputPosition } from "./types"; const SCALING_FACTOR = 10; type LabelOptions = { - text: string; start: InputPosition; - deltaX?: number; - deltaY?: number; + deltaX: number; + deltaY: number; +}; + +const defaultLabelOptions: LabelOptions = { + start: new Vector2(0, 0), + deltaX: 4, + deltaY: 20, }; class Label extends Component { - position: Vector3; object: Object3D; draggable = undefined; - constructor({ - text, - start = new Vector2(0, 0), - deltaX = 20, - deltaY = 4, - }: LabelOptions) { + constructor(text: string, options?: LabelOptions) { + const { start, deltaX, deltaY } = { + ...defaultLabelOptions, + ...options, + }; super(); // set position of the point instance - this.position = toVector3(start); + this.position.set( + toVector3(start).x, + toVector3(start).y, + toVector3(start).z + ); // calculate break and end points const breakPoint = this.calculateBreakPoint(deltaX, deltaY); @@ -38,15 +45,14 @@ class Label extends Component { const line2 = new Line(breakPoint, endPoint); const textComponent = new Text(text, { color: "black", - fontSize: 22, + fontSize: 15, anchorY: "middle", anchorX: deltaX < 0 ? "right" : "left", }); - textComponent.position.set( + textComponent.setPosition([ endPoint.x + (deltaX < 0 ? -1 : 1) * 10, endPoint.y, - 0.1 - ); + ]); // Create a group to contain both lines and text this.object = new Group(); @@ -55,7 +61,7 @@ class Label extends Component { this.object.add(textComponent); // set position of the group - this.object.position.set(this.position.x, this.position.y, 0); + this.object.position.set(1, 5, 5); } private calculateEndPoint(deltaX: number, deltaY: number) { diff --git a/src/Components/Line.ts b/src/Components/Line.ts index 304c3e7..ac71f0e 100644 --- a/src/Components/Line.ts +++ b/src/Components/Line.ts @@ -8,7 +8,7 @@ import { } from "three"; import { Line2, LineGeometry, LineMaterial } from "three-fatline"; import { toVector2 } from "../utils"; -import { Collider, Component } from "./interfaces"; +import { Collider, Component, Draggable } from "./interfaces"; import { InputPosition } from "./types"; const ARROWHEAD_LENGTH = 12; @@ -20,6 +20,7 @@ export type LineOptions = { dashed?: boolean; opacity?: number; transparent?: boolean; + draggable?: Draggable; }; export const defaultLineOptions: LineOptions = { @@ -29,24 +30,31 @@ export const defaultLineOptions: LineOptions = { dashed: false, opacity: 1, transparent: false, + draggable: undefined, }; class Line extends Component implements Collider { start: InputPosition; end: InputPosition; - draggable = undefined; arrowhead: boolean; constructor(start: InputPosition, end: InputPosition, options?: LineOptions) { super(); - const { color, lineWidth, arrowhead, dashed, opacity, transparent } = { + const { + color, + lineWidth, + arrowhead, + dashed, + opacity, + transparent, + draggable, + } = { ...defaultLineOptions, ...options, }; this.start = start; this.end = end; this.arrowhead = arrowhead ?? false; - this.material = new LineMaterial({ color: color, linewidth: lineWidth, @@ -67,6 +75,7 @@ class Line extends Component implements Collider { this.add(arrowheadLine); } this.initialUpdateGeometry(start, end); + this.draggable = draggable; } collidesWith(other: Object3D): boolean { @@ -151,22 +160,22 @@ class Line extends Component implements Collider { (this.geometry as LineGeometry).setPositions([ startPosition.x, startPosition.y, - 1, + 1.1, endPosition.x, endPosition.y, - 1, + 1.1, ]); } - setEnd(end: InputPosition) { + public setEnd(end: InputPosition) { this.end = end; } - setStart(start: InputPosition) { + public setStart(start: InputPosition) { this.start = start; } - setPosition(start: InputPosition, end: InputPosition) { + public setPosition(start: InputPosition, end: InputPosition) { this.start = start; this.end = end; } diff --git a/src/Components/Point.ts b/src/Components/Point.ts index 4719b1f..b60fecd 100644 --- a/src/Components/Point.ts +++ b/src/Components/Point.ts @@ -28,7 +28,6 @@ const defaultPointOptions = { class Point extends Component implements Collider, DragListener { dragListeners: ((point: Point) => void)[]; - constructor(x = 0, y = 0, options?: PointOptions) { super(); const { color, draggable, decimals, label, dragListeners } = { @@ -63,6 +62,7 @@ class Point extends Component implements Collider, DragListener { anchorY: "middle", anchorX: "left", position: [15, 0], + responsiveScale: false, } ); text.name = "label"; diff --git a/src/Components/Shape.ts b/src/Components/Shape.ts index f24a732..8c7c28d 100644 --- a/src/Components/Shape.ts +++ b/src/Components/Shape.ts @@ -76,7 +76,13 @@ class Polygon extends Component implements Collider, DragListener { lines.push([lastVertex, firstVertex]); lines.forEach((l) => { - group.add(new Line(l[0], l[1], { color: 0x080007, opacity: opacity })); + group.add( + new Line(l[0], l[1], { + color: 0x080007, + opacity: opacity, + draggable: undefined, + }) + ); }); this.add(group); this.object = group; @@ -127,15 +133,6 @@ class Polygon extends Component implements Collider, DragListener { toVector2(position).y, this.position.z ); - this.children.forEach((child) => { - if (child instanceof Object3D) { - child.position.set( - toVector2(position).x, - toVector2(position).y, - this.position.z - ); - } - }); } /* update(camera: OrthographicCamera) { diff --git a/src/Components/Text.ts b/src/Components/Text.ts index bc7a318..ead243b 100644 --- a/src/Components/Text.ts +++ b/src/Components/Text.ts @@ -13,6 +13,7 @@ type TextOptions = { anchorY?: "top" | "middle" | "bottom"; anchorX?: "left" | "center" | "right"; weight?: fontWeight; + responsiveScale?: boolean; }; const defaultTextOptions = { @@ -22,6 +23,7 @@ const defaultTextOptions = { anchorX: "left", anchorY: "bottom", weight: "regular" as fontWeight, + responsiveScale: true, }; const fontMap = { @@ -36,11 +38,20 @@ type TroikaTextType = InstanceType; class Text extends Component implements Collider { draggable = undefined; renderText: TroikaTextType; + responsiveScale: boolean; constructor(text?: string, options?: TextOptions) { super(); - const { position, color, fontSize, anchorX, anchorY, weight } = { + const { + position, + color, + fontSize, + anchorX, + anchorY, + weight, + responsiveScale, + } = { ...defaultTextOptions, ...options, }; @@ -58,6 +69,7 @@ class Text extends Component implements Collider { this.renderText = renderText; this.add(renderText); this.position.set(pos.x, pos.y, 0.1); + this.responsiveScale = responsiveScale; } collidesWith(other: Object3D): boolean { @@ -99,7 +111,9 @@ class Text extends Component implements Collider { } update(camera: OrthographicCamera) { - this.scale.set(1 / camera.zoom, 1 / camera.zoom, 1); + if (this.responsiveScale) { + this.scale.set(1 / camera.zoom, 1 / camera.zoom, 1); + } } } diff --git a/src/Components/Vector.ts b/src/Components/Vector.ts index 086e562..9a87350 100644 --- a/src/Components/Vector.ts +++ b/src/Components/Vector.ts @@ -1,31 +1,39 @@ import { Vector2, OrthographicCamera } from "three"; import { toVector2, toVector3 } from "./../utils"; import Line from "./Line"; +import { Draggable } from "./interfaces"; import { InputPosition } from "./types"; const defaultVectorOptions = { color: 0x000000, normalize: true, + draggable: undefined, }; export type VectorOptions = { color?: number; normalize?: boolean; + draggable?: Draggable; }; class Vector extends Line { private vector: InputPosition; constructor( - position: InputPosition, + origin: InputPosition, vector: InputPosition, options?: VectorOptions ) { - const { color, normalize } = { + const { color, normalize, draggable } = { ...defaultVectorOptions, ...options, }; - super(position, position, { lineWidth: 4, arrowhead: true, color: color }); + super(origin, origin, { + lineWidth: 4, + arrowhead: true, + color: color, + draggable: draggable, + }); if (normalize) { this.vector = toVector2(vector).normalize(); } else { @@ -52,6 +60,10 @@ class Vector extends Line { this.start = position; } + public getOriginPoint(): InputPosition { + return this.start; + } + public normalize(): void { this.vector = toVector2(this.vector).normalize(); } diff --git a/src/index.ts b/src/index.ts index fe8dbf9..abb3089 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,5 +17,4 @@ export { default as Text } from "./Components/Text"; export { default as Vector } from "./Components/Vector"; export { default as Fraction } from "./Components/Derived/Fraction"; export { default as SVGLoader } from "./Components/SVGLoader"; - export * as three from "three";