ef.js Simple Data Binding

by Yukino Song

HTML

<script src="https://cdn.jsdelivr.net/npm/ef.js@latest"></script>

SCSS

* {
  box-sizing: border-box;
}

.analog {
  background-color: #CCC;
  height: 204px;
  width: 204px;
  border: 2px solid #8c8c8c;
  border-radius: 102px;
  position: absolute;
  overflow: hidden;
}

.hand {
  height: 200px;
  position: absolute;
  &:before {
    content: '';
    display: block;
    height: 100%;
    width: 100%;
  }
  &.hour {
    width: 20px;
    padding-top: 50px;
    padding-bottom: 90px;
    left: 90px;
    &:before {
      background-color: #666;
    }
  }
  &.minute {
    width: 10px;
    padding-top: 30px;
    padding-bottom: 85px;
    left: 95px;
    &:before {
      background-color: #333;
    }
  }
  &.second {
    width: 4px;
    padding-top: 10px;
    padding-bottom: 75px;
    left: 98px;
    &:before {
      background-color: #000;
    }
  }
}

.pin {
  position: absolute;
  width: 2px;
  height: 2px;
  background-color: #FFF;
  border-radius: 1px;
  top: 99px;
  left: 99px;
}

.grad {
  height: 200px;
  width: 2px;
  border-color: #8c8c8c;
  border-style: solid;
  position: absolute;
  left: 99px;
  &.short {
    border-width: 3px 0;
  }
  &.long {
    border-width: 6px 0;
  }
}

JavaScript

const { t, inform, exec } = ef

inform()

const Grad = t`
>div.grad.{{type}}
  #style = transform: rotate({{deg}}deg);
`

const clock = new t`
>div
  >h2
    .{{hour = 00}}:{{minute = 00}}:{{second = 00}}:{{ms}}
  >div.analog
    +grads
    >div.hand.hour
      #style = transform: rotateZ({{h = 0}}deg) translateZ(0);
    >div.hand.minute
      #style = transform: rotateZ({{m = 0}}deg) translateZ(0);
    >div.hand.second
      #style = transform: rotateZ({{s = 0}}deg) translateZ(0);
    >div.pin
`

for (let i = 0; i < 30; i++) {
  clock.grads.push(new Grad({
    $data: {
      deg: i * 6,
      type: i % 5 === 0 ? 'long' : 'short'
    }
  }))
}

const padZero = (val) => {
  if (val < 10) return `0${val}`
  return `${val}`
}

const getTime = () => {
  const date = new Date()
  const h = date.getHours()
  const m = date.getMinutes()
  const s = date.getSeconds()
  const ms = date.getMilliseconds()
  clock.$data = {
    hour: padZero(h),
    minute: padZero(m),
    second: padZero(s),
    h: h * 30 + m / 2 + s / 120 + ms / 1200000,
    m: m * 6 + s / 10 + ms / 10000,
    s: s * 6 + ms * 0.006,
    ms
  }
  window.requestAnimationFrame(getTime)
}

getTime()

clock.$mount({target: document.body})

exec()