The base concept for a field: a scalar weight defined over space that other elements read to vary an effect from place to place.
Base class — has no declarative element of its own; subclasses inherit its members.
A field turns "where" into "how much." A spatial field gives every point in the
scene a weight based on its position — a radial fade, a linear gradient, coherent
noise — normally in the 0–1 range (a remap-curve can reshape or extend it), and
consumers use that weight to modulate what they do: a material fades its coverage,
a tonemap masks its shading, a constraint scales its effect, a color-source drives
a color-map.
By-id resource model. A field is a place-anywhere scene resource: give it an
id and consumers reference it with field="#id". One field can drive many
consumers at once, and animating the shared field updates all of them together.
A spatial field is also a scene-graph node, so its position, rotation, and scale
move where its weight lands; setting visualize draws its extents.
Member elements. The spatial fields shape weight by distance or noise:
sk-spherical-gradient-field, sk-linear-gradient-field,
sk-cube-gradient-field, sk-cylinder-gradient-field,
sk-capsule-gradient-field, sk-torus-gradient-field,
sk-spline-progress-gradient-field, sk-spline-distance-gradient-field,
sk-noise-spatial-field, sk-random-spatial-field, and
sk-voronoi-spatial-field. Related field
kinds share the same field="#id" model: the stroke fields
sk-cross-stroke-field, sk-dash-array-stroke-field, and
sk-progress-stroke-field weight along a stroke; sk-composite-field
blends several fields into one. Consumers include sk-field-constraint and
sk-color-source-field.
The example is a medley: four different field types each drive a different effect, laid out as labeled stations on a ground plane, so the one idea — a weight over space steering a consumer — is visible across the family. A stroke field ramps color along a stroke; a noise field drives a radial push that deforms a sphere's vertices; a spherical field masks a tonemap over a surface; and a linear field drives a color-source, painting the base color by position rather than by light.
Abstract base class — not instantiated directly. Construct one of its concrete subclasses; this class contributes the members below to them.
Inherited from: VisualizableSceneNode, SceneNode, SkenraAnimatable
— see those pages for inherited members.
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
remapCurveanimatable |
SampledCurve |
— | Optional curve that reshapes this field's raw [0, 1] output. | SpatialField |
visualize |
boolean |
false |
Whether the visualization is visible (wireframe splines + center marker). | VisualizableSceneNode |
interactiveControlsconfig-only |
boolean |
— | Whether to show interactive controls (draggable markers). Requires visualize. Default: false | VisualizableSceneNodeConfig |
visualizationMarkerSizeconfig-only |
number |
— | Size of visualization markers in pixels. Default: 20 | VisualizableSceneNodeConfig |
visualizationColorconfig-only |
string |
— | Color for visualization geometry and markers (CSS color string). Default: VISUALIZATION_HIGHLIGHT_COLOR ('#FF8C00'). | VisualizableSceneNodeConfig |
visualizationZeroWeightColorconfig-only |
string |
— | Color for zero-weight boundary geometry (outer radius, origin plane, etc.). Default: VISUALIZATION_ZERO_WEIGHT_COLOR ('#888888'). | VisualizableSceneNodeConfig |
visualizationSplineThicknessconfig-only |
number |
— | Spline stroke thickness in pixels. Default varies by subclass. | VisualizableSceneNodeConfig |
visualizationSplineOccludedOpacityconfig-only |
number |
— | Opacity of visualization splines when occluded. Default: 0.5 | VisualizableSceneNodeConfig |
visualizationMarkerOpacityconfig-only |
number |
— | Opacity of visualization markers. Default: 0.9 | VisualizableSceneNodeConfig |
idconfig-only |
string |
— | Unique identifier for the node, reflected to the host id attribute. |
SceneNodeConfig |
xanimatable |
number |
0 |
Gets the X position component. | SceneNode |
yanimatable |
number |
0 |
Gets the Y position component. | SceneNode |
zanimatable |
number |
0 |
Gets the Z position component. | SceneNode |
hanimatable |
number |
0 |
Gets the heading (Y-axis) rotation in radians. | SceneNode |
panimatable |
number |
0 |
Gets the pitch (X-axis) rotation in radians. | SceneNode |
banimatable |
number |
0 |
Gets the bank (Z-axis) rotation in radians. | SceneNode |
quaternionanimatable |
Quaternion |
— | Gets the rotation as a quaternion. | SceneNode |
sxanimatable |
number |
1 |
Gets the X-axis scale factor. | SceneNode |
syanimatable |
number |
1 |
Gets the Y-axis scale factor. | SceneNode |
szanimatable |
number |
1 |
Gets the Z-axis scale factor. | SceneNode |
sconfig-only |
number |
— | Uniform scale factor for all axes (overrides sx, sy, sz if provided) | SceneNodeConfig |
classconfig-only |
string |
— | Standard HTML class applied to the node host at construction |
SceneNodeConfig |
styleconfig-only |
string |
— | Standard inline style applied to the node host at construction |
SceneNodeConfig |
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
remapPhaseanimatable |
number |
0 |
Horizontal remap phase — an animatable scalar that translates a present | SpatialField |
enabled |
boolean |
true |
Whether this field is enabled. When disabled, evaluate() returns 0. |
SpatialField |
hRad |
number |
0 |
Gets the heading (Y-axis) rotation in radians. | SceneNode |
pRad |
number |
0 |
Gets the pitch (X-axis) rotation in radians. | SceneNode |
bRad |
number |
0 |
Gets the bank (Z-axis) rotation in radians. | SceneNode |
hDeg |
number |
0 |
Gets the heading (Y-axis) rotation in degrees. | SceneNode |
pDeg |
number |
0 |
Gets the pitch (X-axis) rotation in degrees. | SceneNode |
bDeg |
number |
0 |
Gets the bank (Z-axis) rotation in degrees. | SceneNode |
xBasebase value |
number |
— | Gets the base (non-animated) value of X position. | SceneNode |
yBasebase value |
number |
— | Gets the base (non-animated) value of Y position. | SceneNode |
zBasebase value |
number |
— | Gets the base (non-animated) value of Z position. | SceneNode |
hBasebase value |
number |
0 |
Gets the base (non-animated) value of heading (Y-axis rotation). | SceneNode |
pBasebase value |
number |
0 |
Gets the base (non-animated) value of pitch (X-axis rotation). | SceneNode |
bBasebase value |
number |
0 |
Gets the base (non-animated) value of bank (Z-axis rotation). | SceneNode |
quaternionBasebase value |
Quaternion |
— | Gets the base (non-animated) quaternion rotation. | SceneNode |
sxBasebase value |
number |
— | Gets the base (non-animated) value of X-axis scale. | SceneNode |
syBasebase value |
number |
— | Gets the base (non-animated) value of Y-axis scale. | SceneNode |
szBasebase value |
number |
— | Gets the base (non-animated) value of Z-axis scale. | SceneNode |
draggable |
boolean |
false |
Gets whether this node can be dragged. | SceneNode |
parentread-only |
SceneNode | null |
— | The parent node in the scene graph, or null at the root. |
SceneNode |
sceneread-only |
any |
— | Gets the Scene this node belongs to, if any. | SceneNode |
posread-only |
Point3D |
— | Gets the world-space position of this node. | SceneNode |
matrixread-only |
Float32Array<ArrayBufferLike> |
— | Gets the computed 4x4 transformation matrix. | SceneNode |
animationsread-only |
SkenraAnimation[] |
— | Public getter for the animations affecting this target. | SkenraAnimatable |
| Method | Description | Declared by |
|---|---|---|
addMaterialPaint(material: Material, paintTarget: PaintTarget, options?: any): Paint |
Applies a material to this node for a specific paint target. | SceneNode |
getPaints(): ReadonlyMap<PaintTarget, Paint> |
— | SceneNode |
getOwnPaints(): readonly Paint[] |
Gets only the paints directly applied to this node (not inherited). | SceneNode |
removePaint(paint: Paint): void |
Removes a paint from this node. | SceneNode |
getWorldPosition(): number[] |
Returns this node’s origin in world space. | SceneNode |
getWorldMatrix(): Float32Array<ArrayBufferLike> |
Returns this node’s world transform — its local transform composed with all ancestor transforms. | SceneNode |
setViewportPosition(camera: AbstractCamera, x: number, y: number, z: number = 0.5): boolean |
Sets the node's local translation so that it appears at the specified viewport position. | SceneNode |
getViewportPosition(camera?: AbstractCamera): [number, number, number] | null |
Returns the node's current world position projected to viewport CSS pixel coordinates. | SceneNode |
setNDCPosition(camera: AbstractCamera, ndcX: number, ndcY: number, ndcZ: number = 0.5): boolean |
Sets the node's local translation so that it appears at the specified NDC position in the viewport. | SceneNode |
getBoundsInSpace(targetSpaceMatrix: Float32Array): { minX: number; maxX: number; minY: number; maxY: number; minZ: number; maxZ: number; } | null |
Computes the axis-aligned bounding box (AABB) of this node and its descendants | SceneNode |
animate(firstArg: TypedKeyframe<this>[] | TypedPropertyIndexedKeyframes<this> | Record<string, any> | globalThis.Keyframe[] | globalThis.PropertyIndexedKeyframes | null, secondArg?: number | KeyframeAnimationOptions | globalThis.KeyframeAnimationOptions): SkenraAnimation & Animation |
Creates a new SkenraAnimation for this target per Web Animations API. | SkenraAnimatable |
removeAnimation(animation: SkenraAnimation): boolean |
Removes a specific animation from this object. | SkenraAnimatable |
constrain(type: K, config: ConstraintConfigMap[K]): ConstraintReturnMap[K] |
Creates a constraint on this Animatable using a fluent API. | SkenraAnimatable |
Serve these docs to run the live example.
WebGPU needs a secure context — open this page via grunt serve
rather than double-clicking the file. The Markup tab works from disk.
<!-- Four stations in a 2x2 layout on a ground plane (columns at x=-11/+11, rows
at z=-11 back / z=+11 front), each a different field type driving a different
effect, labeled by an overlay annotation. Palette: a cohesive teal→amber
ramp shared across stations, teal for the deformed sphere, on a
warm charcoal ground. -->
<sk-scene>
<sk-directional-light p="155deg" h="-30deg" intensity="1.0"></sk-directional-light>
<sk-ambient-light intensity="0.45"></sk-ambient-light>
<!-- Ground plane under the four stations. -->
<sk-plain-material id="ground-fill" base-color="#2b2825"></sk-plain-material>
<sk-plain-material id="ground-grid" base-color="#191612"></sk-plain-material>
<sk-plane y="-3" width="34" height="34" width-segments="8" height-segments="8">
<sk-surface-paint material="#ground-fill"></sk-surface-paint>
<sk-edge-paint material="#ground-grid"></sk-edge-paint>
</sk-plane>
<!-- BACK-LEFT — stroke field → gradient ALONG a stroke, via a COLOR-SOURCE.
Arc-length progress (0 at the start, 1 at the end) is the color-map
driver, so the ribbon runs teal→amber end to end. A width-profile swells
it in the middle and tapers it to points. `base-color-darken-factor="0"`
keeps the painted color at full brightness. -->
<sk-progress-stroke-field id="along" clamp="true"></sk-progress-stroke-field>
<sk-ramp-color-map id="ramp">
<sk-color-stop stop-offset="0" stop-color="#1f6f6a"></sk-color-stop>
<sk-color-stop stop-offset="1" stop-color="#e0a03a"></sk-color-stop>
</sk-ramp-color-map>
<sk-color-map-source id="along-src" intensity-field="#along" color-map="#ramp"></sk-color-map-source>
<sk-plain-material id="along-mat" base-color="white" base-color-source="#along-src"
base-color-darken-factor="0"></sk-plain-material>
<sk-spline x="-11" z="-11">
<sk-svg-spline-source path="M 0 0 C 1.5 -3 3 3 4.5 0" coordinate-space="x-z"
anchor="center" normalize-scale="6"></sk-svg-spline-source>
<sk-stroke-paint material="#along-mat" width="12" line-cap="round"
width-profile='{"basis":"catmullRom","points":[{"t":0,"width":0.12},{"t":0.5,"width":1},{"t":1,"width":0.12}]}'></sk-stroke-paint>
</sk-spline>
<sk-overlay-annotation x="-11" y="8" z="-11" anchor="bottom">
<div style="color:#e8ddc7; font:12px sans-serif; text-align:center;">stroke field<br/>→<br/>gradient along a stroke</div>
</sk-overlay-annotation>
<!-- BACK-RIGHT — noise field → radial PUSH on a SPHERE. The constraint
pushes every one of the sphere's own vertices outward from its center,
scaled by the coherent noise at each vertex, so the surface swells into
smooth, organic lumps instead of staying round. -->
<sk-noise-spatial-field id="scatter" frequency="0.9" octaves="3" seed="7"></sk-noise-spatial-field>
<sk-plain-material id="lumps-mat" base-color="#1f6f6a"></sk-plain-material>
<sk-scene-node id="lumps-center" x="11" z="-11"></sk-scene-node>
<sk-sphere x="11" z="-11" radius="2.8" segments="5">
<sk-surface-paint material="#lumps-mat"></sk-surface-paint>
<sk-radial-push-point-constraint origin="#lumps-center" field="#scatter"
distance="2"></sk-radial-push-point-constraint>
</sk-sphere>
<sk-overlay-annotation x="11" y="8" z="-11" anchor="bottom">
<div style="color:#e8ddc7; font:12px sans-serif; text-align:center;">noise field<br/>→<br/>radial push</div>
</sk-overlay-annotation>
<!-- FRONT-LEFT — spherical field → tonemap MASK. The field (shown by its
`visualize` markers, draggable via `interactive-controls`) sits at the
sphere's top pole, so the teal→amber shading is strongest up top and
fades to plainly-lit white toward the bottom. -->
<sk-spherical-gradient-field id="mask" x="-11" y="3" z="11" inner-radius="3"
outer-radius="3.05" visualize="true" interactive-controls="true"></sk-spherical-gradient-field>
<sk-tonemap id="shade-tm" color-map="#ramp" field="#mask"></sk-tonemap>
<sk-plain-material id="shade-mat" base-color="white" tonemap="#shade-tm"></sk-plain-material>
<sk-sphere x="-11" z="11" radius="3" segments="5">
<sk-surface-paint material="#shade-mat"></sk-surface-paint>
</sk-sphere>
<sk-overlay-annotation x="-11" y="8" z="11" anchor="bottom">
<div style="color:#e8ddc7; font:12px sans-serif; text-align:center;">spherical field<br/>→<br/>tonemap mask</div>
</sk-overlay-annotation>
<!-- FRONT-RIGHT — linear field → COLOR-SOURCE. A horizontal linear field
sweeps the teal→amber ramp across the sphere as the base color, painted
by position along the field rather than by the light. The field ramps
along its local +Z; h="90deg" turns that to run along +x, from the
sphere's left edge (weight 0) to its right (weight 1). -->
<sk-linear-gradient-field id="paint" x="8" z="11" extent="6" h="90deg"
visualize="true" interactive-controls="true"></sk-linear-gradient-field>
<sk-color-map-source id="paint-src" intensity-field="#paint" color-map="#ramp"></sk-color-map-source>
<sk-plain-material id="paint-mat" base-color="white" base-color-source="#paint-src"></sk-plain-material>
<sk-sphere x="11" z="11" radius="3" segments="5">
<sk-surface-paint material="#paint-mat"></sk-surface-paint>
</sk-sphere>
<sk-overlay-annotation x="11" y="8" z="11" anchor="bottom">
<div style="color:#e8ddc7; font:12px sans-serif; text-align:center;">linear field<br/>→<br/>color-source</div>
</sk-overlay-annotation>
</sk-scene>