This commit is contained in:
Andras Schmelczer 2026-05-17 14:12:01 +01:00
commit 80ed37298b
73 changed files with 3619 additions and 1295 deletions

View file

@ -24,10 +24,6 @@ interface GardenPointerInputOptions {
}
export class GardenPointerInput {
private static readonly MIN_SMOOTH_SAMPLE_DISTANCE_SQUARED = 0.25;
private static readonly MIN_CURVE_SEGMENT_SPACING_PIXELS = 4;
private static readonly CURVE_SEGMENT_BRUSH_RADIUS_RATIO = 0.65;
private activePointerId: number | null = null;
private lastPointerPosition: vec2 | null = null;
private lastPointerEventTimeMs: number | null = null;
@ -194,6 +190,7 @@ export class GardenPointerInput {
vibe: activeVibe,
from: previousPosition,
to: position,
canvasSize: [this.canvas.width, this.canvas.height],
isErasing: this.isErasing,
elapsedSeconds,
});
@ -216,8 +213,7 @@ export class GardenPointerInput {
this.smoothedStrokePoints[this.smoothedStrokePoints.length - 1];
if (
previousSample !== undefined &&
vec2.squaredDistance(previousSample, position) <=
GardenPointerInput.MIN_SMOOTH_SAMPLE_DISTANCE_SQUARED
vec2.squaredDistance(previousSample, position) <= getBrushSmoothingDistanceSquared()
) {
return;
}
@ -251,16 +247,22 @@ export class GardenPointerInput {
private addQuadraticBrushSegments(start: vec2, control: vec2, end: vec2): void {
const curveLength = vec2.distance(start, control) + vec2.distance(control, end);
const brushRadius = Math.max(1, settings.brushSize / 2);
const brushRadius = Math.max(
settings.brushCurveMinBrushRadius,
settings.brushSize / 2
);
const segmentSpacing = Math.max(
GardenPointerInput.MIN_CURVE_SEGMENT_SPACING_PIXELS,
brushRadius * GardenPointerInput.CURVE_SEGMENT_BRUSH_RADIUS_RATIO
settings.brushCurveMinSegmentSpacing,
brushRadius * settings.brushCurveSegmentBrushRadiusRatio
);
const mirrorSegmentCount = Math.max(1, this.options.getMirrorSegmentCount());
const curveResolution = getBrushCurveResolution();
const maxCurveSegments = Math.max(
1,
Math.floor(curveResolution / Math.sqrt(mirrorSegmentCount))
Math.floor(
curveResolution /
Math.max(1, mirrorSegmentCount ** settings.brushCurveMirrorResolutionExponent)
)
);
const segmentCount = Math.min(
maxCurveSegments,
@ -290,7 +292,7 @@ export class GardenPointerInput {
if (
this.lastSmoothedBrushPosition !== null &&
vec2.squaredDistance(this.lastSmoothedBrushPosition, finalSample) >
GardenPointerInput.MIN_SMOOTH_SAMPLE_DISTANCE_SQUARED
getBrushSmoothingDistanceSquared()
) {
this.addMirroredBrushSegment(this.lastSmoothedBrushPosition, finalSample);
}
@ -372,6 +374,13 @@ const getBrushCurveResolution = (): number => {
return Math.max(1, Math.floor(resolution));
};
const getBrushSmoothingDistanceSquared = (): number => {
const distance = Number.isFinite(settings.brushSmoothingMinSampleDistance)
? settings.brushSmoothingMinSampleDistance
: appConfig.defaultSettings.brushSmoothingMinSampleDistance;
return Math.max(0, distance) ** 2;
};
const isSamePointerSample = (left: PointerEvent, right: PointerEvent): boolean =>
left.clientX === right.clientX &&
left.clientY === right.clientY &&