First commit.

Signed-off-by: Chen Xiao <abigwc@gmail.com>
This commit is contained in:
Chen Xiao
2026-05-08 14:43:16 +08:00
commit 0b64e2de94
10989 changed files with 2253791 additions and 0 deletions
+23
View File
@@ -0,0 +1,23 @@
import { Config, Options, ResolvedOptions, Drawable } from './core';
import { RoughGenerator } from './generator';
import { Point } from './geometry';
export declare class RoughCanvas {
private gen;
private canvas;
private ctx;
constructor(canvas: HTMLCanvasElement, config?: Config);
draw(drawable: Drawable): void;
private fillSketch;
private _drawToContext;
get generator(): RoughGenerator;
getDefaultOptions(): ResolvedOptions;
line(x1: number, y1: number, x2: number, y2: number, options?: Options): Drawable;
rectangle(x: number, y: number, width: number, height: number, options?: Options): Drawable;
ellipse(x: number, y: number, width: number, height: number, options?: Options): Drawable;
circle(x: number, y: number, diameter: number, options?: Options): Drawable;
linearPath(points: Point[], options?: Options): Drawable;
polygon(points: Point[], options?: Options): Drawable;
arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed?: boolean, options?: Options): Drawable;
curve(points: Point[] | Point[][], options?: Options): Drawable;
path(d: string, options?: Options): Drawable;
}
+85
View File
@@ -0,0 +1,85 @@
import { Point } from './geometry';
import { Random } from './math';
export declare const SVGNS = "http://www.w3.org/2000/svg";
export interface Config {
options?: Options;
}
export interface DrawingSurface {
width: number | SVGAnimatedLength;
height: number | SVGAnimatedLength;
}
export interface Options {
maxRandomnessOffset?: number;
roughness?: number;
bowing?: number;
stroke?: string;
strokeWidth?: number;
curveFitting?: number;
curveTightness?: number;
curveStepCount?: number;
fill?: string;
fillStyle?: string;
fillWeight?: number;
hachureAngle?: number;
hachureGap?: number;
simplification?: number;
dashOffset?: number;
dashGap?: number;
zigzagOffset?: number;
seed?: number;
strokeLineDash?: number[];
strokeLineDashOffset?: number;
fillLineDash?: number[];
fillLineDashOffset?: number;
disableMultiStroke?: boolean;
disableMultiStrokeFill?: boolean;
preserveVertices?: boolean;
fixedDecimalPlaceDigits?: number;
fillShapeRoughnessGain?: number;
}
export interface ResolvedOptions extends Options {
maxRandomnessOffset: number;
roughness: number;
bowing: number;
stroke: string;
strokeWidth: number;
curveFitting: number;
curveTightness: number;
curveStepCount: number;
fillStyle: string;
fillWeight: number;
hachureAngle: number;
hachureGap: number;
dashOffset: number;
dashGap: number;
zigzagOffset: number;
seed: number;
randomizer?: Random;
disableMultiStroke: boolean;
disableMultiStrokeFill: boolean;
preserveVertices: boolean;
fillShapeRoughnessGain: number;
}
export declare type OpType = 'move' | 'bcurveTo' | 'lineTo';
export declare type OpSetType = 'path' | 'fillPath' | 'fillSketch';
export interface Op {
op: OpType;
data: number[];
}
export interface OpSet {
type: OpSetType;
ops: Op[];
size?: Point;
path?: string;
}
export interface Drawable {
shape: string;
options: ResolvedOptions;
sets: OpSet[];
}
export interface PathInfo {
d: string;
stroke: string;
strokeWidth: number;
fill?: string;
}
+9
View File
@@ -0,0 +1,9 @@
import { PatternFiller, RenderHelper } from './filler-interface';
import { ResolvedOptions, OpSet } from '../core';
import { Point } from '../geometry';
export declare class DashedFiller implements PatternFiller {
private helper;
constructor(helper: RenderHelper);
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
private dashedLine;
}
+9
View File
@@ -0,0 +1,9 @@
import { PatternFiller, RenderHelper } from './filler-interface';
import { ResolvedOptions, OpSet } from '../core';
import { Point } from '../geometry';
export declare class DotFiller implements PatternFiller {
private helper;
constructor(helper: RenderHelper);
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
private dotsOnLines;
}
+11
View File
@@ -0,0 +1,11 @@
import { ResolvedOptions, OpSet, Op } from '../core';
import { Point } from '../geometry';
export interface PatternFiller {
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
}
export interface RenderHelper {
randOffset(x: number, o: ResolvedOptions): number;
randOffsetWithRange(min: number, max: number, o: ResolvedOptions): number;
ellipse(x: number, y: number, width: number, height: number, o: ResolvedOptions): OpSet;
doubleLineOps(x1: number, y1: number, x2: number, y2: number, o: ResolvedOptions): Op[];
}
+3
View File
@@ -0,0 +1,3 @@
import { ResolvedOptions } from '../core';
import { PatternFiller, RenderHelper } from './filler-interface';
export declare function getFiller(o: ResolvedOptions, helper: RenderHelper): PatternFiller;
+10
View File
@@ -0,0 +1,10 @@
import { PatternFiller, RenderHelper } from './filler-interface';
import { ResolvedOptions, OpSet, Op } from '../core';
import { Point, Line } from '../geometry';
export declare class HachureFiller implements PatternFiller {
private helper;
constructor(helper: RenderHelper);
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
protected _fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
protected renderLines(lines: Line[], o: ResolvedOptions): Op[];
}
+6
View File
@@ -0,0 +1,6 @@
import { HachureFiller } from './hachure-filler';
import { ResolvedOptions, OpSet } from '../core';
import { Point } from '../geometry';
export declare class HatchFiller extends HachureFiller {
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
}
+3
View File
@@ -0,0 +1,3 @@
import { Point, Line } from '../geometry';
import { ResolvedOptions } from '../core';
export declare function polygonHachureLines(polygonList: Point[][], o: ResolvedOptions): Line[];
+6
View File
@@ -0,0 +1,6 @@
import { HachureFiller } from './hachure-filler';
import { ResolvedOptions, OpSet } from '../core';
import { Point } from '../geometry';
export declare class ZigZagFiller extends HachureFiller {
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
}
+9
View File
@@ -0,0 +1,9 @@
import { PatternFiller, RenderHelper } from './filler-interface';
import { ResolvedOptions, OpSet } from '../core';
import { Point } from '../geometry';
export declare class ZigZagLineFiller implements PatternFiller {
private helper;
constructor(helper: RenderHelper);
fillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
private zigzagLines;
}
+23
View File
@@ -0,0 +1,23 @@
import { Config, Options, Drawable, OpSet, ResolvedOptions, PathInfo } from './core.js';
import { Point } from './geometry.js';
export declare class RoughGenerator {
private config;
defaultOptions: ResolvedOptions;
constructor(config?: Config);
static newSeed(): number;
private _o;
private _d;
line(x1: number, y1: number, x2: number, y2: number, options?: Options): Drawable;
rectangle(x: number, y: number, width: number, height: number, options?: Options): Drawable;
ellipse(x: number, y: number, width: number, height: number, options?: Options): Drawable;
circle(x: number, y: number, diameter: number, options?: Options): Drawable;
linearPath(points: Point[], options?: Options): Drawable;
arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed?: boolean, options?: Options): Drawable;
curve(points: Point[] | Point[][], options?: Options): Drawable;
polygon(points: Point[], options?: Options): Drawable;
path(d: string, options?: Options): Drawable;
opsToPath(drawing: OpSet, fixedDecimals?: number): string;
toPaths(drawable: Drawable): PathInfo[];
private fillSketch;
private _mergedShape;
}
+9
View File
@@ -0,0 +1,9 @@
export type Point = [number, number];
export type Line = [Point, Point];
export interface Rectangle {
x: number;
y: number;
width: number;
height: number;
}
export declare function lineLength(line: Line): number;
+6
View File
@@ -0,0 +1,6 @@
export declare function randomSeed(): number;
export declare class Random {
private seed;
constructor(seed: number);
next(): number;
}
+28
View File
@@ -0,0 +1,28 @@
import { ResolvedOptions, Op, OpSet } from './core.js';
import { Point } from './geometry.js';
interface EllipseParams {
rx: number;
ry: number;
increment: number;
}
export declare function line(x1: number, y1: number, x2: number, y2: number, o: ResolvedOptions): OpSet;
export declare function linearPath(points: Point[], close: boolean, o: ResolvedOptions): OpSet;
export declare function polygon(points: Point[], o: ResolvedOptions): OpSet;
export declare function rectangle(x: number, y: number, width: number, height: number, o: ResolvedOptions): OpSet;
export declare function curve(inputPoints: Point[] | Point[][], o: ResolvedOptions): OpSet;
export interface EllipseResult {
opset: OpSet;
estimatedPoints: Point[];
}
export declare function ellipse(x: number, y: number, width: number, height: number, o: ResolvedOptions): OpSet;
export declare function generateEllipseParams(width: number, height: number, o: ResolvedOptions): EllipseParams;
export declare function ellipseWithParams(x: number, y: number, o: ResolvedOptions, ellipseParams: EllipseParams): EllipseResult;
export declare function arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed: boolean, roughClosure: boolean, o: ResolvedOptions): OpSet;
export declare function svgPath(path: string, o: ResolvedOptions): OpSet;
export declare function solidFillPolygon(polygonList: Point[][], o: ResolvedOptions): OpSet;
export declare function patternFillPolygons(polygonList: Point[][], o: ResolvedOptions): OpSet;
export declare function patternFillArc(x: number, y: number, width: number, height: number, start: number, stop: number, o: ResolvedOptions): OpSet;
export declare function randOffset(x: number, o: ResolvedOptions): number;
export declare function randOffsetWithRange(min: number, max: number, o: ResolvedOptions): number;
export declare function doubleLineFillOps(x1: number, y1: number, x2: number, y2: number, o: ResolvedOptions): Op[];
export {};
File diff suppressed because one or more lines are too long
+11
View File
@@ -0,0 +1,11 @@
import { Config } from './core';
import { RoughCanvas } from './canvas';
import { RoughGenerator } from './generator';
import { RoughSVG } from './svg';
declare const _default: {
canvas(canvas: HTMLCanvasElement, config?: Config): RoughCanvas;
svg(svg: SVGSVGElement, config?: Config): RoughSVG;
generator(config?: Config): RoughGenerator;
newSeed(): number;
};
export default _default;
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
+22
View File
@@ -0,0 +1,22 @@
import { Config, Options, OpSet, ResolvedOptions, Drawable } from './core';
import { RoughGenerator } from './generator';
import { Point } from './geometry';
export declare class RoughSVG {
private gen;
private svg;
constructor(svg: SVGSVGElement, config?: Config);
draw(drawable: Drawable): SVGGElement;
private fillSketch;
get generator(): RoughGenerator;
getDefaultOptions(): ResolvedOptions;
opsToPath(drawing: OpSet, fixedDecimalPlaceDigits?: number): string;
line(x1: number, y1: number, x2: number, y2: number, options?: Options): SVGGElement;
rectangle(x: number, y: number, width: number, height: number, options?: Options): SVGGElement;
ellipse(x: number, y: number, width: number, height: number, options?: Options): SVGGElement;
circle(x: number, y: number, diameter: number, options?: Options): SVGGElement;
linearPath(points: Point[], options?: Options): SVGGElement;
polygon(points: Point[], options?: Options): SVGGElement;
arc(x: number, y: number, width: number, height: number, start: number, stop: number, closed?: boolean, options?: Options): SVGGElement;
curve(points: Point[] | Point[][], options?: Options): SVGGElement;
path(d: string, options?: Options): SVGGElement;
}