@motionscript/molecule 0.0.0-stage → 0.1.0-alpha.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/LICENSE +201 -0
  3. package/dist/browser/index.js +4 -0
  4. package/dist/browser/index.js.map +7 -0
  5. package/dist/browser/manifest.json +11 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +3 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/nodes.d.ts +18 -0
  11. package/dist/nodes.d.ts.map +1 -0
  12. package/dist/nodes.js +18 -0
  13. package/dist/nodes.js.map +1 -0
  14. package/dist/protein/chemistry.d.ts +52 -0
  15. package/dist/protein/chemistry.d.ts.map +1 -0
  16. package/dist/protein/chemistry.js +208 -0
  17. package/dist/protein/chemistry.js.map +1 -0
  18. package/dist/protein/index.d.ts +35 -0
  19. package/dist/protein/index.d.ts.map +1 -0
  20. package/dist/protein/index.js +35 -0
  21. package/dist/protein/index.js.map +1 -0
  22. package/dist/protein/parse.d.ts +32 -0
  23. package/dist/protein/parse.d.ts.map +1 -0
  24. package/dist/protein/parse.js +387 -0
  25. package/dist/protein/parse.js.map +1 -0
  26. package/dist/protein/protein.d.ts +265 -0
  27. package/dist/protein/protein.d.ts.map +1 -0
  28. package/dist/protein/protein.js +645 -0
  29. package/dist/protein/protein.js.map +1 -0
  30. package/dist/protein/ribbon.d.ts +83 -0
  31. package/dist/protein/ribbon.d.ts.map +1 -0
  32. package/dist/protein/ribbon.js +468 -0
  33. package/dist/protein/ribbon.js.map +1 -0
  34. package/dist/protein/shared.d.ts +221 -0
  35. package/dist/protein/shared.d.ts.map +1 -0
  36. package/dist/protein/shared.js +478 -0
  37. package/dist/protein/shared.js.map +1 -0
  38. package/dist/protein/structure.d.ts +184 -0
  39. package/dist/protein/structure.d.ts.map +1 -0
  40. package/dist/protein/structure.js +324 -0
  41. package/dist/protein/structure.js.map +1 -0
  42. package/package.json +64 -3
  43. package/registry.json +22 -0
  44. package/src/index.ts +2 -0
  45. package/src/nodes.ts +18 -0
  46. package/src/protein/chemistry.ts +223 -0
  47. package/src/protein/index.ts +34 -0
  48. package/src/protein/parse.ts +427 -0
  49. package/src/protein/protein.ts +897 -0
  50. package/src/protein/ribbon.ts +658 -0
  51. package/src/protein/shared.ts +622 -0
  52. package/src/protein/structure.ts +491 -0
  53. package/README.md +0 -4
