The realistic eye on the scene — a camera with true perspective, where distant things look smaller and parallel lines converge, framed with real photographic controls (focal length, sensor size).
Declarative element:
<sk-perspective-camera>
Global: available as sk.PerspectiveCamera inside a scene <script>.
This is the perspective member of the AbstractCamera family: the camera
decides how the 3D scene is projected onto the 2D viewport. Declaring one replaces
the scene's default camera.
Aiming a camera is fiddly — a bare camera looks straight down its own local −Z,
so you must position AND rotate it by hand to frame the subject, and it does not
follow anything. For most scenes it is far easier to let a
sk-camera-orbit-control own the framing: it points a camera at a pivot,
fits the scene automatically, and gives you orbit / pan / zoom for free. Reach for a
hand-placed camera only when you want a specific fixed shot.
Key attributes. The lens is described photographically. focal-length (in mm)
sets the field of view — a short focal length (24mm) is a wide angle of view, a long
one (85mm+) is a narrow telephoto; it is animatable, so the lens can zoom in and out.
(The strength of perspective — how much near things loom over far ones — comes from
where the camera stands, not the focal length; a wide lens simply invites you close,
where perspective is strong.) sensor-width is the frame that focal length is
measured against (36mm = full-frame); focal length and sensor width together (with
the viewport aspect) determine the vertical field of view. near and far bound the
visible depth range. Position is the usual node transform — a camera on +Z looking
back at the origin is the simplest fixed setup.
Related. Its sibling sk-orthographic-camera drops perspective entirely
(parallel projection, constant on-screen size). To orbit, pan, and auto-fit instead
of hand-placing, use a sk-camera-orbit-control.
constructor(config?: { sensorWidth?: number; focalLength?: number; near?: number; far?: number; aspect?: number; autoClipping?: boolean; autoClippingMargin?: number; minNear?: number; maxFar?: number; id?: string; x?: number; y?: number; z?: number; h?: number; p?: number; b?: number; quaternion?: Quaternion; sx?: number; sy?: number; sz?: number; s?: number; class?: string; style?: string })
Inherited from: AbstractCamera, SceneNode, SkenraAnimatable
— see those pages for inherited members.
| Property | Type | Default | Description | Declared by |
|---|---|---|---|---|
sensorWidthanimatable |
number |
36 |
Gets the sensor width. | PerspectiveCamera |
focalLengthanimatable |
number |
300 |
Gets the focal length of the camera lens. | PerspectiveCamera |
nearanimatable |
number |
0.1 |
Gets the distance to the near clipping plane. | AbstractCamera |
faranimatable |
number |
500.0 |
Gets the distance to the far clipping plane. | AbstractCamera |
aspectread-only |
number |
— | Gets the current aspect ratio. | AbstractCamera |
autoClipping |
boolean |
true |
Whether auto near/far clipping is enabled. | AbstractCamera |
autoClippingMargin |
number |
0.1 |
Padding applied to the auto-computed depth range (fraction). | AbstractCamera |
minNear |
number |
— | Hard lower clamp on the auto-computed near plane. | AbstractCamera |
maxFar |
number |
1e6 |
Hard upper clamp on the auto-computed far plane. | AbstractCamera |
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 |
|---|---|---|---|---|
focalLengthBasebase value |
number |
— | Gets the base (non-animated) value of focalLength. | PerspectiveCamera |
sensorWidthBasebase value |
number |
— | Gets the base (non-animated) value of sensorWidth. | PerspectiveCamera |
fovYread-only |
number |
— | Gets the vertical field of view. | PerspectiveCamera |
viewProjectionMatrixread-only |
Float32Array<ArrayBufferLike> |
— | Gets the combined view-projection matrix. | AbstractCamera |
viewMatrixread-only |
Float32Array<ArrayBufferLike> |
— | Gets the view matrix that transforms world space to camera space. | AbstractCamera |
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 |
|---|---|---|
getRayFromNDC(ndcX: number, ndcY: number): { origin: Float32Array; direction: Float32Array; } | null |
Creates a ray from the camera through a point in normalized device coordinates. | AbstractCamera |
worldPositionFromNDC(ndcX: number, ndcY: number, ndcZ: number = 0.5): [number, number, number] | null |
Computes a world-space position from Normalized Device Coordinates (NDC). | AbstractCamera |
worldPositionToNDC(worldX: number, worldY: number, worldZ: number): [number, number, number] | null |
Converts a world-space position to normalized device coordinates (NDC). | AbstractCamera |
getFrustumCornersWorldSpace(): { near: [number, number, number][]; far: [number, number, number][]; } |
Gets the 8 corners of the camera's view frustum in world space. | AbstractCamera |
getLookDirection(): [number, number, number] |
Gets the camera's look direction in world space. | AbstractCamera |
fitViewToBounds(bounds: SceneBounds, options?: FitViewOptions): void |
Adjusts camera to fit the given bounding box in view. | AbstractCamera |
fitViewToSphere(center: [number, number, number], radius: number, options?: FitViewOptions): void |
Adjusts camera to fit a bounding sphere in view. | AbstractCamera |
fitViewToScene(scene: Scene, options?: FitViewOptions): void |
Adjusts camera to fit all visible geometry in the scene. | AbstractCamera |
fitViewToNodes(nodes: SceneNode | SceneNode[], options?: FitViewOptions): void |
Adjusts camera to fit specific node(s) and their descendants. | AbstractCamera |
setViewOffset(fullWidth: number, fullHeight: number, x: number, y: number, width: number, height: number): void |
Sets a viewport offset for rendering a sub-region of the full viewport. | AbstractCamera |
clearViewOffset(): void |
Clears the viewport offset, restoring normal full-viewport rendering. | AbstractCamera |
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 |
// Create camera with 50mm focal length (standard lens)
const camera = new PerspectiveCamera({ id: 'main-camera',
focalLength: 50,
sensorWidth: 36, // Full-frame sensor
near: 0.1,
far: 1000
});
// Position camera
camera.z = 5;
camera.lookAt([0, 0, 0]); // Look at origin
// Wide-angle camera (24mm)
const wideCamera = new PerspectiveCamera({ id: 'wide',
focalLength: 24
});
// Telephoto camera (200mm)
const telephoto = new PerspectiveCamera({ id: 'tele',
focalLength: 200
});
Used in guides: Scene basics