JSFiddle - React, Tailwind, and code Playground

by Kye Hohenberger

HTML

<script src="https://unpkg.com/preact/dist/preact.min.js"></script>
<script src="https://unpkg.com/proptypes"></script>
<script src="https://unpkg.com/preact-compat/dist/preact-compat.min.js"></script>
<script src="https://cdn.rawgit.com/developit/0c2755a85948cb62e663170e403c9697/raw/9591812d5742f25e2df6b90133ccc70ba2241485/preact-polyfill.js"></script>
<script src="https://unpkg.com/[email protected]/umd/data-driven-motion.min.js"></script>
<div id="app"></div>

CSS

html,
body,
#app,
.full-size {
  font-family: sans-serif;
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

Babel + JSX

const { h, Component, render} = preact
const {Motion} = DDM // https://github.com/tkh44/data-driven-motion

const WOBBLY_SPRING = {stiffness: 280, damping: 30}

class BoxContainer extends Component {
  state = {x: 0, y: 0, mouseDown: false}

  render () {
    const {x, y} = this.state

    return h(Motion, {
      data: Array.from({length: 33}, (v, i) => ({key: 'circle-' + i})),
      component: (
        <div
          style={{flex: 1, width: '100%', height: '100%', backgroundColor: '#111111', perspective: 1000}}
          onMouseMove={({pageX: x, pageY: y}) => this.setState({x, y})}
          onMouseDown={() => this.setState({mouseDown: true})}
          onMouseUp={() => this.setState({mouseDown: false})}
        />
      ),
      getKey: data => data.key,
      onComponentMount: () => ({x, y, z: 0, hue: 0}),
      onRender: (data, i, spring) => ({
        x: spring(x, WOBBLY_SPRING),
        y: spring(y, WOBBLY_SPRING),
        z: spring(this.state.mouseDown ? i * 30 : 0, WOBBLY_SPRING),
        hue: spring(((x * i + y * i) / 2) % 360)
      }),
      onRemount: () => ({x, y, z: 0, hue: 0}), // Does not matter since data does not change
      onUnmount: () => ({x, y, z: 0, hue: 0}), // Does not matter since data does not change
      render: this.renderCircle
    })
  }

  renderCircle = (key, data, style, dataIndex, layerIndex) => {
    return (
      <div
        key={key}
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          height: 'calc((64px + 5vh + 5vw) / 3)',
          width: 'calc((64px + 5vh + 5vw) / 3)',
          borderRadius: '50%',
          border: `3px solid hsl(${style.hue + dataIndex * 180}, 50%, 40%)`,
          backfaceVisibility: 'hidden',
          transformOrigin: 'center center',
          transform: `translate3d(calc(${style.x}px - 5vw), calc(${style.y}px - 5vh), ${style.z}px)`,
          cursor: dataIndex === 0 ? 'pointer' : 'normal'
        }}
        children={this.state.mouseDown}
      />
...