@@ -2,11 +2,8 @@ import {genBlob} from "../internal/gen";
22import { rand } from "../internal/rand" ;
33import { Point } from "../internal/types" ;
44import { 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
118export 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
2020export 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+
2733export 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
6088export 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- } ;
0 commit comments