Skip to content

Commit b1ef617

Browse files
committed
implement v2 api
1 parent c68b70e commit b1ef617

File tree

6 files changed

+76
-47
lines changed

6 files changed

+76
-47
lines changed

editable/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// TODO move to legacy.
2+
13
// Generic XML element.
24
export interface IXml {
35
render(): string;

internal/animate/testing/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
<body>
2121
<button id="toggle">TOGGLE<br>DEBUG</button>
2222
<script src="./script.ts"></script>
23-
<script src="../../../legacy/blobs.ts"></script>
2423
</body>
2524

2625
</html>

internal/render/canvas.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,34 @@ const drawPoint = (ctx: CanvasRenderingContext2D, p: Coord, style: string) => {
3434
export const drawClosed = (ctx: CanvasRenderingContext2D, debug: boolean, points: Point[]) => {
3535
if (points.length < 2) throw new Error("not enough points");
3636

37-
forPoints(points, ({curr, next: getNext}) => {
38-
const next = getNext();
37+
// Draw debug points.
38+
if (debug) {
39+
forPoints(points, ({curr, next: getNext}) => {
40+
const next = getNext();
3941

40-
// Compute coordinates of handles.
41-
const currHandle = expandHandle(curr, curr.handleOut);
42-
const nextHandle = expandHandle(next, next.handleIn);
42+
// Compute coordinates of handles.
43+
const currHandle = expandHandle(curr, curr.handleOut);
44+
const nextHandle = expandHandle(next, next.handleIn);
4345

44-
if (debug) {
4546
drawPoint(ctx, curr, "");
4647
drawLine(ctx, curr, currHandle, "#ccc");
4748
drawLine(ctx, next, nextHandle, "#b6b");
48-
}
49+
});
50+
}
51+
52+
ctx.stroke(renderPath2D(points));
53+
};
4954

50-
// Draw curve between curr and next points.
51-
ctx.beginPath();
52-
ctx.moveTo(curr.x, curr.y);
53-
ctx.bezierCurveTo(currHandle.x, currHandle.y, nextHandle.x, nextHandle.y, next.x, next.y);
54-
ctx.stroke();
55+
export const renderPath2D = (points: Point[]): Path2D => {
56+
const path = new Path2D();
57+
path.moveTo(points[0].x, points[0].y);
58+
59+
forPoints(points, ({curr, next: getNext}) => {
60+
const next = getNext();
61+
const currHandle = expandHandle(curr, curr.handleOut);
62+
const nextHandle = expandHandle(next, next.handleIn);
63+
path.bezierCurveTo(currHandle.x, currHandle.y, nextHandle.x, nextHandle.y, next.x, next.y);
5564
});
65+
66+
return path;
5667
};

public/blobs.ts

Lines changed: 46 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ import {genBlob} from "../internal/gen";
22
import {rand} from "../internal/rand";
33
import {Point} from "../internal/types";
44
import {mapPoints} from "../internal/util";
5-
import {renderPath, renderEditable} from "../internal/render/svg";
6-
7-
// TODO include editable types in this file
8-
// TODO make path editable in editable svg
9-
// TODO make editable svg more structured
5+
import {renderPath} from "../internal/render/svg";
6+
import {renderPath2D} from "../internal/render/canvas";
107

118
export interface BlobOptions {
129
seed: string | number;
@@ -15,18 +12,32 @@ export interface BlobOptions {
1512
size: number;
1613
}
1714

18-
export interface CanvasOptions {}
15+
export interface CanvasOptions {
16+
offsetX?: number;
17+
offsetY?: number;
18+
}
1919

2020
export interface SvgOptions {
21-
style: {
22-
color: string;
23-
strokeColor: string;
24-
}
21+
fill?: string;
22+
stroke?: string;
23+
strokeWidth?: number;
2524
}
2625

26+
const typeCheck = (name: string, val: any, expected: string[]) => {
27+
const actual = typeof val;
28+
if (!expected.includes(actual)) {
29+
throw `(blobs2) "${name}" should have type "${expected.join("|")}" but was "${actual}".`;
30+
}
31+
};
32+
2733
export const raw = (blobOptions: BlobOptions): Point[] => {
2834
const rgen = rand(String(blobOptions.seed));
2935

36+
typeCheck("seed", blobOptions.seed, ["string", "number"]);
37+
typeCheck("extraPoints", blobOptions.extraPoints, ["number"]);
38+
typeCheck("randomness", blobOptions.randomness, ["number"]);
39+
typeCheck("size", blobOptions.size, ["number"]);
40+
3041
// Scale of random movement increases as randomness approaches infinity.
3142
// randomness = 0 -> rangeStart = 1
3243
// randomness = 2 -> rangeStart = 0.8333
@@ -39,39 +50,41 @@ export const raw = (blobOptions: BlobOptions): Point[] => {
3950

4051
const points = genBlob(
4152
3 + Math.abs(blobOptions.extraPoints),
42-
() => rangeStart + rgen() * (1 - rangeStart),
53+
() => (rangeStart + rgen() * (1 - rangeStart)) / 2,
4354
);
4455

56+
const size = Math.abs(blobOptions.size);
4557
return mapPoints(points, ({curr}) => {
46-
curr.x *= blobOptions.size;
47-
curr.y *= blobOptions.size;
48-
curr.handleIn.length *= blobOptions.size;
49-
curr.handleOut.length *= blobOptions.size;
58+
curr.x *= size;
59+
curr.y *= size;
60+
curr.handleIn.length *= size;
61+
curr.handleOut.length *= size;
5062
return curr;
5163
});
5264
};
5365

54-
export const canvas = (blobOptions: BlobOptions, canvasOptions: CanvasOptions) => {
55-
// TODO
66+
export const canvas = (blobOptions: BlobOptions, canvasOptions: CanvasOptions): Path2D => {
67+
return renderPath2D(
68+
mapPoints(raw(blobOptions), ({curr}) => {
69+
curr.x += canvasOptions.offsetX || 0;
70+
curr.y += canvasOptions.offsetY || 0;
71+
return curr;
72+
}),
73+
);
5674
};
5775

58-
export const svg = (blobOptions: BlobOptions, svgOptions: SvgOptions) => {};
76+
export const svg = (blobOptions: BlobOptions, svgOptions: SvgOptions): string => {
77+
const path = svgPath(blobOptions);
78+
const size = Math.floor(blobOptions.size);
79+
const fill = svgOptions.fill === undefined ? "#ec576b" : svgOptions.fill;
80+
const stroke = svgOptions.stroke === undefined ? "none" : svgOptions.stroke;
81+
const strokeWidth = svgOptions.strokeWidth === undefined ? 1 : svgOptions.strokeWidth;
82+
return `
83+
<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
84+
<path stroke="${stroke}" stroke-width="${strokeWidth}" fill="${fill}" d="${path}"/>
85+
</svg>`.trim();
86+
};
5987

6088
export const svgPath = (blobOptions: BlobOptions): string => {
6189
return renderPath(raw(blobOptions));
6290
};
63-
64-
export const svgEditable = (blobOptions: BlobOptions, svgOptions: SvgOptions) => {
65-
// TODO fill from svgOptions
66-
// return renderEditable(raw(blobOptions), {
67-
// closed: true,
68-
// height: blobOptions.size,
69-
// width: blobOptions.size,
70-
// boundingBox: false,
71-
// fill: "",
72-
// guides: false,
73-
// stroke: "",
74-
// strokeWidth: 0,
75-
// transform: "",
76-
// });
77-
};

public/legacy.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {XmlElement} from "../editable";
44
import {genBlob} from "../internal/gen";
55
import {mapPoints} from "../internal/util";
66

7+
// TODO check if file (ex. file://...)
78
const isBrowser = new Function("try {return this===window;}catch(e){ return false;}");
89
const isLocalhost = () => location.hostname === "localhost" || location.hostname === "127.0.0.1";
910
if (!isBrowser() || (isBrowser() && isLocalhost())) {

rollup.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,17 @@ import {uglify} from "rollup-plugin-uglify";
33

44
const bundles = [
55
{
6+
name: "blobs",
67
entry: "public/legacy.ts",
78
output: "index.js",
89
},
910
{
11+
name: "blobs",
1012
entry: "public/legacy.ts",
1113
output: "v1/index.js",
1214
},
1315
{
16+
name: "blobs2",
1417
entry: "public/blobs.ts",
1518
output: "v2/index.js",
1619
},
@@ -21,7 +24,7 @@ export default bundles.map((bundle) => ({
2124
output: {
2225
file: bundle.output,
2326
format: "umd",
24-
name: "blobs",
27+
name: bundle.name,
2528
sourcemap: true,
2629
},
2730
plugins: [typescript({cacheRoot: "./node_modules/.cache/rpt2"}), uglify()],

0 commit comments

Comments
 (0)