@@ -0,0 +1,221 @@
1
+ /**
2
+ * What the {@link Protein} node turns a parsed molecule into: which atoms are
3
+ * showing, what colour each one takes, and how a bond becomes a cylinder.
4
+ *
5
+ * Everything here is **derived per structure**, not per frame. The node caches
6
+ * what these return against the inputs that produced them (see
7
+ * `Protein.instances`), because the camera moves every frame and none of this
8
+ * changes when it does — and a mid-sized entry is tens of thousands of atoms, so
9
+ * rebuilding the arrays sixty times a second to spin the view would be the
10
+ * difference between a smooth orbit and a slideshow.
11
+ */
12
+ import type { Color, Transform3D, Vector3 } from "@motionscript/core";
13
+ import type { ProteinAtom, ProteinChain, ProteinStructure, SecondaryStructure } from "./structure.js";
14
+ /**
15
+ * How the molecule is drawn.
16
+ *
17
+ * The four that answer genuinely different questions, which is why there are
18
+ * four rather than a dozen:
19
+ *
20
+ * - `spacefill` — every atom at its van der Waals radius. What the molecule's
21
+ * *surface* is: the shape it presents to everything around it.
22
+ * - `ballAndStick` — atoms shrunk, bonds drawn. What the molecule's *chemistry*
23
+ * is, and the only one where an individual atom can be picked out.
24
+ * - `backbone` — a thin even tube through the α-carbons. Where the chain *goes*,
25
+ * with nothing else in the way.
26
+ * - `ribbon` — the same curve, swelling along helices and strands and coloured
27
+ * by them. What the protein is *folded into*, which is what a figure in a
28
+ * paper is nearly always about.
29
+ */
30
+ export declare const PROTEIN_REPRESENTATIONS: readonly ["ribbon", "backbone", "ballAndStick", "spacefill"];
31
+ export type ProteinRepresentation = (typeof PROTEIN_REPRESENTATIONS)[number];
32
+ /**
33
+ * What decides an atom's colour.
34
+ *
35
+ * Each one answers a question the picture might be asking, and the default
36
+ * differs by representation for exactly that reason: a space-filling model with
37
+ * no element colouring is a featureless blob, while a ribbon coloured by element
38
+ * is a single shade of grey.
39
+ */
40
+ export declare const PROTEIN_COLOR_SCHEMES: readonly ["secondary", "element", "chain", "residue", "uniform"];
41
+ export type ProteinColorScheme = (typeof PROTEIN_COLOR_SCHEMES)[number];
42
+ /**
43
+ * The per-chain palette.
44
+ *
45
+ * Eight, spread around the wheel rather than sampled from a gradient: chains are
46
+ * a *nominal* scale — chain B is not between A and C in any sense — so the
47
+ * colours have to be distinguishable rather than ordered. A ninth chain wraps,
48
+ * which is the honest failure for a complex that large; the alternative is
49
+ * colours nobody can tell apart.
50
+ *
51
+ * Eight is therefore the *palette's* length rather than a constant anything
52
+ * downstream may assume: an author who edits these edits eight entries, and the
53
+ * wrap is modulo whatever the list holds.
54
+ */
55
+ export declare const CHAIN_COLORS: readonly ["#4f9dff", "#ff8a3d", "#4ddb9a", "#e05fd0", "#ffd166", "#8b7bff", "#ff6b6b", "#3fd0d6"];
56
+ /**
57
+ * Helix, sheet and coil.
58
+ *
59
+ * The conventional assignment — warm for helices, cool for strands, pale for
60
+ * everything else — which is old enough to be read without a legend.
61
+ */
62
+ export declare const SECONDARY_COLORS: Readonly<Record<SecondaryStructure, string>>;
63
+ /**
64
+ * Every colour a scheme reaches for that is **not** the node's own `color`.
65
+ *
66
+ * Three schemes paint from more than one colour — the fold's three states, the
67
+ * eight chain hues, the two ends of the N→C ramp — and until now all three were
68
+ * frozen in this file. They are conventional rather than arbitrary, which is why
69
+ * the defaults below are exactly what they were, but "conventional" is a good
70
+ * reason for a *default* and a poor one for a rule: a figure has a palette, and
71
+ * a molecule in it that refuses to join in is the one element on the slide
72
+ * somebody has to work around.
73
+ *
74
+ * A **read** shape rather than a prop. The node holds these as thirteen separate
75
+ * props and gathers them into one of these to hand to the colourers below, and
76
+ * that split is deliberate rather than clumsy: a prop is a whole value, so a
77
+ * single `palette` prop would make every `to` that reddens the helices a
78
+ * statement about all thirteen colours, snapping the twelve the author never
79
+ * touched back to whatever the command happened to carry. Thirteen props carry
80
+ * over one at a time and tween one at a time, which is what every other colour
81
+ * in the app does.
82
+ *
83
+ * Nothing here reaches the `element` scheme, deliberately. CPK is not a palette
84
+ * anybody chose — oxygen is red because oxygen is red — so it stays in
85
+ * `chemistry.ts` with the van der Waals radii, which are facts about the same
86
+ * atoms and equally not a matter of taste.
87
+ */
88
+ export interface ProteinPalette {
89
+ /** Secondary structure, when the scheme is `secondary`. */
90
+ helix: string;
91
+ sheet: string;
92
+ coil: string;
93
+ /**
94
+ * One hue per chain, when the scheme is `chain`, wrapping past the end.
95
+ *
96
+ * A list rather than a fixed eight so the wrap follows what is actually here:
97
+ * an author who deletes down to three colours gets a three-colour cycle, which
98
+ * is a legible answer, where a wrap modulo a constant would index past it.
99
+ */
100
+ chains: readonly string[];
101
+ /** The two ends of the N→C ramp, when the scheme is `residue`. */
102
+ residueStart: string;
103
+ residueEnd: string;
104
+ }
105
+ /**
106
+ * The palette every scheme has always drawn — the conventional assignment, now
107
+ * stated as a value the author can take over rather than as a constant.
108
+ *
109
+ * The two spectrum ends are **computed** from the hues the ramp used to be
110
+ * written as, rather than typed out as hex, so the default sweep is the same
111
+ * blue-through-green-to-red it has always been by construction instead of by
112
+ * somebody having done the arithmetic correctly once.
113
+ */
114
+ export declare const DEFAULT_PROTEIN_PALETTE: ProteinPalette;
115
+ /**
116
+ * How many chain colours the palette offers, and therefore what the chain cycle
117
+ * wraps at.
118
+ *
119
+ * Eight, because that is how many hues can be told apart at a glance — the
120
+ * reason {@link CHAIN_COLORS} has eight — and it is named here because three
121
+ * places have to agree on it: the schema declares this many rows, the props
122
+ * mapper reads this many, and the node holds this many.
123
+ */
124
+ export declare const CHAIN_COLOR_COUNT: 8;
125
+ /**
126
+ * The appearance-bag field names the palette is edited as, in panel order.
127
+ *
128
+ * Three places have to agree on this list and none of them can derive it from
129
+ * the others: the schema declares a row per name, `proteinMotionProps` copies a
130
+ * row per name onto the props, and the node declares a `@property` per name.
131
+ * The third is the one that cannot be written as a loop — a decorator is a
132
+ * declaration — so what this buys is the first two staying in step with it, and
133
+ * a test pins the third against it.
134
+ *
135
+ * `color` is deliberately not here. It is the node's own colour rather than part
136
+ * of a scheme's palette: it is what `uniform` paints and what every scheme falls
137
+ * back to, so it lives beside `representation` as a field of the molecule.
138
+ */
139
+ export declare const PROTEIN_PALETTE_FIELDS: readonly ["helixColor", "sheetColor", "coilColor", "residueStartColor", "residueEndColor", ...`chainColor${number}`[]];
140
+ /** The default each {@link PROTEIN_PALETTE_FIELDS} entry carries, by name. */
141
+ export declare const PROTEIN_PALETTE_DEFAULTS: Readonly<Record<string, string>>;
142
+ /**
143
+ * Tween: two `#rrggbb` strings, blended per channel.
144
+ *
145
+ * The palette entries are the one family of colours here that stay **strings**
146
+ * rather than going through `resolveColor3D` — an instance tint is handed a hex
147
+ * string — so they need a tween of their own rather than {@link lerpColor3D}.
148
+ *
149
+ * Blended in RGB, unlike the residue ramp {@link spectrum} sweeps: that one is a
150
+ * *spectrum*, where covering the wheel is the whole point, while this is one
151
+ * colour becoming another, where the short straight path is what "fading to red"
152
+ * means. Anything unparseable snaps, which is the only honest answer for a value
153
+ * with no channels to interpolate.
154
+ */
155
+ export declare function lerpHexColor(from: string, to: string, t: number): string;
156
+ /**
157
+ * The colour of every atom, in the order the structure holds them.
158
+ *
159
+ * One flat array rather than a function called per atom, because the instance
160
+ * builder walks the whole list and an array is what `Graphics3D.instances` takes
161
+ * anyway.
162
+ */
163
+ export declare function atomColors(structure: ProteinStructure, scheme: ProteinColorScheme, uniform: string, palette?: ProteinPalette): string[];
164
+ /**
165
+ * The colour of each point along one chain's backbone.
166
+ *
167
+ * Separate from {@link atomColors} because a trace point is a *residue* and an
168
+ * atom is not: the element scheme has nothing to say about a residue (every
169
+ * trace atom is a carbon, so the whole ribbon would be grey), so it falls back
170
+ * to the chain colouring — which is what somebody who picked "element" and then
171
+ * switched to a ribbon actually wants to see.
172
+ */
173
+ export declare function traceColors(structure: ProteinStructure, chain: ProteinChain, scheme: ProteinColorScheme, uniform: string, palette?: ProteinPalette): string[];
174
+ /** An atom's drawn radius in Ångströms, at a given scale of its true size. */
175
+ export declare function atomRadius(atom: ProteinAtom, scale: number): number;
176
+ /**
177
+ * The placement of a stick running from `from` to `to`.
178
+ *
179
+ * A cylinder geometry is built along **+Y**, centred on the origin and one unit
180
+ * tall, so placing one takes all three parts of a transform: move it to the
181
+ * midpoint, scale it to the bond's length, and turn +Y onto the bond's
182
+ * direction.
183
+ *
184
+ * The turn is a quaternion rather than an Euler triple because there is no
185
+ * ordering of three axis rotations that doesn't gimbal somewhere, and a molecule
186
+ * has bonds pointing every way there is — one of them would land exactly on the
187
+ * degenerate axis and the stick would spin to a wrong orientation.
188
+ */
189
+ export declare function stickPlacement(from: Vector3, to: Vector3, radius: number): Transform3D;
190
+ /** One stretch of a chain drawn as a single swept tube. */
191
+ export interface BackboneRun {
192
+ points: Vector3[];
193
+ color: string;
194
+ secondary: SecondaryStructure;
195
+ }
196
+ /**
197
+ * Splits a chain's trace into the runs a backbone is swept as.
198
+ *
199
+ * A run is a stretch that can be drawn as **one** `Geo.tube`, and what forces a
200
+ * break is anything the tube carries once for its whole length: its colour
201
+ * always, and — for a cartoon — its radius, since a helix that doesn't swell is
202
+ * not a helix anyone will recognise.
203
+ *
204
+ * Consecutive runs **overlap by one point**, which is what keeps the tubes
205
+ * meeting rather than leaving a gap at every transition: the shared point is the
206
+ * end of one sweep and the start of the next, so their ends sit in the same
207
+ * place.
208
+ *
209
+ * The trade this makes is worth stating. A tube is swept along a Catmull-Rom
210
+ * curve through its own points, so a long run comes out smooth and a two-point
211
+ * run comes out straight. Under the colourings a fold is usually drawn in —
212
+ * secondary structure, chain, one colour — runs are long and the curve is
213
+ * smooth. Under the residue spectrum every point is its own colour, so the
214
+ * chain becomes a faceted polyline with a gradient along it. That is the honest
215
+ * cost of colouring per residue without a mesh built vertex by vertex, and at
216
+ * the scale a whole fold is viewed at it reads as a curve anyway.
217
+ */
218
+ export declare function backboneRuns(chain: ProteinChain, colors: string[], splitBySecondary: boolean): BackboneRun[];
219
+ /** The colour a `Color` prop resolves to when a scheme wants a plain string. */
220
+ export declare function hexOf(value: Color): string;
221
+ //# sourceMappingURL=shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/protein/shared.ts"],"names":[],"mappings":"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"}