@franzenzenhofer/asanakit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/dist/anatomy/muscles.d.ts +55 -0
- package/dist/anatomy/muscles.d.ts.map +1 -0
- package/dist/anatomy/muscles.js +79 -0
- package/dist/anatomy/muscles.js.map +1 -0
- package/dist/anatomy/validate.d.ts +11 -0
- package/dist/anatomy/validate.d.ts.map +1 -0
- package/dist/anatomy/validate.js +94 -0
- package/dist/anatomy/validate.js.map +1 -0
- package/dist/cli/commands/export.d.ts +3 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +45 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/info.d.ts +3 -0
- package/dist/cli/commands/info.d.ts.map +1 -0
- package/dist/cli/commands/info.js +101 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/render.d.ts +3 -0
- package/dist/cli/commands/render.d.ts.map +1 -0
- package/dist/cli/commands/render.js +103 -0
- package/dist/cli/commands/render.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +31 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/resolve.d.ts +12 -0
- package/dist/cli/resolve.d.ts.map +1 -0
- package/dist/cli/resolve.js +46 -0
- package/dist/cli/resolve.js.map +1 -0
- package/dist/core/angles.d.ts +12 -0
- package/dist/core/angles.d.ts.map +1 -0
- package/dist/core/angles.js +27 -0
- package/dist/core/angles.js.map +1 -0
- package/dist/core/rig.d.ts +8 -0
- package/dist/core/rig.d.ts.map +1 -0
- package/dist/core/rig.js +97 -0
- package/dist/core/rig.js.map +1 -0
- package/dist/core/skeleton.d.ts +17 -0
- package/dist/core/skeleton.d.ts.map +1 -0
- package/dist/core/skeleton.js +144 -0
- package/dist/core/skeleton.js.map +1 -0
- package/dist/core/types.d.ts +105 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +47 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/vec2.d.ts +19 -0
- package/dist/core/vec2.d.ts.map +1 -0
- package/dist/core/vec2.js +41 -0
- package/dist/core/vec2.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/library/index.d.ts +27 -0
- package/dist/library/index.d.ts.map +1 -0
- package/dist/library/index.js +75 -0
- package/dist/library/index.js.map +1 -0
- package/dist/model/index.d.ts +4 -0
- package/dist/model/index.d.ts.map +1 -0
- package/dist/model/index.js +4 -0
- package/dist/model/index.js.map +1 -0
- package/dist/model/parse.d.ts +12 -0
- package/dist/model/parse.d.ts.map +1 -0
- package/dist/model/parse.js +43 -0
- package/dist/model/parse.js.map +1 -0
- package/dist/model/pose.d.ts +11 -0
- package/dist/model/pose.d.ts.map +1 -0
- package/dist/model/pose.js +26 -0
- package/dist/model/pose.js.map +1 -0
- package/dist/model/schema.d.ts +1122 -0
- package/dist/model/schema.d.ts.map +1 -0
- package/dist/model/schema.js +178 -0
- package/dist/model/schema.js.map +1 -0
- package/dist/render/anatomy.d.ts +10 -0
- package/dist/render/anatomy.d.ts.map +1 -0
- package/dist/render/anatomy.js +77 -0
- package/dist/render/anatomy.js.map +1 -0
- package/dist/render/annotations.d.ts +9 -0
- package/dist/render/annotations.d.ts.map +1 -0
- package/dist/render/annotations.js +185 -0
- package/dist/render/annotations.js.map +1 -0
- package/dist/render/context.d.ts +16 -0
- package/dist/render/context.d.ts.map +1 -0
- package/dist/render/context.js +2 -0
- package/dist/render/context.js.map +1 -0
- package/dist/render/figure.d.ts +8 -0
- package/dist/render/figure.d.ts.map +1 -0
- package/dist/render/figure.js +138 -0
- package/dist/render/figure.js.map +1 -0
- package/dist/render/index.d.ts +7 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +7 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/project.d.ts +18 -0
- package/dist/render/project.d.ts.map +1 -0
- package/dist/render/project.js +35 -0
- package/dist/render/project.js.map +1 -0
- package/dist/render/props.d.ts +9 -0
- package/dist/render/props.d.ts.map +1 -0
- package/dist/render/props.js +178 -0
- package/dist/render/props.js.map +1 -0
- package/dist/render/raster.d.ts +19 -0
- package/dist/render/raster.d.ts.map +1 -0
- package/dist/render/raster.js +39 -0
- package/dist/render/raster.js.map +1 -0
- package/dist/render/scene.d.ts +26 -0
- package/dist/render/scene.d.ts.map +1 -0
- package/dist/render/scene.js +144 -0
- package/dist/render/scene.js.map +1 -0
- package/dist/render/sheet.d.ts +20 -0
- package/dist/render/sheet.d.ts.map +1 -0
- package/dist/render/sheet.js +74 -0
- package/dist/render/sheet.js.map +1 -0
- package/dist/render/styles.d.ts +77 -0
- package/dist/render/styles.d.ts.map +1 -0
- package/dist/render/styles.js +122 -0
- package/dist/render/styles.js.map +1 -0
- package/dist/render/svg.d.ts +19 -0
- package/dist/render/svg.d.ts.map +1 -0
- package/dist/render/svg.js +40 -0
- package/dist/render/svg.js.map +1 -0
- package/dist/standards/keypoints.d.ts +31 -0
- package/dist/standards/keypoints.d.ts.map +1 -0
- package/dist/standards/keypoints.js +118 -0
- package/dist/standards/keypoints.js.map +1 -0
- package/docs/AUTHORING.md +144 -0
- package/package.json +94 -0
- package/poses/surf/bottom-turn.pose.yaml +47 -0
- package/poses/surf/cutback.pose.yaml +47 -0
- package/poses/surf/duck-dive.pose.yaml +47 -0
- package/poses/surf/noseride.pose.yaml +48 -0
- package/poses/surf/paddling.pose.yaml +48 -0
- package/poses/surf/pop-up.pose.yaml +47 -0
- package/poses/surf/takeoff.pose.yaml +47 -0
- package/poses/surf/tube-stance.pose.yaml +47 -0
- package/poses/yoga/ashtanga/adho-mukha-svanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/ardha-uttanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/baddha-konasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/balasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/chaturanga-dandasana.pose.yaml +41 -0
- package/poses/yoga/ashtanga/dandasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/halasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/janu-sirsasana-a.pose.yaml +42 -0
- package/poses/yoga/ashtanga/karnapidasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/marichyasana-a.pose.yaml +42 -0
- package/poses/yoga/ashtanga/marichyasana-c.pose.yaml +42 -0
- package/poses/yoga/ashtanga/matsyasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/navasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/padahastasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/padangusthasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/padmasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/parsvottanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/paschimottanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/prasarita-padottanasana-a.pose.yaml +46 -0
- package/poses/yoga/ashtanga/prasarita-padottanasana-c.pose.yaml +46 -0
- package/poses/yoga/ashtanga/primary.seq.yaml +74 -0
- package/poses/yoga/ashtanga/purvottanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/salamba-sarvangasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/samasthiti.pose.yaml +29 -0
- package/poses/yoga/ashtanga/savasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/setu-bandhasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/sirsasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/supta-padangusthasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/upavistha-konasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/urdhva-dhanurasana.pose.yaml +43 -0
- package/poses/yoga/ashtanga/urdhva-hastasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/urdhva-mukha-svanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/utkatasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/uttanasana.pose.yaml +42 -0
- package/poses/yoga/ashtanga/utthita-parsvakonasana.pose.yaml +44 -0
- package/poses/yoga/ashtanga/utthita-trikonasana.pose.yaml +44 -0
- package/poses/yoga/ashtanga/virabhadrasana-a.pose.yaml +42 -0
- package/poses/yoga/ashtanga/virabhadrasana-b.pose.yaml +42 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { curveCatmullRomClosed, line } from 'd3-shape';
|
|
2
|
+
import { el, group } from './svg.js';
|
|
3
|
+
const LIMB_BONES = [
|
|
4
|
+
'upperArmL',
|
|
5
|
+
'forearmL',
|
|
6
|
+
'handL',
|
|
7
|
+
'thighL',
|
|
8
|
+
'shinL',
|
|
9
|
+
'footL',
|
|
10
|
+
'upperArmR',
|
|
11
|
+
'forearmR',
|
|
12
|
+
'handR',
|
|
13
|
+
'thighR',
|
|
14
|
+
'shinR',
|
|
15
|
+
'footR',
|
|
16
|
+
];
|
|
17
|
+
const TORSO_BONES = ['pelvis', 'spine', 'neck', 'clavicleL', 'clavicleR', 'hipL', 'hipR'];
|
|
18
|
+
const JOINT_LANDMARKS = [
|
|
19
|
+
'shoulderL',
|
|
20
|
+
'elbowL',
|
|
21
|
+
'wristL',
|
|
22
|
+
'shoulderR',
|
|
23
|
+
'elbowR',
|
|
24
|
+
'wristR',
|
|
25
|
+
'hipJointL',
|
|
26
|
+
'kneeL',
|
|
27
|
+
'ankleL',
|
|
28
|
+
'hipJointR',
|
|
29
|
+
'kneeR',
|
|
30
|
+
'ankleR',
|
|
31
|
+
'chest',
|
|
32
|
+
'hipCenter',
|
|
33
|
+
];
|
|
34
|
+
/** In a profile view the far-side limbs sit behind the body and read as lighter. */
|
|
35
|
+
const FAR_SIDE_VIEWS = ['side', 'three-quarter'];
|
|
36
|
+
const isFar = (bone, view) => FAR_SIDE_VIEWS.includes(view) && bone.side === 'right';
|
|
37
|
+
const boneLine = (bone, ctx) => {
|
|
38
|
+
const { proj, style } = ctx;
|
|
39
|
+
const view = ctx.skeleton.view;
|
|
40
|
+
const [x1, y1] = proj.p(bone.start);
|
|
41
|
+
const [x2, y2] = proj.p(bone.end);
|
|
42
|
+
return el('line', {
|
|
43
|
+
'data-bone': bone.id,
|
|
44
|
+
x1,
|
|
45
|
+
y1,
|
|
46
|
+
x2,
|
|
47
|
+
y2,
|
|
48
|
+
stroke: style.figure.stroke,
|
|
49
|
+
'stroke-width': style.figure.strokeWidth * proj.s,
|
|
50
|
+
'stroke-linecap': style.figure.lineCap,
|
|
51
|
+
opacity: isFar(bone, view) ? style.figure.farOpacity : undefined,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
const closedPath = line()
|
|
55
|
+
.x((p) => p[0])
|
|
56
|
+
.y((p) => p[1])
|
|
57
|
+
.curve(curveCatmullRomClosed);
|
|
58
|
+
/** A filled trunk between the shoulders and the hips, for the heavier styles. */
|
|
59
|
+
const torsoShape = ({ skeleton, proj, style }) => {
|
|
60
|
+
if (style.figure.torsoWidth <= 0)
|
|
61
|
+
return null;
|
|
62
|
+
const l = skeleton.landmarks;
|
|
63
|
+
const outline = [l.shoulderL, l.chest, l.shoulderR, l.hipJointR, l.hipCenter, l.hipJointL].map((p) => proj.p(p));
|
|
64
|
+
const d = closedPath(outline);
|
|
65
|
+
if (d === null)
|
|
66
|
+
return null;
|
|
67
|
+
return el('path', {
|
|
68
|
+
'data-part': 'torso',
|
|
69
|
+
d,
|
|
70
|
+
fill: style.figure.fill === 'none' ? style.figure.stroke : style.figure.fill,
|
|
71
|
+
stroke: style.figure.stroke,
|
|
72
|
+
'stroke-width': style.figure.torsoWidth * proj.s,
|
|
73
|
+
'stroke-linejoin': 'round',
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
const head = ({ skeleton, proj, style }) => {
|
|
77
|
+
if (style.head.shape === 'none')
|
|
78
|
+
return null;
|
|
79
|
+
const bone = skeleton.bones.head;
|
|
80
|
+
const [cx, cy] = proj.p(skeleton.landmarks.headCenter);
|
|
81
|
+
const rx = style.head.rx * proj.s * skeleton.scale;
|
|
82
|
+
const ry = (style.head.shape === 'circle' ? style.head.rx : style.head.ry) * proj.s * skeleton.scale;
|
|
83
|
+
// SVG rotates clockwise because y points down, so the sign flips against the world angle.
|
|
84
|
+
const rotation = 90 - bone.worldAngle;
|
|
85
|
+
return el('ellipse', {
|
|
86
|
+
'data-part': 'head',
|
|
87
|
+
cx,
|
|
88
|
+
cy,
|
|
89
|
+
rx,
|
|
90
|
+
ry,
|
|
91
|
+
transform: rotation === 0 ? undefined : `rotate(${rotation.toFixed(3)} ${cx.toFixed(3)} ${cy.toFixed(3)})`,
|
|
92
|
+
fill: style.head.fill,
|
|
93
|
+
stroke: style.head.stroke,
|
|
94
|
+
'stroke-width': style.head.strokeWidth * proj.s,
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
const joints = ({ skeleton, proj, style }) => {
|
|
98
|
+
if (style.figure.joints !== 'dots')
|
|
99
|
+
return null;
|
|
100
|
+
return group({ 'data-part': 'joints' }, JOINT_LANDMARKS.map((id) => {
|
|
101
|
+
const [cx, cy] = proj.p(skeleton.landmarks[id]);
|
|
102
|
+
return el('circle', {
|
|
103
|
+
'data-joint': id,
|
|
104
|
+
cx,
|
|
105
|
+
cy,
|
|
106
|
+
r: style.figure.jointRadius * proj.s * skeleton.scale,
|
|
107
|
+
fill: style.figure.stroke,
|
|
108
|
+
});
|
|
109
|
+
}));
|
|
110
|
+
};
|
|
111
|
+
const bonesOf = (skeleton, ids, side) => ids
|
|
112
|
+
.map((id) => skeleton.bones[id])
|
|
113
|
+
.filter((bone) => {
|
|
114
|
+
if (side === 'all')
|
|
115
|
+
return true;
|
|
116
|
+
const far = isFar(bone, skeleton.view);
|
|
117
|
+
return side === 'far' ? far : !far;
|
|
118
|
+
});
|
|
119
|
+
/**
|
|
120
|
+
* Draw the figure back-to-front: far limbs, trunk, head, near limbs. That single
|
|
121
|
+
* ordering is what makes a profile pose read as a body rather than a tangle.
|
|
122
|
+
*/
|
|
123
|
+
export const renderFigure = (ctx) => {
|
|
124
|
+
const { skeleton } = ctx;
|
|
125
|
+
const draw = (bones) => bones.map((b) => boneLine(b, ctx));
|
|
126
|
+
const optional = (node) => (node === null ? [] : [node]);
|
|
127
|
+
return group({ 'data-layer': 'figure' }, [
|
|
128
|
+
group({ 'data-layer': 'limbs-far' }, draw(bonesOf(skeleton, LIMB_BONES, 'far'))),
|
|
129
|
+
group({ 'data-layer': 'torso' }, [
|
|
130
|
+
...optional(torsoShape(ctx)),
|
|
131
|
+
...draw(bonesOf(skeleton, TORSO_BONES, 'all')),
|
|
132
|
+
]),
|
|
133
|
+
...optional(head(ctx)),
|
|
134
|
+
group({ 'data-layer': 'limbs-near' }, draw(bonesOf(skeleton, LIMB_BONES, 'near'))),
|
|
135
|
+
...optional(joints(ctx)),
|
|
136
|
+
]);
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=figure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"figure.js","sourceRoot":"","sources":["../../src/render/figure.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/render/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Bounds } from '../core/types.js';
|
|
2
|
+
import type { Vec2 } from '../core/vec2.js';
|
|
3
|
+
/**
|
|
4
|
+
* Maps math coordinates (y up, origin at the figure's feet) into SVG user units
|
|
5
|
+
* (y down, origin top-left). This is the only place the y-axis flips.
|
|
6
|
+
*/
|
|
7
|
+
export interface Projection {
|
|
8
|
+
/** Project a point. */
|
|
9
|
+
readonly p: (v: Vec2) => [number, number];
|
|
10
|
+
/** SVG units per stature unit - use it to scale every stroke width and radius. */
|
|
11
|
+
readonly s: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const unionBounds: (a: Bounds, b: Bounds) => Bounds;
|
|
14
|
+
export declare const boundsOfPoints: (points: readonly Vec2[]) => Bounds;
|
|
15
|
+
export declare const padBounds: (b: Bounds, pad: number) => Bounds;
|
|
16
|
+
/** Fit `content` inside a width x height canvas, preserving aspect ratio and centring. */
|
|
17
|
+
export declare const fitProjection: (content: Bounds, width: number, height: number) => Projection;
|
|
18
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/render/project.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,uBAAuB;IACvB,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,kFAAkF;IAClF,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,eAAO,MAAM,WAAW,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,MAKjD,CAAC;AAEH,eAAO,MAAM,cAAc,GAAI,QAAQ,SAAS,IAAI,EAAE,KAAG,MAKvD,CAAC;AAEH,eAAO,MAAM,SAAS,GAAI,GAAG,MAAM,EAAE,KAAK,MAAM,KAAG,MAKjD,CAAC;AAEH,0FAA0F;AAC1F,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,EAAE,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAG,UAc9E,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const MIN_EXTENT = 1e-6;
|
|
2
|
+
export const unionBounds = (a, b) => ({
|
|
3
|
+
minX: Math.min(a.minX, b.minX),
|
|
4
|
+
minY: Math.min(a.minY, b.minY),
|
|
5
|
+
maxX: Math.max(a.maxX, b.maxX),
|
|
6
|
+
maxY: Math.max(a.maxY, b.maxY),
|
|
7
|
+
});
|
|
8
|
+
export const boundsOfPoints = (points) => ({
|
|
9
|
+
minX: Math.min(...points.map((p) => p[0])),
|
|
10
|
+
maxX: Math.max(...points.map((p) => p[0])),
|
|
11
|
+
minY: Math.min(...points.map((p) => p[1])),
|
|
12
|
+
maxY: Math.max(...points.map((p) => p[1])),
|
|
13
|
+
});
|
|
14
|
+
export const padBounds = (b, pad) => ({
|
|
15
|
+
minX: b.minX - pad,
|
|
16
|
+
minY: b.minY - pad,
|
|
17
|
+
maxX: b.maxX + pad,
|
|
18
|
+
maxY: b.maxY + pad,
|
|
19
|
+
});
|
|
20
|
+
/** Fit `content` inside a width x height canvas, preserving aspect ratio and centring. */
|
|
21
|
+
export const fitProjection = (content, width, height) => {
|
|
22
|
+
const bw = Math.max(content.maxX - content.minX, MIN_EXTENT);
|
|
23
|
+
const bh = Math.max(content.maxY - content.minY, MIN_EXTENT);
|
|
24
|
+
const s = Math.min(width / bw, height / bh);
|
|
25
|
+
const offsetX = (width - bw * s) / 2;
|
|
26
|
+
const offsetY = (height - bh * s) / 2;
|
|
27
|
+
return {
|
|
28
|
+
s,
|
|
29
|
+
p: (v) => [
|
|
30
|
+
offsetX + (v[0] - content.minX) * s,
|
|
31
|
+
height - offsetY - (v[1] - content.minY) * s,
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/render/project.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,CAAC;IAC5D,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC9B,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC9B,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IAC9B,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAuB,EAAU,EAAE,CAAC,CAAC;IAClE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC3C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,GAAW,EAAU,EAAE,CAAC,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,GAAG;IAClB,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,GAAG;CACnB,CAAC,CAAC;AAEH,0FAA0F;AAC1F,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,KAAa,EAAE,MAAc,EAAc,EAAE;IAC1F,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7D,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IAEtC,OAAO;QACL,CAAC;QACD,CAAC,EAAE,CAAC,CAAO,EAAoB,EAAE,CAAC;YAChC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;YACnC,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC;SAC7C;KACF,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Bounds, Skeleton } from '../core/types.js';
|
|
2
|
+
import { type Vec2 } from '../core/vec2.js';
|
|
3
|
+
import type { Anchor, Prop } from '../model/schema.js';
|
|
4
|
+
import type { RenderContext } from './context.js';
|
|
5
|
+
import { type SvgNode } from './svg.js';
|
|
6
|
+
export declare const resolveAnchor: (anchor: Anchor, skeleton: Skeleton) => Vec2;
|
|
7
|
+
export declare const propsBounds: (props: readonly Prop[], skeleton: Skeleton) => Bounds | null;
|
|
8
|
+
export declare const renderProps: (ctx: RenderContext, props: readonly Prop[]) => SvgNode | null;
|
|
9
|
+
//# sourceMappingURL=props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/render/props.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAc,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAA6C,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAExD,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,UAAU,QAAQ,KAAG,IACe,CAAC;AA+FnF,eAAO,MAAM,WAAW,GAAI,OAAO,SAAS,IAAI,EAAE,EAAE,UAAU,QAAQ,KAAG,MAAM,GAAG,IAGjF,CAAC;AAkFF,eAAO,MAAM,WAAW,GAAI,KAAK,aAAa,EAAE,OAAO,SAAS,IAAI,EAAE,KAAG,OAAO,GAAG,IACiB,CAAC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { curveBasis, line } from 'd3-shape';
|
|
2
|
+
import { path } from 'd3-path';
|
|
3
|
+
import { add, fromPolar, rotate, scale as scaleVec } from '../core/vec2.js';
|
|
4
|
+
import { boundsOfPoints } from './project.js';
|
|
5
|
+
import { el, group, num } from './svg.js';
|
|
6
|
+
export const resolveAnchor = (anchor, skeleton) => typeof anchor === 'string' ? skeleton.landmarks[anchor] : [anchor[0], anchor[1]];
|
|
7
|
+
const centreX = (skeleton) => (skeleton.bounds.minX + skeleton.bounds.maxX) / 2;
|
|
8
|
+
const centroid = (ids, skeleton) => {
|
|
9
|
+
if (ids.length === 0)
|
|
10
|
+
return [centreX(skeleton), skeleton.bounds.minY];
|
|
11
|
+
const pts = ids.map((id) => skeleton.landmarks[id]);
|
|
12
|
+
return [
|
|
13
|
+
pts.reduce((sum, p) => sum + p[0], 0) / pts.length,
|
|
14
|
+
pts.reduce((sum, p) => sum + p[1], 0) / pts.length,
|
|
15
|
+
];
|
|
16
|
+
};
|
|
17
|
+
const smooth = line()
|
|
18
|
+
.x((p) => p[0])
|
|
19
|
+
.y((p) => p[1])
|
|
20
|
+
.curve(curveBasis);
|
|
21
|
+
const WAVE_STEPS = 48;
|
|
22
|
+
const BOARD_WIDTH_RATIO = 0.19;
|
|
23
|
+
const wavePoints = (prop, cx) => {
|
|
24
|
+
const dir = prop.facing === 'right' ? 1 : -1;
|
|
25
|
+
return Array.from({ length: WAVE_STEPS + 1 }, (_, i) => {
|
|
26
|
+
const t = i / WAVE_STEPS;
|
|
27
|
+
const px = cx + (t - 0.5) * prop.length;
|
|
28
|
+
// A breaking wave: a swell that steepens into a crest on the facing side.
|
|
29
|
+
const swell = Math.sin(t * Math.PI * 2 - Math.PI / 2);
|
|
30
|
+
const steepen = prop.breaking ? Math.pow(t, 1.6) : 1;
|
|
31
|
+
return [px * 1, prop.y + prop.amplitude * swell * steepen * dir * dir];
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const boardOutline = (centre, length, rotationDeg) => {
|
|
35
|
+
const half = length / 2;
|
|
36
|
+
const w = length * BOARD_WIDTH_RATIO;
|
|
37
|
+
const local = [
|
|
38
|
+
[half, 0],
|
|
39
|
+
[half * 0.45, w / 2],
|
|
40
|
+
[-half * 0.55, w / 2],
|
|
41
|
+
[-half, w * 0.16],
|
|
42
|
+
[-half, -w * 0.16],
|
|
43
|
+
[-half * 0.55, -w / 2],
|
|
44
|
+
[half * 0.45, -w / 2],
|
|
45
|
+
];
|
|
46
|
+
return local.map((p) => add(centre, rotate(p, rotationDeg)));
|
|
47
|
+
};
|
|
48
|
+
const polygon = (points, proj) => {
|
|
49
|
+
const p = path();
|
|
50
|
+
points.forEach((pt, i) => {
|
|
51
|
+
const [px, py] = proj.p(pt);
|
|
52
|
+
if (i === 0)
|
|
53
|
+
p.moveTo(num(px), num(py));
|
|
54
|
+
else
|
|
55
|
+
p.lineTo(num(px), num(py));
|
|
56
|
+
});
|
|
57
|
+
p.closePath();
|
|
58
|
+
return p.toString();
|
|
59
|
+
};
|
|
60
|
+
const propPoints = (prop, skeleton) => {
|
|
61
|
+
const cx = centreX(skeleton);
|
|
62
|
+
switch (prop.type) {
|
|
63
|
+
case 'ground':
|
|
64
|
+
return [
|
|
65
|
+
[cx - prop.width / 2, prop.y],
|
|
66
|
+
[cx + prop.width / 2, prop.y],
|
|
67
|
+
];
|
|
68
|
+
case 'mat':
|
|
69
|
+
return [
|
|
70
|
+
[cx - prop.width / 2, prop.y - prop.thickness],
|
|
71
|
+
[cx + prop.width / 2, prop.y + prop.thickness],
|
|
72
|
+
];
|
|
73
|
+
case 'block': {
|
|
74
|
+
const at = resolveAnchor(prop.at, skeleton);
|
|
75
|
+
return [
|
|
76
|
+
[at[0] - prop.width, at[1] - prop.height],
|
|
77
|
+
[at[0] + prop.width, at[1] + prop.height],
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
case 'strap':
|
|
81
|
+
return [resolveAnchor(prop.from, skeleton), resolveAnchor(prop.to, skeleton)];
|
|
82
|
+
case 'wall':
|
|
83
|
+
return [
|
|
84
|
+
[prop.x, skeleton.bounds.minY],
|
|
85
|
+
[prop.x, skeleton.bounds.maxY],
|
|
86
|
+
];
|
|
87
|
+
case 'surfboard': {
|
|
88
|
+
const centre = prop.at ?? add(centroid(prop.under, skeleton), prop.offset);
|
|
89
|
+
return boardOutline(centre, prop.length, prop.rotation);
|
|
90
|
+
}
|
|
91
|
+
case 'wave':
|
|
92
|
+
return wavePoints(prop, cx);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
export const propsBounds = (props, skeleton) => {
|
|
96
|
+
const pts = props.flatMap((prop) => propPoints(prop, skeleton));
|
|
97
|
+
return pts.length === 0 ? null : boundsOfPoints(pts);
|
|
98
|
+
};
|
|
99
|
+
const renderProp = (prop, ctx) => {
|
|
100
|
+
const { skeleton, proj, style } = ctx;
|
|
101
|
+
const cx = centreX(skeleton);
|
|
102
|
+
const attrs = { stroke: style.props.stroke, 'stroke-width': style.props.strokeWidth * proj.s };
|
|
103
|
+
switch (prop.type) {
|
|
104
|
+
case 'ground': {
|
|
105
|
+
const [x1, y1] = proj.p([cx - prop.width / 2, prop.y]);
|
|
106
|
+
const [x2, y2] = proj.p([cx + prop.width / 2, prop.y]);
|
|
107
|
+
return el('line', { 'data-prop': 'ground', x1, y1, x2, y2, ...attrs, 'stroke-linecap': 'round' });
|
|
108
|
+
}
|
|
109
|
+
case 'mat': {
|
|
110
|
+
const [x1, y1] = proj.p([cx - prop.width / 2, prop.y + prop.thickness]);
|
|
111
|
+
const [x2] = proj.p([cx + prop.width / 2, prop.y]);
|
|
112
|
+
return el('rect', {
|
|
113
|
+
'data-prop': 'mat',
|
|
114
|
+
x: x1,
|
|
115
|
+
y: y1,
|
|
116
|
+
width: x2 - x1,
|
|
117
|
+
height: prop.thickness * 2 * proj.s,
|
|
118
|
+
rx: prop.thickness * proj.s,
|
|
119
|
+
fill: style.props.fill,
|
|
120
|
+
...attrs,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
case 'block': {
|
|
124
|
+
const at = resolveAnchor(prop.at, skeleton);
|
|
125
|
+
const local = [
|
|
126
|
+
[-prop.width / 2, -prop.height / 2],
|
|
127
|
+
[prop.width / 2, -prop.height / 2],
|
|
128
|
+
[prop.width / 2, prop.height / 2],
|
|
129
|
+
[-prop.width / 2, prop.height / 2],
|
|
130
|
+
];
|
|
131
|
+
const corners = local.map((p) => add(at, rotate(p, prop.rotation)));
|
|
132
|
+
return el('path', { 'data-prop': 'block', d: polygon(corners, proj), fill: style.props.fill, ...attrs });
|
|
133
|
+
}
|
|
134
|
+
case 'strap': {
|
|
135
|
+
const a = resolveAnchor(prop.from, skeleton);
|
|
136
|
+
const b = resolveAnchor(prop.to, skeleton);
|
|
137
|
+
const mid = add(scaleVec(add(a, b), 0.5), [0, -Math.abs(prop.sag)]);
|
|
138
|
+
const [ax, ay] = proj.p(a);
|
|
139
|
+
const [mx, my] = proj.p(mid);
|
|
140
|
+
const [bx, by] = proj.p(b);
|
|
141
|
+
const p = path();
|
|
142
|
+
p.moveTo(num(ax), num(ay));
|
|
143
|
+
p.quadraticCurveTo(num(mx), num(my), num(bx), num(by));
|
|
144
|
+
return el('path', { 'data-prop': 'strap', d: p.toString(), fill: 'none', ...attrs });
|
|
145
|
+
}
|
|
146
|
+
case 'wall': {
|
|
147
|
+
const [x1, y1] = proj.p([prop.x, skeleton.bounds.minY]);
|
|
148
|
+
const [x2, y2] = proj.p([prop.x, skeleton.bounds.maxY]);
|
|
149
|
+
return el('line', { 'data-prop': 'wall', x1, y1, x2, y2, ...attrs });
|
|
150
|
+
}
|
|
151
|
+
case 'surfboard': {
|
|
152
|
+
const centre = prop.at ?? add(centroid(prop.under, skeleton), prop.offset);
|
|
153
|
+
const outline = boardOutline(centre, prop.length, prop.rotation);
|
|
154
|
+
const stringerEnd = add(centre, fromPolar(prop.rotation, prop.length / 2));
|
|
155
|
+
const stringerStart = add(centre, fromPolar(prop.rotation + 180, prop.length / 2));
|
|
156
|
+
const [sx1, sy1] = proj.p(stringerStart);
|
|
157
|
+
const [sx2, sy2] = proj.p(stringerEnd);
|
|
158
|
+
return group({ 'data-prop': 'surfboard' }, [
|
|
159
|
+
el('path', { d: polygon(outline, proj), fill: style.props.fill, ...attrs, 'stroke-linejoin': 'round' }),
|
|
160
|
+
el('line', { 'data-part': 'stringer', x1: sx1, y1: sy1, x2: sx2, y2: sy2, ...attrs, opacity: 0.5 }),
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
case 'wave': {
|
|
164
|
+
const pts = wavePoints(prop, cx).map((p) => proj.p(p));
|
|
165
|
+
const d = smooth(pts);
|
|
166
|
+
return el('path', {
|
|
167
|
+
'data-prop': 'wave',
|
|
168
|
+
d: d ?? '',
|
|
169
|
+
fill: 'none',
|
|
170
|
+
...attrs,
|
|
171
|
+
'stroke-width': style.props.strokeWidth * 1.5 * proj.s,
|
|
172
|
+
'stroke-linecap': 'round',
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
export const renderProps = (ctx, props) => props.length === 0 ? null : group({ 'data-layer': 'props' }, props.map((p) => renderProp(p, ctx)));
|
|
178
|
+
//# sourceMappingURL=props.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"props.js","sourceRoot":"","sources":["../../src/render/props.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface PngOptions {
|
|
2
|
+
/** Output width in pixels; height follows the SVG aspect ratio. */
|
|
3
|
+
readonly width?: number;
|
|
4
|
+
/** Uniform scale factor, used when no width is given. */
|
|
5
|
+
readonly scale?: number;
|
|
6
|
+
readonly background?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Rasterise with resvg: a pure-Rust SVG renderer with no system libraries and
|
|
10
|
+
* no browser, so a PNG built on a laptop is byte-identical to one built in CI.
|
|
11
|
+
*/
|
|
12
|
+
export declare const renderPng: (svg: string, options?: PngOptions) => Buffer;
|
|
13
|
+
/**
|
|
14
|
+
* Shrink the SVG without losing the `data-*` hooks: those attributes are the
|
|
15
|
+
* contract that lets another program (or a model) find a bone, a muscle or an
|
|
16
|
+
* annotation in the output.
|
|
17
|
+
*/
|
|
18
|
+
export declare const optimizeSvg: (svg: string) => string;
|
|
19
|
+
//# sourceMappingURL=raster.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster.d.ts","sourceRoot":"","sources":["../../src/render/raster.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,EAAE,UAAS,UAAe,KAAG,MAajE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,MAgBjC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Resvg } from '@resvg/resvg-js';
|
|
2
|
+
import { optimize } from 'svgo';
|
|
3
|
+
/**
|
|
4
|
+
* Rasterise with resvg: a pure-Rust SVG renderer with no system libraries and
|
|
5
|
+
* no browser, so a PNG built on a laptop is byte-identical to one built in CI.
|
|
6
|
+
*/
|
|
7
|
+
export const renderPng = (svg, options = {}) => {
|
|
8
|
+
const fitTo = options.width === undefined
|
|
9
|
+
? { mode: 'zoom', value: options.scale ?? 1 }
|
|
10
|
+
: { mode: 'width', value: options.width };
|
|
11
|
+
const resvg = new Resvg(svg, {
|
|
12
|
+
fitTo,
|
|
13
|
+
...(options.background === undefined ? {} : { background: options.background }),
|
|
14
|
+
font: { loadSystemFonts: true },
|
|
15
|
+
});
|
|
16
|
+
return Buffer.from(resvg.render().asPng());
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Shrink the SVG without losing the `data-*` hooks: those attributes are the
|
|
20
|
+
* contract that lets another program (or a model) find a bone, a muscle or an
|
|
21
|
+
* annotation in the output.
|
|
22
|
+
*/
|
|
23
|
+
export const optimizeSvg = (svg) => optimize(svg, {
|
|
24
|
+
multipass: true,
|
|
25
|
+
js2svg: { indent: 0, pretty: false },
|
|
26
|
+
plugins: [
|
|
27
|
+
{
|
|
28
|
+
name: 'preset-default',
|
|
29
|
+
params: {
|
|
30
|
+
overrides: {
|
|
31
|
+
removeViewBox: false,
|
|
32
|
+
cleanupIds: false,
|
|
33
|
+
removeUnknownsAndDefaults: { keepDataAttrs: true },
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
}).data;
|
|
39
|
+
//# sourceMappingURL=raster.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster.js","sourceRoot":"","sources":["../../src/render/raster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAUhC;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,UAAsB,EAAE,EAAU,EAAE;IACzE,MAAM,KAAK,GACT,OAAO,CAAC,KAAK,KAAK,SAAS;QACzB,CAAC,CAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC,EAAY;QACxD,CAAC,CAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAY,CAAC;IAEzD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE;QAC3B,KAAK;QACL,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;QAC/E,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE;KAChC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;AAC7C,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAU,EAAE,CACjD,QAAQ,CAAC,GAAG,EAAE;IACZ,SAAS,EAAE,IAAI;IACf,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE;IACpC,OAAO,EAAE;QACP;YACE,IAAI,EAAE,gBAAgB;YACtB,MAAM,EAAE;gBACN,SAAS,EAAE;oBACT,aAAa,EAAE,KAAK;oBACpB,UAAU,EAAE,KAAK;oBACjB,yBAAyB,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE;iBACnD;aACF;SACF;KACF;CACF,CAAC,CAAC,IAAI,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Bounds, Rig, Skeleton } from '../core/types.js';
|
|
2
|
+
import { type PoseSpec } from '../model/index.js';
|
|
3
|
+
import { type Style, type StyleId, type StyleOverride } from './styles.js';
|
|
4
|
+
import { type SvgNode } from './svg.js';
|
|
5
|
+
export interface RenderOptions {
|
|
6
|
+
readonly width?: number;
|
|
7
|
+
readonly height?: number;
|
|
8
|
+
readonly style?: StyleId;
|
|
9
|
+
readonly styleOverride?: StyleOverride;
|
|
10
|
+
readonly rig?: Rig;
|
|
11
|
+
/** Draw the pose name (and Sanskrit name) above the figure. */
|
|
12
|
+
readonly title?: boolean;
|
|
13
|
+
/** Draw the teaching cues below the figure. */
|
|
14
|
+
readonly caption?: boolean;
|
|
15
|
+
readonly background?: string;
|
|
16
|
+
/** Force the muscle layer on or off, overriding the style. */
|
|
17
|
+
readonly muscles?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const DEFAULT_WIDTH = 600;
|
|
20
|
+
export declare const DEFAULT_HEIGHT = 800;
|
|
21
|
+
/** Everything that must be visible: the figure, its props and its annotations. */
|
|
22
|
+
export declare const contentBounds: (pose: PoseSpec, skeleton: Skeleton, style: Style) => Bounds;
|
|
23
|
+
export declare const renderSvgNode: (pose: PoseSpec, options?: RenderOptions) => SvgNode;
|
|
24
|
+
/** Render a pose to a standalone, deterministic SVG document. */
|
|
25
|
+
export declare const renderSvg: (pose: PoseSpec, options?: RenderOptions) => string;
|
|
26
|
+
//# sourceMappingURL=scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../src/render/scene.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAiB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAOjE,OAAO,EAAgB,KAAK,KAAK,EAAE,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAgC,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,aAAa,MAAM,CAAC;AACjC,eAAO,MAAM,cAAc,MAAM,CAAC;AAalC,kFAAkF;AAClF,eAAO,MAAM,aAAa,GAAI,MAAM,QAAQ,EAAE,UAAU,QAAQ,EAAE,OAAO,KAAK,KAAG,MAWhF,CAAC;AAkHF,eAAO,MAAM,aAAa,GAAI,MAAM,QAAQ,EAAE,UAAS,aAAkB,KAAG,OAwC3E,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,SAAS,GAAI,MAAM,QAAQ,EAAE,UAAS,aAAkB,KAAG,MAC/B,CAAC"}
|