Comparing version 0.2.2 to 0.2.3
@@ -0,1 +1,4 @@ | ||
# 0.2.3 | ||
* Fix lines with thickness set to small numbers self-intersecting many times. | ||
# 0.2.2 | ||
@@ -2,0 +5,0 @@ * Fix custon toolbar action buttons having wrong height. |
@@ -11,5 +11,4 @@ import { Bezier } from 'bezier-js'; | ||
// less than ± 2 px from the curve. | ||
const canvasTransform = viewport.screenToCanvasTransform; | ||
const maxSmoothingDist = canvasTransform.transformVec3(Vec2.unitX).magnitude() * 7; | ||
const minSmoothingDist = canvasTransform.transformVec3(Vec2.unitX).magnitude() * 2; | ||
const maxSmoothingDist = viewport.getSizeOfPixelOnCanvas() * 7; | ||
const minSmoothingDist = viewport.getSizeOfPixelOnCanvas() * 2; | ||
return new FreehandLineBuilder(initialPoint, minSmoothingDist, maxSmoothingDist); | ||
@@ -31,2 +30,3 @@ }; | ||
this.mostRecentConnector = null; | ||
this.lastExitingVec = null; | ||
this.currentCurve = null; | ||
@@ -39,2 +39,3 @@ this.lastPoint = this.startPoint; | ||
this.currentCurve = null; | ||
this.curveStartWidth = startPoint.width; | ||
this.bbox = new Rect2(this.startPoint.pos.x, this.startPoint.pos.y, 0, 0); | ||
@@ -128,3 +129,7 @@ } | ||
roundPoint(point) { | ||
return Viewport.roundPoint(point, this.minFitAllowed); | ||
let minFit = Math.min(this.minFitAllowed, this.curveStartWidth); | ||
if (minFit < 1e-10) { | ||
minFit = this.minFitAllowed; | ||
} | ||
return Viewport.roundPoint(point, minFit); | ||
} | ||
@@ -234,6 +239,9 @@ finalizeCurrentCurve() { | ||
}; | ||
const upperBoundary = computeBoundaryCurve(1, halfVec); | ||
const lowerBoundary = computeBoundaryCurve(-1, halfVec); | ||
const boundariesIntersect = () => { | ||
const upperBoundary = computeBoundaryCurve(1, halfVec); | ||
const lowerBoundary = computeBoundaryCurve(-1, halfVec); | ||
return upperBoundary.intersects(lowerBoundary).length > 0; | ||
}; | ||
// If the boundaries have two intersections, increasing the half vector's length could fix this. | ||
if (upperBoundary.intersects(lowerBoundary).length > 0) { | ||
if (boundariesIntersect()) { | ||
halfVec = halfVec.times(2); | ||
@@ -282,3 +290,3 @@ } | ||
} | ||
const threshold = Math.min(this.lastPoint.width, newPoint.width) / 4; | ||
const threshold = Math.min(this.lastPoint.width, newPoint.width) / 3; | ||
const shouldSnapToInitial = this.startPoint.pos.minus(newPoint.pos).magnitude() < threshold | ||
@@ -370,3 +378,4 @@ && this.isFirstSegment; | ||
}; | ||
if (this.buffer.length > 3) { | ||
const approxCurveLen = controlPoint.minus(segmentStart).magnitude() + segmentEnd.minus(controlPoint).magnitude(); | ||
if (this.buffer.length > 3 && approxCurveLen > this.curveEndWidth / 2) { | ||
if (!curveMatchesPoints(this.currentCurve)) { | ||
@@ -373,0 +382,0 @@ // Use a curve that better fits the points |
@@ -52,6 +52,11 @@ import EditorImage from '../EditorImage'; | ||
onPointerDown({ current, allPointers }) { | ||
if (current.device === PointerDevice.Eraser) { | ||
return false; | ||
const isEraser = current.device === PointerDevice.Eraser; | ||
let anyDeviceIsStylus = false; | ||
for (const pointer of allPointers) { | ||
if (pointer.device === PointerDevice.Pen) { | ||
anyDeviceIsStylus = true; | ||
break; | ||
} | ||
} | ||
if (allPointers.length === 1 || current.device === PointerDevice.Pen) { | ||
if ((allPointers.length === 1 && !isEraser) || anyDeviceIsStylus) { | ||
this.builder = this.builderFactory(this.getStrokePoint(current), this.editor.viewport); | ||
@@ -58,0 +63,0 @@ return true; |
{ | ||
"name": "js-draw", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"description": "Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript. ", | ||
@@ -5,0 +5,0 @@ "main": "./dist/src/lib.d.ts", |
@@ -44,4 +44,4 @@ # js-draw | ||
```html | ||
<!-- Replace 0.2.0 with the latest version of js-draw --> | ||
<script src="https://cdn.jsdelivr.net/npm/js-draw@0.2.0/dist/bundle.js"></script> | ||
<!-- Replace 0.2.3 with the latest version of js-draw --> | ||
<script src="https://cdn.jsdelivr.net/npm/js-draw@0.2.3/dist/bundle.js"></script> | ||
<script> | ||
@@ -48,0 +48,0 @@ const editor = new jsdraw.Editor(document.body); |
@@ -5,3 +5,3 @@ import { Bezier } from 'bezier-js'; | ||
import Rect2 from '../../math/Rect2'; | ||
import { LinePathCommand, PathCommandType, QuadraticBezierPathCommand } from '../../math/Path'; | ||
import { LinePathCommand, PathCommand, PathCommandType, QuadraticBezierPathCommand } from '../../math/Path'; | ||
import LineSegment2 from '../../math/LineSegment2'; | ||
@@ -17,5 +17,4 @@ import Stroke from '../Stroke'; | ||
// less than ± 2 px from the curve. | ||
const canvasTransform = viewport.screenToCanvasTransform; | ||
const maxSmoothingDist = canvasTransform.transformVec3(Vec2.unitX).magnitude() * 7; | ||
const minSmoothingDist = canvasTransform.transformVec3(Vec2.unitX).magnitude() * 2; | ||
const maxSmoothingDist = viewport.getSizeOfPixelOnCanvas() * 7; | ||
const minSmoothingDist = viewport.getSizeOfPixelOnCanvas() * 2; | ||
@@ -29,4 +28,4 @@ return new FreehandLineBuilder( | ||
upperCurve: QuadraticBezierPathCommand, | ||
lowerToUpperConnector: LinePathCommand, | ||
upperToLowerConnector: LinePathCommand, | ||
lowerToUpperConnector: PathCommand, | ||
upperToLowerConnector: PathCommand, | ||
lowerCurve: QuadraticBezierPathCommand, | ||
@@ -38,4 +37,4 @@ }; | ||
private isFirstSegment: boolean = true; | ||
private pathStartConnector: LinePathCommand|null = null; | ||
private mostRecentConnector: LinePathCommand|null = null; | ||
private pathStartConnector: PathCommand|null = null; | ||
private mostRecentConnector: PathCommand|null = null; | ||
@@ -60,3 +59,3 @@ // Beginning of the list of lower parts | ||
private lastPoint: StrokeDataPoint; | ||
private lastExitingVec: Vec2; | ||
private lastExitingVec: Vec2|null = null; | ||
private currentCurve: Bezier|null = null; | ||
@@ -87,2 +86,3 @@ private curveStartWidth: number; | ||
this.currentCurve = null; | ||
this.curveStartWidth = startPoint.width; | ||
@@ -105,4 +105,4 @@ this.bbox = new Rect2(this.startPoint.pos.x, this.startPoint.pos.y, 0, 0); | ||
let lowerPath: QuadraticBezierPathCommand[]; | ||
let lowerToUpperCap: LinePathCommand; | ||
let pathStartConnector: LinePathCommand; | ||
let lowerToUpperCap: PathCommand; | ||
let pathStartConnector: PathCommand; | ||
if (this.currentCurve) { | ||
@@ -190,3 +190,9 @@ const { upperCurve, lowerToUpperConnector, upperToLowerConnector, lowerCurve } = this.currentSegmentToPath(); | ||
private roundPoint(point: Point2): Point2 { | ||
return Viewport.roundPoint(point, this.minFitAllowed); | ||
let minFit = Math.min(this.minFitAllowed, this.curveStartWidth); | ||
if (minFit < 1e-10) { | ||
minFit = this.minFitAllowed; | ||
} | ||
return Viewport.roundPoint(point, minFit); | ||
} | ||
@@ -328,7 +334,10 @@ | ||
const upperBoundary = computeBoundaryCurve(1, halfVec); | ||
const lowerBoundary = computeBoundaryCurve(-1, halfVec); | ||
const boundariesIntersect = () => { | ||
const upperBoundary = computeBoundaryCurve(1, halfVec); | ||
const lowerBoundary = computeBoundaryCurve(-1, halfVec); | ||
return upperBoundary.intersects(lowerBoundary).length > 0; | ||
}; | ||
// If the boundaries have two intersections, increasing the half vector's length could fix this. | ||
if (upperBoundary.intersects(lowerBoundary).length > 0) { | ||
if (boundariesIntersect()) { | ||
halfVec = halfVec.times(2); | ||
@@ -384,3 +393,3 @@ } | ||
const threshold = Math.min(this.lastPoint.width, newPoint.width) / 4; | ||
const threshold = Math.min(this.lastPoint.width, newPoint.width) / 3; | ||
const shouldSnapToInitial = this.startPoint.pos.minus(newPoint.pos).magnitude() < threshold | ||
@@ -506,3 +515,4 @@ && this.isFirstSegment; | ||
if (this.buffer.length > 3) { | ||
const approxCurveLen = controlPoint.minus(segmentStart).magnitude() + segmentEnd.minus(controlPoint).magnitude(); | ||
if (this.buffer.length > 3 && approxCurveLen > this.curveEndWidth / 2) { | ||
if (!curveMatchesPoints(this.currentCurve)) { | ||
@@ -509,0 +519,0 @@ // Use a curve that better fits the points |
@@ -70,7 +70,13 @@ import Color4 from '../Color4'; | ||
public onPointerDown({ current, allPointers }: PointerEvt): boolean { | ||
if (current.device === PointerDevice.Eraser) { | ||
return false; | ||
const isEraser = current.device === PointerDevice.Eraser; | ||
let anyDeviceIsStylus = false; | ||
for (const pointer of allPointers) { | ||
if (pointer.device === PointerDevice.Pen) { | ||
anyDeviceIsStylus = true; | ||
break; | ||
} | ||
} | ||
if (allPointers.length === 1 || current.device === PointerDevice.Pen) { | ||
if ((allPointers.length === 1 && !isEraser) || anyDeviceIsStylus) { | ||
this.builder = this.builderFactory(this.getStrokePoint(current), this.editor.viewport); | ||
@@ -77,0 +83,0 @@ return true; |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1075350
22820