feature: vor und nachteile

This commit is contained in:
Hikyu
2026-05-31 13:54:31 +02:00
parent 552a947a1c
commit e3dad17446
23270 changed files with 3024794 additions and 200 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-2021 Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+310
View File
@@ -0,0 +1,310 @@
interface Unsubscribe {
(): void
}
/**
* The options object for `getStroke` or `getStrokePoints`.
* @param points An array of points (as `[x, y, pressure]` or `{x, y, pressure}`). Pressure is optional in both cases.
* @param options (optional) An object with options.
* @param options.size The base size (diameter) of the stroke.
* @param options.thinning The effect of pressure on the stroke's size.
* @param options.smoothing How much to soften the stroke's edges.
* @param options.easing An easing function to apply to each point's pressure.
* @param options.simulatePressure Whether to simulate pressure based on velocity.
* @param options.start Cap, taper and easing for the start of the line.
* @param options.end Cap, taper and easing for the end of the line.
* @param options.last Whether to handle the points as a completed stroke.
*/
interface StrokeOptions {
size?: number;
thinning?: number;
smoothing?: number;
streamline?: number;
easing?: (pressure: number) => number;
simulatePressure?: boolean;
start?: {
cap?: boolean;
taper?: number | boolean;
easing?: (distance: number) => number;
};
end?: {
cap?: boolean;
taper?: number | boolean;
easing?: (distance: number) => number;
};
last?: boolean;
}
type DrawingMode = 'draw' | 'stylus' | 'line' | 'rectangle' | 'ellipse' | 'eraseLine';
interface Brush {
/**
* @default 'brush'
*/
mode?: DrawingMode;
/**
* Stroke color
*/
color: string;
/**
* Stroke width
*/
size: number;
/**
* Color filled, only works in `rectangle` and `ellipse` mode.
* @default 'transparent'
*/
fill?: string;
/**
* Pattern of dashes, set to `undefined` for solid line.
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
*/
dasharray?: string;
/**
* Corner radius of the rectangle.
* Works only in `rectangle` mode.
*
* @default 0
*/
cornerRadius?: number;
/**
* Show an arrow at the end of the line.
* Works only in `draw` and `line` mode.
*
* @default false
*/
arrowEnd?: boolean;
/**
* Options for 'perfect-freehand'
*/
stylusOptions?: StrokeOptions;
}
interface Point {
x: number;
y: number;
pressure?: number;
}
interface Options {
el?: string | SVGSVGElement;
brush?: Brush;
/**
* Filter out events based on input type
*
* @default ['mouse', 'touch', 'pen']
*/
acceptsInputTypes?: ('mouse' | 'touch' | 'pen')[];
/**
* Use different element to listen on the events
*
* @default the `el` option
*/
eventTarget?: string | Element;
/**
* Listen to a different window for mouse events.
* Useful when you have an iframe or a popup.
*
* @default window
*/
window?: Window;
/**
* When you apply a scale transform to the svg container,
* set this property to let drauu aware of the currect coordinates.
* @default 1
*/
coordinateScale?: number;
/**
* Apply SVG CTM transform when calculating the coordinates.
*
* @advanced you don't commonly need this
* @default true
*/
coordinateTransform?: boolean;
/**
* To calculate the correct touch and mouse event positions for
* elements using the zoom property on older Chrome versions(before 96)
* @default 1
*/
cssZoom?: number;
/**
* Sets the offset of the transformation when calculating coordinates.
*
* @default { x: 0, y: 0 }
*/
offset?: {
x: number;
y: number;
};
}
interface EventsMap {
start: () => void;
end: () => void;
committed: (node: SVGElement | undefined) => void;
canceled: () => void;
changed: () => void;
mounted: () => void;
unmounted: () => void;
}
interface Operation {
undo: () => void;
redo: () => void;
}
declare abstract class BaseModel<T extends SVGElement> {
protected drauu: Drauu;
event: PointerEvent;
point: Point;
start: Point;
el: T | null;
constructor(drauu: Drauu);
onSelected(_el: SVGSVGElement | null): void;
onUnselected(): void;
onStart(_point: Point): SVGElement | undefined;
onMove(_point: Point): boolean;
onEnd(_point: Point): Operation | boolean | undefined;
get brush(): Brush;
get shiftPressed(): boolean;
get altPressed(): boolean;
get svgElement(): SVGSVGElement | null;
getMousePosition(event: PointerEvent): Point;
protected createElement<K extends keyof SVGElementTagNameMap>(name: K, overrides?: Partial<Brush>): SVGElementTagNameMap[K];
protected attr(name: string, value: string | number): void;
private _setEvent;
/**
* @internal
*/
_eventDown(event: PointerEvent): SVGElement | undefined;
/**
* @internal
*/
_eventMove(event: PointerEvent): boolean;
/**
* @internal
*/
_eventUp(event: PointerEvent): boolean | Operation | undefined;
}
declare class DrawModel extends BaseModel<SVGPathElement> {
points: Point[];
private count;
private arrowId;
onStart(point: Point): SVGPathElement;
onMove(point: Point): boolean;
onEnd(): boolean;
static line(a: Point, b: Point): {
length: number;
angle: number;
};
static controlPoint(current: Point, previous: Point, next?: Point, reverse?: boolean): {
x: number;
y: number;
};
static bezierCommand(point: Point, i: number, points: Point[]): string;
static toSvgData(points: Point[]): string;
}
declare class EllipseModel extends BaseModel<SVGEllipseElement> {
onStart(point: Point): SVGEllipseElement;
onMove(point: Point): boolean;
onEnd(): boolean;
}
interface EraserPathFragment {
x1: number;
x2: number;
y1: number;
y2: number;
segment: number;
element: any;
}
declare class EraserModel extends BaseModel<SVGRectElement> {
svgPointPrevious?: DOMPoint;
svgPointCurrent?: DOMPoint;
pathSubFactor: number;
pathFragments: EraserPathFragment[];
private _erased;
onSelected(el: SVGSVGElement | null): void;
onUnselected(): void;
onStart(point: Point): undefined;
onMove(point: Point): boolean;
onEnd(): Operation;
private checkAndEraseElement;
private lineLineIntersect;
}
declare class LineModel extends BaseModel<SVGLineElement> {
onStart(point: Point): SVGGElement;
onMove(point: Point): boolean;
onEnd(): boolean;
}
declare class RectModel extends BaseModel<SVGRectElement> {
onStart(point: Point): SVGRectElement;
onMove(point: Point): boolean;
onEnd(): boolean;
}
declare class StylusModel extends BaseModel<SVGPathElement> {
points: Point[];
onStart(point: Point): SVGPathElement;
onMove(point: Point): boolean;
onEnd(): boolean;
getSvgData(points: Point[]): string;
static getSvgData(points: Point[], brush: Brush): string;
}
declare class Drauu {
options: Options;
el: SVGSVGElement | null;
svgPoint: DOMPoint | null;
eventEl: Element | null;
shiftPressed: boolean;
altPressed: boolean;
drawing: boolean;
private _emitter;
private _originalPointerId;
private _models;
private _currentNode;
private _opStack;
private _opIndex;
private _disposables;
private _elements;
constructor(options?: Options);
get model(): DrawModel | EllipseModel | EraserModel | LineModel | RectModel | StylusModel;
get mounted(): boolean;
get mode(): DrawingMode;
set mode(v: DrawingMode);
get brush(): Brush;
set brush(v: Brush);
resolveSelector<T>(selector: string | T | null | undefined): T | null;
mount(el: string | SVGSVGElement, eventEl?: string | Element, listenWindow?: Window): void;
unmount(): void;
on<K extends keyof EventsMap>(type: K, fn: EventsMap[K]): Unsubscribe;
undo(): boolean;
redo(): boolean;
canRedo(): boolean;
canUndo(): boolean;
private eventMove;
private eventStart;
private eventEnd;
private acceptsInput;
private eventKeyboard;
private commit;
clear(): void;
cancel(): void;
dump(): string;
load(svg: string): void;
/**
* @internal
*/
_appendNode(node: SVGElement): void;
/**
* @internal
*/
_removeNode(node: SVGElement): void;
/**
* @internal
*/
_restoreNode(node: SVGElement): void;
}
declare function createDrauu(options?: Options): Drauu;
export { type Brush, Drauu, DrawModel, type DrawingMode, EllipseModel, EraserModel, type EventsMap, LineModel, type Operation, type Options, type Point, RectModel, StylusModel, createDrauu };
+310
View File
@@ -0,0 +1,310 @@
interface Unsubscribe {
(): void
}
/**
* The options object for `getStroke` or `getStrokePoints`.
* @param points An array of points (as `[x, y, pressure]` or `{x, y, pressure}`). Pressure is optional in both cases.
* @param options (optional) An object with options.
* @param options.size The base size (diameter) of the stroke.
* @param options.thinning The effect of pressure on the stroke's size.
* @param options.smoothing How much to soften the stroke's edges.
* @param options.easing An easing function to apply to each point's pressure.
* @param options.simulatePressure Whether to simulate pressure based on velocity.
* @param options.start Cap, taper and easing for the start of the line.
* @param options.end Cap, taper and easing for the end of the line.
* @param options.last Whether to handle the points as a completed stroke.
*/
interface StrokeOptions {
size?: number;
thinning?: number;
smoothing?: number;
streamline?: number;
easing?: (pressure: number) => number;
simulatePressure?: boolean;
start?: {
cap?: boolean;
taper?: number | boolean;
easing?: (distance: number) => number;
};
end?: {
cap?: boolean;
taper?: number | boolean;
easing?: (distance: number) => number;
};
last?: boolean;
}
type DrawingMode = 'draw' | 'stylus' | 'line' | 'rectangle' | 'ellipse' | 'eraseLine';
interface Brush {
/**
* @default 'brush'
*/
mode?: DrawingMode;
/**
* Stroke color
*/
color: string;
/**
* Stroke width
*/
size: number;
/**
* Color filled, only works in `rectangle` and `ellipse` mode.
* @default 'transparent'
*/
fill?: string;
/**
* Pattern of dashes, set to `undefined` for solid line.
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray
*/
dasharray?: string;
/**
* Corner radius of the rectangle.
* Works only in `rectangle` mode.
*
* @default 0
*/
cornerRadius?: number;
/**
* Show an arrow at the end of the line.
* Works only in `draw` and `line` mode.
*
* @default false
*/
arrowEnd?: boolean;
/**
* Options for 'perfect-freehand'
*/
stylusOptions?: StrokeOptions;
}
interface Point {
x: number;
y: number;
pressure?: number;
}
interface Options {
el?: string | SVGSVGElement;
brush?: Brush;
/**
* Filter out events based on input type
*
* @default ['mouse', 'touch', 'pen']
*/
acceptsInputTypes?: ('mouse' | 'touch' | 'pen')[];
/**
* Use different element to listen on the events
*
* @default the `el` option
*/
eventTarget?: string | Element;
/**
* Listen to a different window for mouse events.
* Useful when you have an iframe or a popup.
*
* @default window
*/
window?: Window;
/**
* When you apply a scale transform to the svg container,
* set this property to let drauu aware of the currect coordinates.
* @default 1
*/
coordinateScale?: number;
/**
* Apply SVG CTM transform when calculating the coordinates.
*
* @advanced you don't commonly need this
* @default true
*/
coordinateTransform?: boolean;
/**
* To calculate the correct touch and mouse event positions for
* elements using the zoom property on older Chrome versions(before 96)
* @default 1
*/
cssZoom?: number;
/**
* Sets the offset of the transformation when calculating coordinates.
*
* @default { x: 0, y: 0 }
*/
offset?: {
x: number;
y: number;
};
}
interface EventsMap {
start: () => void;
end: () => void;
committed: (node: SVGElement | undefined) => void;
canceled: () => void;
changed: () => void;
mounted: () => void;
unmounted: () => void;
}
interface Operation {
undo: () => void;
redo: () => void;
}
declare abstract class BaseModel<T extends SVGElement> {
protected drauu: Drauu;
event: PointerEvent;
point: Point;
start: Point;
el: T | null;
constructor(drauu: Drauu);
onSelected(_el: SVGSVGElement | null): void;
onUnselected(): void;
onStart(_point: Point): SVGElement | undefined;
onMove(_point: Point): boolean;
onEnd(_point: Point): Operation | boolean | undefined;
get brush(): Brush;
get shiftPressed(): boolean;
get altPressed(): boolean;
get svgElement(): SVGSVGElement | null;
getMousePosition(event: PointerEvent): Point;
protected createElement<K extends keyof SVGElementTagNameMap>(name: K, overrides?: Partial<Brush>): SVGElementTagNameMap[K];
protected attr(name: string, value: string | number): void;
private _setEvent;
/**
* @internal
*/
_eventDown(event: PointerEvent): SVGElement | undefined;
/**
* @internal
*/
_eventMove(event: PointerEvent): boolean;
/**
* @internal
*/
_eventUp(event: PointerEvent): boolean | Operation | undefined;
}
declare class DrawModel extends BaseModel<SVGPathElement> {
points: Point[];
private count;
private arrowId;
onStart(point: Point): SVGPathElement;
onMove(point: Point): boolean;
onEnd(): boolean;
static line(a: Point, b: Point): {
length: number;
angle: number;
};
static controlPoint(current: Point, previous: Point, next?: Point, reverse?: boolean): {
x: number;
y: number;
};
static bezierCommand(point: Point, i: number, points: Point[]): string;
static toSvgData(points: Point[]): string;
}
declare class EllipseModel extends BaseModel<SVGEllipseElement> {
onStart(point: Point): SVGEllipseElement;
onMove(point: Point): boolean;
onEnd(): boolean;
}
interface EraserPathFragment {
x1: number;
x2: number;
y1: number;
y2: number;
segment: number;
element: any;
}
declare class EraserModel extends BaseModel<SVGRectElement> {
svgPointPrevious?: DOMPoint;
svgPointCurrent?: DOMPoint;
pathSubFactor: number;
pathFragments: EraserPathFragment[];
private _erased;
onSelected(el: SVGSVGElement | null): void;
onUnselected(): void;
onStart(point: Point): undefined;
onMove(point: Point): boolean;
onEnd(): Operation;
private checkAndEraseElement;
private lineLineIntersect;
}
declare class LineModel extends BaseModel<SVGLineElement> {
onStart(point: Point): SVGGElement;
onMove(point: Point): boolean;
onEnd(): boolean;
}
declare class RectModel extends BaseModel<SVGRectElement> {
onStart(point: Point): SVGRectElement;
onMove(point: Point): boolean;
onEnd(): boolean;
}
declare class StylusModel extends BaseModel<SVGPathElement> {
points: Point[];
onStart(point: Point): SVGPathElement;
onMove(point: Point): boolean;
onEnd(): boolean;
getSvgData(points: Point[]): string;
static getSvgData(points: Point[], brush: Brush): string;
}
declare class Drauu {
options: Options;
el: SVGSVGElement | null;
svgPoint: DOMPoint | null;
eventEl: Element | null;
shiftPressed: boolean;
altPressed: boolean;
drawing: boolean;
private _emitter;
private _originalPointerId;
private _models;
private _currentNode;
private _opStack;
private _opIndex;
private _disposables;
private _elements;
constructor(options?: Options);
get model(): DrawModel | EllipseModel | EraserModel | LineModel | RectModel | StylusModel;
get mounted(): boolean;
get mode(): DrawingMode;
set mode(v: DrawingMode);
get brush(): Brush;
set brush(v: Brush);
resolveSelector<T>(selector: string | T | null | undefined): T | null;
mount(el: string | SVGSVGElement, eventEl?: string | Element, listenWindow?: Window): void;
unmount(): void;
on<K extends keyof EventsMap>(type: K, fn: EventsMap[K]): Unsubscribe;
undo(): boolean;
redo(): boolean;
canRedo(): boolean;
canUndo(): boolean;
private eventMove;
private eventStart;
private eventEnd;
private acceptsInput;
private eventKeyboard;
private commit;
clear(): void;
cancel(): void;
dump(): string;
load(svg: string): void;
/**
* @internal
*/
_appendNode(node: SVGElement): void;
/**
* @internal
*/
_removeNode(node: SVGElement): void;
/**
* @internal
*/
_restoreNode(node: SVGElement): void;
}
declare function createDrauu(options?: Options): Drauu;
export { type Brush, Drauu, DrawModel, type DrawingMode, EllipseModel, EraserModel, type EventsMap, LineModel, type Operation, type Options, type Point, RectModel, StylusModel, createDrauu };
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+38
View File
@@ -0,0 +1,38 @@
{
"name": "@drauu/core",
"version": "0.4.3",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/antfu/drauu#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/antfu/drauu.git"
},
"bugs": {
"url": "https://github.com/antfu/drauu/issues"
},
"keywords": [],
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"unpkg": "dist/index.global.js",
"jsdelivr": "dist/index.global.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"devDependencies": {
"perfect-freehand": "^1.2.2"
},
"scripts": {
"dev": "nr build --watch",
"build": "tsup src/index.ts --format esm,cjs,iife --dts --no-splitting --clean --dts-resolve"
}
}