Socket
Socket
Sign inDemoInstall

js-draw

Package Overview
Dependencies
Maintainers
1
Versions
117
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

js-draw - npm Package Compare versions

Comparing version 0.4.0 to 0.4.1

.github/pull_request_template.md

7

CHANGELOG.md

@@ -0,1 +1,8 @@

# 0.4.1
* Bug fixes
* Fix in-progress strokes occasionally flickering and disappearing.
* This was caused by a division-by-zero error.
* Increase contrast between disabled and enabled buttons.
* Copy selected text objects as text.
# 0.4.0

@@ -2,0 +9,0 @@ * Moved the selection tool rotate handle to the top, added resize horizontally and resize vertically handles.

1

dist/src/components/AbstractComponent.js

@@ -51,2 +51,3 @@ var _a;

}
// Returns a copy of this component.
clone() {

@@ -53,0 +54,0 @@ const clone = this.createClone();

@@ -32,2 +32,3 @@ import AbstractRenderer from '../../rendering/renderers/AbstractRenderer';

private roundPoint;
private approxCurrentCurveLength;
private finalizeCurrentCurve;

@@ -34,0 +35,0 @@ private currentSegmentToPath;

70

dist/src/components/builders/FreehandLineBuilder.js

@@ -120,3 +120,3 @@ import { Bezier } from 'bezier-js';

build() {
if (this.lastPoint) {
if (this.lastPoint && (this.lowerSegments.length === 0 || this.approxCurrentCurveLength() > this.curveStartWidth * 2)) {
this.finalizeCurrentCurve();

@@ -133,2 +133,14 @@ }

}
// Returns the distance between the start, control, and end points of the curve.
approxCurrentCurveLength() {
if (!this.currentCurve) {
return 0;
}
const startPt = Vec2.ofXY(this.currentCurve.points[0]);
const controlPt = Vec2.ofXY(this.currentCurve.points[1]);
const endPt = Vec2.ofXY(this.currentCurve.points[2]);
const toControlDist = startPt.minus(controlPt).length();
const toEndDist = endPt.minus(controlPt).length();
return toControlDist + toEndDist;
}
finalizeCurrentCurve() {

@@ -209,6 +221,4 @@ // Case where no points have been added

endVec = endVec.times(this.curveEndWidth / 2);
if (isNaN(startVec.magnitude())) {
// TODO: This can happen when events are too close together. Find out why and
// fix.
console.error('startVec is NaN', startVec, endVec, this.currentCurve);
if (!isFinite(startVec.magnitude())) {
console.error('Warning: startVec is NaN or ∞', startVec, endVec, this.currentCurve);
startVec = endVec;

@@ -230,24 +240,14 @@ }

const halfVecT = projectionT;
let halfVec = Vec2.ofXY(this.currentCurve.normal(halfVecT))
const halfVec = Vec2.ofXY(this.currentCurve.normal(halfVecT))
.normalized().times(this.curveStartWidth / 2 * halfVecT
+ this.curveEndWidth / 2 * (1 - halfVecT));
// Computes a boundary curve. [direction] should be either +1 or -1 (determines the side
// of the center curve to place the boundary).
const computeBoundaryCurve = (direction, halfVec) => {
return new Bezier(startPt.plus(startVec.times(direction)), controlPoint.plus(halfVec.times(direction)), endPt.plus(endVec.times(direction)));
};
const boundariesIntersect = () => {
const upperBoundary = computeBoundaryCurve(1, halfVec);
const lowerBoundary = computeBoundaryCurve(-1, halfVec);
return upperBoundary.intersects(lowerBoundary).length > 0;
};
// If the boundaries have intersections, increasing the half vector's length could fix this.
if (boundariesIntersect()) {
halfVec = halfVec.times(1.1);
}
// Each starts at startPt ± startVec
const lowerCurveControlPoint = this.roundPoint(controlPoint.plus(halfVec));
const lowerCurveEndPoint = this.roundPoint(endPt.plus(endVec));
const upperCurveControlPoint = this.roundPoint(controlPoint.minus(halfVec));
const upperCurveStartPoint = this.roundPoint(endPt.minus(endVec));
const lowerCurve = {
kind: PathCommandType.QuadraticBezierTo,
controlPoint: this.roundPoint(controlPoint.plus(halfVec)),
endPoint: this.roundPoint(endPt.plus(endVec)),
controlPoint: lowerCurveControlPoint,
endPoint: lowerCurveEndPoint,
};

@@ -262,7 +262,7 @@ // From the end of the upperCurve to the start of the lowerCurve:

kind: PathCommandType.LineTo,
point: this.roundPoint(endPt.minus(endVec))
point: upperCurveStartPoint,
};
const upperCurve = {
kind: PathCommandType.QuadraticBezierTo,
controlPoint: this.roundPoint(controlPoint.minus(halfVec)),
controlPoint: upperCurveControlPoint,
endPoint: this.roundPoint(startPt.minus(startVec)),

@@ -283,3 +283,2 @@ };

if (newPoint.pos.eq(this.lastPoint.pos, fuzzEq) || deltaTime === 0) {
console.warn('Discarding identical point');
return;

@@ -330,3 +329,3 @@ }

// Find the intersection between the entering vector and the exiting vector
const maxRelativeLength = 2;
const maxRelativeLength = 3;
const segmentStart = this.buffer[0];

@@ -337,9 +336,9 @@ const segmentEnd = newPoint.pos;

// Exit in cases where we would divide by zero
if (maxControlPointDist === 0 || exitingVec.magnitude() === 0 || isNaN(exitingVec.magnitude())) {
if (maxControlPointDist === 0 || exitingVec.magnitude() === 0 || !isFinite(exitingVec.magnitude())) {
return;
}
console.assert(!isNaN(enteringVec.magnitude()));
console.assert(isFinite(enteringVec.magnitude()), 'Pre-normalized enteringVec has NaN or ∞ magnitude!');
enteringVec = enteringVec.normalized();
exitingVec = exitingVec.normalized();
console.assert(!isNaN(enteringVec.magnitude()));
console.assert(isFinite(enteringVec.magnitude()), 'Normalized enteringVec has NaN or ∞ magnitude!');
const lineFromStart = new LineSegment2(segmentStart, segmentStart.plus(enteringVec.times(maxControlPointDist)));

@@ -349,7 +348,8 @@ const lineFromEnd = new LineSegment2(segmentEnd.minus(exitingVec.times(maxControlPointDist)), segmentEnd);

// Position the control point at this intersection
let controlPoint;
let controlPoint = null;
if (intersection) {
controlPoint = intersection.point;
}
else {
// No intersection or the intersection is one of the end points?
if (!controlPoint || segmentStart.eq(controlPoint) || segmentEnd.eq(controlPoint)) {
// Position the control point closer to the first -- the connecting

@@ -359,5 +359,4 @@ // segment will be roughly a line.

}
if (isNaN(controlPoint.magnitude()) || isNaN(segmentStart.magnitude())) {
console.error('controlPoint is NaN', intersection, 'Start:', segmentStart, 'End:', segmentEnd, 'in:', enteringVec, 'out:', exitingVec);
}
console.assert(!segmentStart.eq(controlPoint, 1e-11), 'Start and control points are equal!');
console.assert(!controlPoint.eq(segmentEnd, 1e-11), 'Control and end points are equal!');
const prevCurve = this.currentCurve;

@@ -382,4 +381,3 @@ this.currentCurve = new Bezier(segmentStart.xy, controlPoint.xy, segmentEnd.xy);

};
const approxCurveLen = controlPoint.minus(segmentStart).magnitude() + segmentEnd.minus(controlPoint).magnitude();
if (this.buffer.length > 3 && approxCurveLen > this.curveEndWidth / 3) {
if (this.buffer.length > 3 && this.approxCurrentCurveLength() > this.curveStartWidth) {
if (!curveMatchesPoints(this.currentCurve)) {

@@ -386,0 +384,0 @@ // Use a curve that better fits the points

@@ -9,3 +9,4 @@ import Path from '../math/Path';

super('stroke');
this.parts = parts.map((section) => {
this.parts = [];
for (const section of parts) {
const path = Path.fromRenderable(section);

@@ -19,3 +20,3 @@ const pathBBox = this.bboxForPart(path.bbox, section.style);

}
return {
this.parts.push({
path,

@@ -26,4 +27,4 @@ // To implement RenderablePathSpec

commands: path.parts,
};
});
});
}
(_a = this.contentBBox) !== null && _a !== void 0 ? _a : (this.contentBBox = Rect2.empty);

@@ -86,7 +87,12 @@ }

getPath() {
var _a;
return (_a = this.parts.reduce((accumulator, current) => {
var _a;
return (_a = accumulator === null || accumulator === void 0 ? void 0 : accumulator.union(current.path)) !== null && _a !== void 0 ? _a : current.path;
}, null)) !== null && _a !== void 0 ? _a : Path.empty;
let result = null;
for (const part of this.parts) {
if (result) {
result = result.union(part.path);
}
else {
result !== null && result !== void 0 ? result : (result = part.path);
}
}
return result !== null && result !== void 0 ? result : Path.empty;
}

@@ -93,0 +99,0 @@ description(localization) {

@@ -32,3 +32,3 @@ import LineSegment2 from '../math/LineSegment2';

protected createClone(): AbstractComponent;
private getText;
getText(): string;
description(localizationTable: ImageComponentLocalization): string;

@@ -35,0 +35,0 @@ protected serializeToJSON(): Record<string, any>;

@@ -116,3 +116,3 @@ import LineSegment2 from '../math/LineSegment2';

}
return result.join(' ');
return result.join('\n');
}

@@ -119,0 +119,0 @@ description(localizationTable) {

@@ -610,3 +610,5 @@ /**

// Intended primarially for unit tests.
sendPenEvent(eventType, point, allPointers) {
sendPenEvent(eventType, point,
// @deprecated
allPointers) {
const mainPointer = Pointer.ofCanvasPoint(point, eventType !== InputEvtType.PointerUpEvt, this.viewport);

@@ -613,0 +615,0 @@ this.toolController.dispatchInputEvent({

@@ -100,3 +100,3 @@ /**

*/
eq(other: Vec3, fuzz: number): boolean;
eq(other: Vec3, fuzz?: number): boolean;
toString(): string;

@@ -103,0 +103,0 @@ static unitX: Vec3;

@@ -159,3 +159,3 @@ /**

*/
eq(other, fuzz) {
eq(other, fuzz = 1e-10) {
for (let i = 0; i < 3; i++) {

@@ -162,0 +162,0 @@ if (Math.abs(other.at(i) - this.at(i)) > fuzz) {

import Editor from '../Editor';
/** Creates an editor. Should only be used in test files. */
declare const _default: () => Editor;
export default _default;
import { RenderingMode } from '../rendering/Display';
import Editor from '../Editor';
export default () => new Editor(document.body, { renderingMode: RenderingMode.DummyRenderer });
/** Creates an editor. Should only be used in test files. */
export default () => {
if (jest === undefined) {
throw new Error('Files in the testing/ folder should only be used in tests!');
}
return new Editor(document.body, { renderingMode: RenderingMode.DummyRenderer });
};
export declare const loadExpectExtensions: () => void;
export interface CustomMatchers<R = unknown> {
objEq(expected: {
eq: (other: any, ...args: any) => boolean;
}, ...opts: any): R;
}
declare global {
export namespace jest {
interface Expect extends CustomMatchers {
}
interface Matchers<R> extends CustomMatchers<R> {
}
interface AsyncAsymmetricMatchers extends CustomMatchers {
}
}
}
export default loadExpectExtensions;

@@ -11,2 +11,3 @@ // Allows users to select/transform portions of the `EditorImage`.

import Selection from './Selection';
import TextComponent from '../../components/Text';
export const cssPrefix = 'selection-tool-';

@@ -219,6 +220,13 @@ // {@inheritDoc SelectionTool!}

const renderer = new SVGRenderer(exportElem, exportViewport, sanitize);
const text = [];
for (const elem of selectedElems) {
elem.render(renderer);
if (elem instanceof TextComponent) {
text.push(elem.getText());
}
}
event.setData('image/svg+xml', exportElem.outerHTML);
if (text.length > 0) {
event.setData('text/plain', text.join('\n'));
}
return true;

@@ -225,0 +233,0 @@ }

@@ -13,2 +13,6 @@ // Test configuration

testPathIgnorePatterns: [
'<rootDir>/dist/', '<rootDir>/node_modules/'
],
// Mocks.

@@ -23,4 +27,5 @@ // See https://jestjs.io/docs/webpack#handling-static-assets

testEnvironment: 'jsdom',
setupFilesAfterEnv: [ '<rootDir>/src/testing/beforeEachFile.ts' ],
};
module.exports = config;
{
"name": "js-draw",
"version": "0.4.0",
"version": "0.4.1",
"description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ",

@@ -74,2 +74,3 @@ "main": "./dist/src/lib.d.ts",

"lint-staged": "lint-staged",
"lint-ci": "eslint . --max-warnings=0 --ext .js --ext .ts",
"prepare": "husky install && yarn build",

@@ -80,3 +81,3 @@ "prepack": "yarn build && yarn test && pinst --disable",

"dependencies": {
"@melloware/coloris": "^0.16.0",
"@melloware/coloris": "^0.16.1",
"bezier-js": "^6.1.0"

@@ -86,12 +87,12 @@ },

"@types/bezier-js": "^4.1.0",
"@types/jest": "^28.1.7",
"@types/jest": "^29.0.3",
"@types/jsdom": "^20.0.0",
"@types/node": "^18.7.15",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"@types/node": "^18.7.23",
"@typescript-eslint/eslint-plugin": "^5.38.1",
"@typescript-eslint/parser": "^5.38.1",
"css-loader": "^6.7.1",
"eslint": "^8.23.0",
"eslint": "^8.24.0",
"husky": "^8.0.1",
"jest": "^28.1.3",
"jest-environment-jsdom": "^29.0.2",
"jest": "^29.0.3",
"jest-environment-jsdom": "^29.0.3",
"jsdom": "^20.0.0",

@@ -101,8 +102,8 @@ "lint-staged": "^13.0.3",

"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.5",
"ts-jest": "^28.0.8",
"ts-loader": "^9.3.1",
"terser-webpack-plugin": "^5.3.6",
"ts-jest": "^29.0.2",
"ts-loader": "^9.4.1",
"ts-node": "^10.9.1",
"typedoc": "^0.23.14",
"typescript": "^4.8.2",
"typedoc": "^0.23.15",
"typescript": "^4.8.3",
"webpack": "^5.74.0"

@@ -109,0 +110,0 @@ },

@@ -209,4 +209,6 @@ import SerializableCommand from '../commands/SerializableCommand';

// Component-specific implementation of {@link clone}.
protected abstract createClone(): AbstractComponent;
// Returns a copy of this component.
public clone() {

@@ -213,0 +215,0 @@ const clone = this.createClone();

@@ -176,3 +176,3 @@ import { Bezier } from 'bezier-js';

public build(): Stroke {
if (this.lastPoint) {
if (this.lastPoint && (this.lowerSegments.length === 0 || this.approxCurrentCurveLength() > this.curveStartWidth * 2)) {
this.finalizeCurrentCurve();

@@ -193,2 +193,15 @@ }

// Returns the distance between the start, control, and end points of the curve.
private approxCurrentCurveLength() {
if (!this.currentCurve) {
return 0;
}
const startPt = Vec2.ofXY(this.currentCurve.points[0]);
const controlPt = Vec2.ofXY(this.currentCurve.points[1]);
const endPt = Vec2.ofXY(this.currentCurve.points[2]);
const toControlDist = startPt.minus(controlPt).length();
const toEndDist = endPt.minus(controlPt).length();
return toControlDist + toEndDist;
}
private finalizeCurrentCurve() {

@@ -290,6 +303,4 @@ // Case where no points have been added

if (isNaN(startVec.magnitude())) {
// TODO: This can happen when events are too close together. Find out why and
// fix.
console.error('startVec is NaN', startVec, endVec, this.currentCurve);
if (!isFinite(startVec.magnitude())) {
console.error('Warning: startVec is NaN or ∞', startVec, endVec, this.currentCurve);
startVec = endVec;

@@ -313,3 +324,3 @@ }

const halfVecT = projectionT;
let halfVec = Vec2.ofXY(this.currentCurve.normal(halfVecT))
const halfVec = Vec2.ofXY(this.currentCurve.normal(halfVecT))
.normalized().times(

@@ -320,29 +331,12 @@ this.curveStartWidth / 2 * halfVecT

// Computes a boundary curve. [direction] should be either +1 or -1 (determines the side
// of the center curve to place the boundary).
const computeBoundaryCurve = (direction: number, halfVec: Vec2) => {
return new Bezier(
startPt.plus(startVec.times(direction)),
controlPoint.plus(halfVec.times(direction)),
endPt.plus(endVec.times(direction)),
);
};
const boundariesIntersect = () => {
const upperBoundary = computeBoundaryCurve(1, halfVec);
const lowerBoundary = computeBoundaryCurve(-1, halfVec);
return upperBoundary.intersects(lowerBoundary).length > 0;
};
// If the boundaries have intersections, increasing the half vector's length could fix this.
if (boundariesIntersect()) {
halfVec = halfVec.times(1.1);
}
// Each starts at startPt ± startVec
const lowerCurveControlPoint = this.roundPoint(controlPoint.plus(halfVec));
const lowerCurveEndPoint = this.roundPoint(endPt.plus(endVec));
const upperCurveControlPoint = this.roundPoint(controlPoint.minus(halfVec));
const upperCurveStartPoint = this.roundPoint(endPt.minus(endVec));
const lowerCurve: QuadraticBezierPathCommand = {
kind: PathCommandType.QuadraticBezierTo,
controlPoint: this.roundPoint(controlPoint.plus(halfVec)),
endPoint: this.roundPoint(endPt.plus(endVec)),
controlPoint: lowerCurveControlPoint,
endPoint: lowerCurveEndPoint,
};

@@ -359,3 +353,3 @@

kind: PathCommandType.LineTo,
point: this.roundPoint(endPt.minus(endVec))
point: upperCurveStartPoint,
};

@@ -365,3 +359,3 @@

kind: PathCommandType.QuadraticBezierTo,
controlPoint: this.roundPoint(controlPoint.minus(halfVec)),
controlPoint: upperCurveControlPoint,
endPoint: this.roundPoint(startPt.minus(startVec)),

@@ -384,3 +378,2 @@ };

if (newPoint.pos.eq(this.lastPoint.pos, fuzzEq) || deltaTime === 0) {
console.warn('Discarding identical point');
return;

@@ -444,3 +437,3 @@ } else if (isNaN(newPoint.pos.magnitude())) {

// Find the intersection between the entering vector and the exiting vector
const maxRelativeLength = 2;
const maxRelativeLength = 3;
const segmentStart = this.buffer[0];

@@ -452,7 +445,7 @@ const segmentEnd = newPoint.pos;

// Exit in cases where we would divide by zero
if (maxControlPointDist === 0 || exitingVec.magnitude() === 0 || isNaN(exitingVec.magnitude())) {
if (maxControlPointDist === 0 || exitingVec.magnitude() === 0 || !isFinite(exitingVec.magnitude())) {
return;
}
console.assert(!isNaN(enteringVec.magnitude()));
console.assert(isFinite(enteringVec.magnitude()), 'Pre-normalized enteringVec has NaN or ∞ magnitude!');

@@ -462,3 +455,3 @@ enteringVec = enteringVec.normalized();

console.assert(!isNaN(enteringVec.magnitude()));
console.assert(isFinite(enteringVec.magnitude()), 'Normalized enteringVec has NaN or ∞ magnitude!');

@@ -476,6 +469,9 @@ const lineFromStart = new LineSegment2(

// Position the control point at this intersection
let controlPoint: Point2;
let controlPoint: Point2|null = null;
if (intersection) {
controlPoint = intersection.point;
} else {
}
// No intersection or the intersection is one of the end points?
if (!controlPoint || segmentStart.eq(controlPoint) || segmentEnd.eq(controlPoint)) {
// Position the control point closer to the first -- the connecting

@@ -486,5 +482,4 @@ // segment will be roughly a line.

if (isNaN(controlPoint.magnitude()) || isNaN(segmentStart.magnitude())) {
console.error('controlPoint is NaN', intersection, 'Start:', segmentStart, 'End:', segmentEnd, 'in:', enteringVec, 'out:', exitingVec);
}
console.assert(!segmentStart.eq(controlPoint, 1e-11), 'Start and control points are equal!');
console.assert(!controlPoint.eq(segmentEnd, 1e-11), 'Control and end points are equal!');

@@ -518,4 +513,3 @@ const prevCurve = this.currentCurve;

const approxCurveLen = controlPoint.minus(segmentStart).magnitude() + segmentEnd.minus(controlPoint).magnitude();
if (this.buffer.length > 3 && approxCurveLen > this.curveEndWidth / 3) {
if (this.buffer.length > 3 && this.approxCurrentCurveLength() > this.curveStartWidth) {
if (!curveMatchesPoints(this.currentCurve)) {

@@ -522,0 +516,0 @@ // Use a curve that better fits the points

@@ -5,8 +5,5 @@ import Color4 from '../Color4';

import Stroke from './Stroke';
import { loadExpectExtensions } from '../testing/loadExpectExtensions';
import createEditor from '../testing/createEditor';
import Mat33 from '../math/Mat33';
loadExpectExtensions();
describe('Stroke', () => {

@@ -13,0 +10,0 @@ it('empty stroke should have an empty bounding box', () => {

@@ -21,3 +21,4 @@ import LineSegment2 from '../math/LineSegment2';

this.parts = parts.map((section): StrokePart => {
this.parts = [];
for (const section of parts) {
const path = Path.fromRenderable(section);

@@ -32,3 +33,3 @@ const pathBBox = this.bboxForPart(path.bbox, section.style);

return {
this.parts.push({
path,

@@ -40,4 +41,4 @@

commands: path.parts,
};
});
});
}
this.contentBBox ??= Rect2.empty;

@@ -110,5 +111,11 @@ }

public getPath() {
return this.parts.reduce((accumulator: Path|null, current: StrokePart) => {
return accumulator?.union(current.path) ?? current.path;
}, null) ?? Path.empty;
let result: Path|null = null;
for (const part of this.parts) {
if (result) {
result = result.union(part.path);
} else {
result ??= part.path;
}
}
return result ?? Path.empty;
}

@@ -115,0 +122,0 @@

@@ -6,6 +6,3 @@ import Color4 from '../Color4';

import Text, { TextStyle } from './Text';
import { loadExpectExtensions } from '../testing/loadExpectExtensions';
loadExpectExtensions();
const estimateTextBounds = (text: string, style: TextStyle): Rect2 => {

@@ -12,0 +9,0 @@ const widthEst = text.length * style.size;

@@ -138,3 +138,3 @@ import LineSegment2 from '../math/LineSegment2';

private getText() {
public getText() {
const result: string[] = [];

@@ -150,3 +150,3 @@

return result.join(' ');
return result.join('\n');
}

@@ -153,0 +153,0 @@

@@ -800,2 +800,4 @@ /**

point: Point2,
// @deprecated
allPointers?: Pointer[]

@@ -802,0 +804,0 @@ ) {

@@ -5,3 +5,3 @@

export const assertUnreachable = (key: never): never => {
throw new Error(`Should be unreachable. Key: ${key}.`);
};
throw new Error(`Should be unreachable. Key: ${key}.`);
};
import LineSegment2 from './LineSegment2';
import { loadExpectExtensions } from '../testing/loadExpectExtensions';
import { Vec2 } from './Vec2';
import Mat33 from './Mat33';
loadExpectExtensions();

@@ -17,9 +15,9 @@ describe('Line2', () => {

it('y = -2x + 2 and y = 2x - 2 should intersect at (1,0)', () => {
// y = -2x + 2
// y = -4x + 2
const line1 = new LineSegment2(Vec2.of(0, 2), Vec2.of(1, -2));
// y = 2x - 2
// y = 4x - 2
const line2 = new LineSegment2(Vec2.of(0, -2), Vec2.of(1, 2));
expect(line1.intersection(line2)?.point).objEq(Vec2.of(1, 0));
expect(line2.intersection(line1)?.point).objEq(Vec2.of(1, 0));
expect(line1.intersection(line2)?.point).objEq(Vec2.of(0.5, 0));
expect(line2.intersection(line1)?.point).objEq(Vec2.of(0.5, 0));
});

@@ -85,10 +83,10 @@

it('Closest point from (-1,2) to segment((1,1) -> (2,4)) should be (1,1)', () => {
it('Closest point from (-1,-2) to segment((1,1) -> (2,4)) should be (1,1)', () => {
const line = new LineSegment2(Vec2.of(1, 1), Vec2.of(2, 4));
expect(line.closestPointTo(Vec2.of(-1, 2))).objEq(Vec2.of(1, 1));
expect(line.closestPointTo(Vec2.of(-1, -2))).objEq(Vec2.of(1, 1));
});
it('Closest point from (5,2) to segment((1,1) -> (2,4)) should be (2,4)', () => {
it('Closest point from (5,8) to segment((1,1) -> (2,4)) should be (2,4)', () => {
const line = new LineSegment2(Vec2.of(1, 1), Vec2.of(2, 4));
expect(line.closestPointTo(Vec2.of(5, 2))).objEq(Vec2.of(2, 4));
expect(line.closestPointTo(Vec2.of(5, 8))).objEq(Vec2.of(2, 4));
});

@@ -95,0 +93,0 @@

import Mat33 from './Mat33';
import { Vec2 } from './Vec2';
import { loadExpectExtensions } from '../testing/loadExpectExtensions';
import Vec3 from './Vec3';
loadExpectExtensions();

@@ -8,0 +6,0 @@ describe('Mat33 tests', () => {

import Rect2 from './Rect2';
import { Vec2 } from './Vec2';
import loadExpectExtensions from '../testing/loadExpectExtensions';
import Mat33 from './Mat33';
loadExpectExtensions();
describe('Rect2', () => {

@@ -10,0 +7,0 @@ it('width, height should always be positive', () => {

import { Vec2 } from './Vec2';
import Vec3 from './Vec3';
import { loadExpectExtensions } from '../testing/loadExpectExtensions';
loadExpectExtensions();
describe('Vec2', () => {

@@ -8,0 +5,0 @@ it('Magnitude', () => {

import { loadExpectExtensions } from '../testing/loadExpectExtensions';
import Vec3 from './Vec3';
loadExpectExtensions();
describe('Vec3', () => {

@@ -8,0 +5,0 @@ it('.xy should contain the x and y components', () => {

@@ -199,3 +199,3 @@

*/
public eq(other: Vec3, fuzz: number): boolean {
public eq(other: Vec3, fuzz: number = 1e-10): boolean {
for (let i = 0; i < 3; i++) {

@@ -202,0 +202,0 @@ if (Math.abs(other.at(i) - this.at(i)) > fuzz) {

import { RenderingMode } from '../rendering/Display';
import Editor from '../Editor';
export default () => new Editor(document.body, { renderingMode: RenderingMode.DummyRenderer });
/** Creates an editor. Should only be used in test files. */
export default () => {
if (jest === undefined) {
throw new Error('Files in the testing/ folder should only be used in tests!');
}
return new Editor(document.body, { renderingMode: RenderingMode.DummyRenderer });
};

@@ -25,17 +25,2 @@ export const loadExpectExtensions = () => {

// Type declarations for custom matchers
export interface CustomMatchers<R = unknown> {
objEq(expected: {
eq: (other: any, ...args: any)=> boolean;
}, ...opts: any): R;
}
declare global {
export namespace jest {
interface Expect extends CustomMatchers {}
interface Matchers<R> extends CustomMatchers<R> {}
interface AsyncAsymmetricMatchers extends CustomMatchers {}
}
}
export default loadExpectExtensions;

@@ -15,2 +15,3 @@ // Allows users to select/transform portions of the `EditorImage`.

import Selection from './Selection';
import TextComponent from '../../components/Text';

@@ -276,7 +277,15 @@ export const cssPrefix = 'selection-tool-';

const text: string[] = [];
for (const elem of selectedElems) {
elem.render(renderer);
if (elem instanceof TextComponent) {
text.push(elem.getText());
}
}
event.setData('image/svg+xml', exportElem.outerHTML);
if (text.length > 0) {
event.setData('text/plain', text.join('\n'));
}
return true;

@@ -283,0 +292,0 @@ }

@@ -26,3 +26,3 @@ {

// Files that don't need transpilation
"**/*.test.ts",
// "**/*.test.ts", <- vscode requires .test.ts files to be transpiled for other settings to apply.
"__mocks__/*",

@@ -33,2 +33,4 @@

],
"files": [ "./src/testing/global.d.ts" ]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc