This commit is contained in:
Andras Schmelczer 2026-05-18 08:11:52 +01:00
commit 15e99380b5
84 changed files with 1659 additions and 4726 deletions

View file

@ -4,7 +4,7 @@ import { GardenAudio } from '../audio/garden-audio';
import { appConfig } from '../config';
import {
BrushPipeline,
getSafeDevicePixelRatio,
getSafePixelRatio,
} from '../pipelines/brush/brush-pipeline';
import { EraserAgentPipeline } from '../pipelines/eraser/eraser-agent-pipeline';
import { EraserTexturePipeline } from '../pipelines/eraser/eraser-texture-pipeline';
@ -19,7 +19,7 @@ interface GardenPointerInputOptions {
eraserAgentPipeline: EraserAgentPipeline;
eraserTexturePipeline: EraserTexturePipeline;
eraserPreview: EraserPreview;
getDevicePixelRatio: () => number;
getCanvasPixelRatio: () => number;
getMirrorSegmentCount: () => number;
onStartDrawing: () => void;
onEraseGestureEnded: () => void;
@ -106,9 +106,7 @@ export class GardenPointerInput {
return;
}
if (event.pointerType !== 'touch') {
this.options.audio.start(activeVibe, { userGesture: true });
}
this.options.audio.start(activeVibe, { userGesture: true });
this.options.audio.beginGesture();
this.options.onStartDrawing();
this.activePointerId = event.pointerId;
@ -204,12 +202,11 @@ export class GardenPointerInput {
private getCanvasPointerPosition(event: PointerEvent): vec2 {
const rect = this.canvas.getBoundingClientRect();
const devicePixelRatio = getSafeDevicePixelRatio(
this.options.getDevicePixelRatio()
);
const xScale = getSafePixelRatio(this.canvas.width / rect.width);
const yScale = getSafePixelRatio(this.canvas.height / rect.height);
return vec2.fromValues(
(event.clientX - rect.left) * devicePixelRatio,
(event.clientY - rect.top) * devicePixelRatio
(event.clientX - rect.left) * xScale,
(event.clientY - rect.top) * yScale
);
}
@ -219,7 +216,7 @@ export class GardenPointerInput {
if (
previousSample !== undefined &&
vec2.squaredDistance(previousSample, position) <=
getBrushSmoothingDistanceSquared(this.options.getDevicePixelRatio())
getBrushSmoothingDistanceSquared(this.options.getCanvasPixelRatio())
) {
return;
}
@ -253,13 +250,15 @@ export class GardenPointerInput {
private addQuadraticBrushSegments(start: vec2, control: vec2, end: vec2): void {
const curveLength = vec2.distance(start, control) + vec2.distance(control, end);
const devicePixelRatio = getSafeDevicePixelRatio(this.options.getDevicePixelRatio());
const canvasPixelRatio = getSafePixelRatio(
this.options.getCanvasPixelRatio()
);
const brushRadius = Math.max(
settings.brushCurveMinBrushRadius * devicePixelRatio,
(settings.brushSize * devicePixelRatio) / 2
settings.brushCurveMinBrushRadius * canvasPixelRatio,
(settings.brushSize * canvasPixelRatio) / 2
);
const segmentSpacing = Math.max(
settings.brushCurveMinSegmentSpacing * devicePixelRatio,
settings.brushCurveMinSegmentSpacing * canvasPixelRatio,
brushRadius * settings.brushCurveSegmentBrushRadiusRatio
);
const mirrorSegmentCount = Math.max(1, this.options.getMirrorSegmentCount());
@ -299,7 +298,7 @@ export class GardenPointerInput {
if (
this.lastSmoothedBrushPosition !== null &&
vec2.squaredDistance(this.lastSmoothedBrushPosition, finalSample) >
getBrushSmoothingDistanceSquared(this.options.getDevicePixelRatio())
getBrushSmoothingDistanceSquared(this.options.getCanvasPixelRatio())
) {
this.addMirroredBrushSegment(this.lastSmoothedBrushPosition, finalSample);
}
@ -381,11 +380,11 @@ const getBrushCurveResolution = (): number => {
return Math.max(1, Math.floor(resolution));
};
const getBrushSmoothingDistanceSquared = (devicePixelRatio?: number): number => {
const getBrushSmoothingDistanceSquared = (pixelRatio?: number): number => {
const distance = Number.isFinite(settings.brushSmoothingMinSampleDistance)
? settings.brushSmoothingMinSampleDistance
: appConfig.defaultSettings.brushSmoothingMinSampleDistance;
return Math.max(0, distance * getSafeDevicePixelRatio(devicePixelRatio)) ** 2;
return Math.max(0, distance * getSafePixelRatio(pixelRatio)) ** 2;
};
const isSamePointerSample = (left: PointerEvent, right: PointerEvent): boolean =>