KloradDocs

Style objects by readings

Colour and scale objects by their current state, and show when a sensor has gone quiet.

The default look encodes correspondence and freshness. To show your own state, give the renderer an objectStyle function. It runs for every object whenever the object, its readings or its staleness change.

style-by-readings.ts
import type { StyleFn } from "@klorad/engine-three";

/** Colours a room by how full it is, and greys it out when its counter goes quiet. */
export const occupancyStyle: StyleFn = ({ object, readings, stale, palette }) => {
  if (stale) return { color: palette.stale, opacity: 0.6 };
  const people = readings.occupancy?.value;
  if (typeof people !== "number") return { color: object.color ?? palette.object };
  const load = people / Number(object.properties.capacity ?? 50);
  const color = load > 0.9 ? "#dc2626" : load > 0.6 ? "#f59e0b" : palette.shadow;
  return { color, heightScale: Math.max(0.2, Math.min(load, 1.5)) };
};

The function receives:

Prop

Type

and returns any of color, opacity and heightScale. Anything it leaves out keeps the default.

In React

rooms-view.tsx
"use client";

import { ThreeView } from "@klorad/engine-three/react";
import { occupancyStyle } from "./style-by-readings";

// Options are read when the view mounts: change `key` to apply a different style.
export function RoomsView() {
  return <ThreeView objectStyle={occupancyStyle} palette={{ background: "#0b1220" }} />;
}

ThreeView reads its options when it mounts. To switch styles at runtime, change its key.

Keep it pure

A style function is called often and must not change anything: no scene writes, no fetches. If a colour depends on something outside the scene, put that something in the scene first (as a property or a reading), so every view and every hook agrees on it.

Something wrong or unclear? Tell your contact at Prieston Technologies.