snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
This commit is contained in:
167
packages/tldraw/src/lib/shapes/draw/getPath.ts
Normal file
167
packages/tldraw/src/lib/shapes/draw/getPath.ts
Normal file
@@ -0,0 +1,167 @@
|
||||
import {
|
||||
EASINGS,
|
||||
PI,
|
||||
SIN,
|
||||
TLDefaultDashStyle,
|
||||
TLDrawShape,
|
||||
TLDrawShapeSegment,
|
||||
Vec,
|
||||
b64Vecs,
|
||||
modulate,
|
||||
} from '@tldraw/editor'
|
||||
import { StrokeOptions } from '../shared/freehand/types'
|
||||
|
||||
const PEN_EASING = (t: number) => t * 0.65 + SIN((t * PI) / 2) * 0.35
|
||||
|
||||
const simulatePressureSettings = (strokeWidth: number): StrokeOptions => {
|
||||
return {
|
||||
size: strokeWidth,
|
||||
thinning: 0.5,
|
||||
streamline: modulate(strokeWidth, [9, 16], [0.64, 0.74], true), // 0.62 + ((1 + strokeWidth) / 8) * 0.06,
|
||||
smoothing: 0.62,
|
||||
easing: EASINGS.easeOutSine,
|
||||
simulatePressure: true,
|
||||
}
|
||||
}
|
||||
|
||||
const realPressureSettings = (strokeWidth: number): StrokeOptions => {
|
||||
return {
|
||||
size: 1 + strokeWidth * 1.2,
|
||||
thinning: 0.62,
|
||||
streamline: 0.62,
|
||||
smoothing: 0.62,
|
||||
simulatePressure: false,
|
||||
easing: PEN_EASING,
|
||||
}
|
||||
}
|
||||
|
||||
const solidSettings = (strokeWidth: number): StrokeOptions => {
|
||||
return {
|
||||
size: strokeWidth,
|
||||
thinning: 0,
|
||||
streamline: modulate(strokeWidth, [9, 16], [0.64, 0.74], true), // 0.62 + ((1 + strokeWidth) / 8) * 0.06,
|
||||
smoothing: 0.62,
|
||||
simulatePressure: false,
|
||||
easing: EASINGS.linear,
|
||||
}
|
||||
}
|
||||
|
||||
const solidRealPressureSettings = (strokeWidth: number): StrokeOptions => {
|
||||
return {
|
||||
size: strokeWidth,
|
||||
thinning: 0,
|
||||
streamline: 0.62,
|
||||
smoothing: 0.62,
|
||||
simulatePressure: false,
|
||||
easing: EASINGS.linear,
|
||||
}
|
||||
}
|
||||
|
||||
export function getHighlightFreehandSettings({
|
||||
strokeWidth,
|
||||
showAsComplete,
|
||||
}: {
|
||||
strokeWidth: number
|
||||
showAsComplete: boolean
|
||||
}): StrokeOptions {
|
||||
return {
|
||||
size: 1 + strokeWidth,
|
||||
thinning: 0,
|
||||
streamline: 0.5,
|
||||
smoothing: 0.5,
|
||||
simulatePressure: false,
|
||||
easing: EASINGS.easeOutSine,
|
||||
last: showAsComplete,
|
||||
}
|
||||
}
|
||||
|
||||
export function getFreehandOptions(
|
||||
shapeProps: { dash: TLDefaultDashStyle; isPen: boolean; isComplete: boolean },
|
||||
strokeWidth: number,
|
||||
forceComplete: boolean,
|
||||
forceSolid: boolean
|
||||
): StrokeOptions {
|
||||
const last = shapeProps.isComplete || forceComplete
|
||||
|
||||
if (forceSolid) {
|
||||
if (shapeProps.isPen) {
|
||||
return { ...solidRealPressureSettings(strokeWidth), last }
|
||||
} else {
|
||||
return { ...solidSettings(strokeWidth), last }
|
||||
}
|
||||
}
|
||||
|
||||
if (shapeProps.dash === 'draw') {
|
||||
if (shapeProps.isPen) {
|
||||
return { ...realPressureSettings(strokeWidth), last }
|
||||
} else {
|
||||
return { ...simulatePressureSettings(strokeWidth), last }
|
||||
}
|
||||
}
|
||||
|
||||
return { ...solidSettings(strokeWidth), last }
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function getPointsFromDrawSegment(
|
||||
segment: TLDrawShapeSegment,
|
||||
scaleX: number,
|
||||
scaleY: number,
|
||||
points: Vec[] = []
|
||||
) {
|
||||
const _points = b64Vecs.decodePoints(segment.path, segment.dim)
|
||||
|
||||
// Apply scale factors (used for lazy resize and flipping)
|
||||
if (scaleX !== 1 || scaleY !== 1) {
|
||||
for (const point of _points) {
|
||||
point.x *= scaleX
|
||||
point.y *= scaleY
|
||||
}
|
||||
}
|
||||
|
||||
if (segment.type === 'free' || _points.length < 2) {
|
||||
points.push(..._points.map(Vec.From))
|
||||
} else {
|
||||
// A B <interpolated points> D
|
||||
const A = Vec.From(_points[0])
|
||||
const D = Vec.From(_points[1])
|
||||
const dist = Vec.Dist(D, A)
|
||||
if (dist === 0) {
|
||||
points.push(A)
|
||||
} else {
|
||||
const uni = Vec.Tan(D, A)
|
||||
const nudgeDist = Math.min(1, Math.floor(dist / 4))
|
||||
const B = Vec.Add(A, Vec.Mul(uni, nudgeDist))
|
||||
const C = Vec.Add(D, Vec.Mul(uni, -nudgeDist))
|
||||
const interpolatedPointsCount = Math.max(4, Math.floor(dist / 16))
|
||||
points.push(A, ...Vec.PointsBetween(B, C, interpolatedPointsCount, EASINGS.easeInOutCubic), D)
|
||||
}
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export function getPointsFromDrawSegments(segments: TLDrawShapeSegment[], scaleX = 1, scaleY = 1) {
|
||||
const points: Vec[] = []
|
||||
|
||||
for (const segment of segments) {
|
||||
getPointsFromDrawSegment(segment, scaleX, scaleY, points)
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
export function getDrawShapeStrokeDashArray(
|
||||
shape: TLDrawShape,
|
||||
strokeWidth: number,
|
||||
dotAdjustment: number
|
||||
) {
|
||||
return {
|
||||
draw: 'none',
|
||||
solid: `none`,
|
||||
dotted: `${dotAdjustment} ${strokeWidth * 2}`,
|
||||
dashed: `${strokeWidth * 2} ${strokeWidth * 2}`,
|
||||
none: `none`,
|
||||
}[shape.props.dash]
|
||||
}
|
||||
Reference in New Issue
Block a user