lightAPI

lightshow.js

DMX512

DMX512

  • protocol used for any* kind of professional lighting
  • one sender, multiple receivers
  • 512 DMX-Channels === 512 bytes of data

Device-Mapping

  • fixed, preconfigured address per device
  • reads 1..n channels starting at that address
  • most annoying: what meaning a channel has is entirely vendor and device-specific

DMX.js

const dmxData = new Uint8Array(512);
  
// device with 4 channels at address 42 
// (dmx-channels are 1-based, our array isn't)
const deviceData = dmxData.slice(41, 45);
//            brightness
//            |    RGB-Color
//            |    |
//            |    +----------+
deviceData = [255, 255, 240, 30];

complex devices

complex devices

  • PAN / TILT
  • BRIGHTNESS / COLOR
  • ZOOM / FOCUS
  • BEAM-SHAPING (GOBO / PRISM)
  • SPECIAL FX

(Martin Professional Quantum Profile EX)

(...thats 27 DMX-Channels per Device)

fivetwelve

an abstraction-layer for DMX512

fivetwelve

const device = new DmxDevice(421, paramDefinitions);

// values for motion in degrees
device.pan = 90;
device.tilt = 45;

device.brightness = 1; // values [0..1] for most properties
device.color = 'magenta'; // css-color-value for RGB and CMY
Object.defineProperty() ♥️

an abstraction-layer for DMX512

fivetwelve

const d = new QuantumProfile(channel);

setInterval(() => {
  d.pan = 90 * Math.sin(time / 3000);
  d.tilt = 30 * Math.sin(time / 2000);

  d.brightness = 1;
  d.color = 'rgb(255,140,63)';
}, 1000/30);

simple animations..

fivetwelve-css

why not just use CSS instead?

device[type="quantum-profile"] {
  pan: 90deg;
  tilt: 30deg;

  brightness: 1;
  color: rgb(255,140,63);

  animation: panTilt 3s infinite alternate;
}

@keyframes panTilt {
  from { pan: 45deg; tilt: 0deg; }
  to { pan: 135deg; tilt: 60deg; }
}

fivetwelve-css

HTML-structure

<deviceroot>
  <devices>
    <!-- UNIVERSE 1: STAGE -->
    <!-- STAGE BACK / 6 Quantum Profile -->
    <device class="qp back left" type="quantum-profile" channel="1:109"></device>
    <device class="qp back left" type="quantum-profile" channel="1:136"></device>
    <device class="qp back center" type="quantum-profile" channel="1:163"></device>
    <device class="qp back center" type="quantum-profile" channel="1:190"></device>
    <device class="qp back right" type="quantum-profile" channel="1:217"></device>
    <device class="qp back right" type="quantum-profile" channel="1:244"></device>
  </devices>
</deviceroot>

fivetwelve-css

...and some javascript

const deviceNodes = Array.from(document.querySelectorAll('device'));

deviceNodes.forEach(deviceNode => {
  const currStyle = window.getComputedStyle(deviceNode);
  const dmxDevice = getDevice(deviceNode);
  
  dmxDevice.setParams(extractParams(currStyle));
});

dmxOutput.send();

some problems with that:

  • unknown CSS-properties are ignored by the browser

fivetwelve-css

Solution: use CSS custom-properties

device[type="quantum-profile"] {
  --pan: 90deg;
  --tilt: 30deg;

  --brightness: 1;
  color: rgb(255,140,63);

  animation: panTilt 3s infinite alternate;
}

@keyframes panTilt {
  from { --pan: 45deg; --tilt: 0deg; }
  to { --pan: 135deg; --tilt: 60deg; }
}

some problems with that:

  • unknown CSS-properties are ignored by the browser
  • custom-properties + transitions/animations don't work

fivetwelve-css

Solution: use properties that can be animated, map values

device[type="quantum-profile"] {
  --pan: 90deg; left: 90px;
  --tilt: 30deg; right: 90px;

  --brightness: 1;
  color: rgb(255,140,63);

  animation: panTilt 3s infinite alternate;
}

@keyframes panTilt {
  from { --pan: 45deg; --tilt: 0deg; left: 45px; right: 0px; }
  to { --pan: 135deg; --tilt: 60deg; left: 135px; right: 60px; }
}

the hack

  • parse CSS using the rework css-parser
  • transform: custom-properties + animation-fallbacks
  • rebuild CSS and inject into page
  • Animation-Frame: use                                            to get final values for all parameters
getComputedStyle()

Copy of jsconf.asia-2016

By Martin Schuhfuss

Copy of jsconf.asia-2016

  • 1,268