みかづきブログ その3

3ヶ月つづけてみました。

CSSでロングシャドウをつくってその影で影時計をつくりました。 😎

f:id:kimizuka:20170202173007p:plain

最近、家に時計がないことに気づきました。

時計機能のついたものはたくさんあるので、時間がわからなくて困ることは無いんですが、
世の中から時計という装置がどんどん減ってきてるのではないかと思いました。

反面、ありとあらゆるものに時計機能が付随しているなぁと思いました。
レンジとか、炊飯器やら、エアコンのリモコンやら、スマホやら。そう。それは時計という装置の存在を追いやるほどに。

でもって、マウスカーソルに時計機能を付けたらどうなるか考えてみたものがこちらです。なぜマウスカーソルなのかは自分でもわかりません。
マウスカーソルにロングシャドウを落とすことで現在時刻を表しています。
短針しかないのですが、例えば10時30分であれば、10.5時と表現しています。
また、スマホで見たときはディスプレイに置いた指に影を落としています。
なので上記写真は5時半ぐらいかとおもわれます。

DEMO

See the Pen Long Shadow Clock by kimmy (@kimmy) on CodePen.

HTML

<div id="wrapper">
  <h1 class="ttl">Please Touch The Screen.</h1>
  <div id="clock"></div>
</div>

SCSS

%shadow {
  position: absolute;
  display: block;
  left: 50%;
  content: "";
  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .1)), to(rgba(0, 0, 0, 0)));
  transform-origin: center left;
  opacity: 0;
  
  &[data-visible="true"] {
    opacity: 1;
  }
}

* {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-touch-callout: none;
  -webkit-user-select: none;
}

html {
  height: 100%;
  cursor: pointer;
}

body {
  height: 100%;
  background: #424242;
}


#wrapper {
  position: relative;
  width: 100%; height: 100%;
  overflow: hidden;
}

#clock {
  position: absolute;
  width: 10px; height: 10px;
  z-index: 1;
  
  &:before {
    @extend %shadow;
  }
  
  &[data-touch="false"] {
    &:before {
      border-radius: 5px;
      width: 50vw; height: 10px;
    }
  }
  
  &[data-touch="true"] {
    margin: -35px;
    width: 70px; height: 70px;
    opacity: 1;
    
    &:before {
      border-radius: 35px;
      width: 100vh; height: 70px;
      opacity: 1;
    }
  }
}

@for $i from 0 through 119 {
  [data-hours="#{$i}"] {
    &:before {
      transform: rotate(#{($i + 1) * 3 - 90}deg);
    }
  }
}

.ttl {
  position: fixed;
  top: 50%;
  margin-top: -25px;
  width: 100%;
  color: rgba(255, 255, 255, .1);
  font: 50px AvenirNext-Heavy;
  text-align: center;
  text-shadow: 0 0 2px rgba(0, 0, 0, .1);
  user-select: none;
  pointer-events: none;
}

.ttl {
  display: flex;
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  color: rgba(255, 255, 255, .1);
  font: 50px AvenirNext-Heavy;
  align-items: center;
  justify-content: center;
  text-shadow: 0 0 2px rgba(0, 0, 0, .1);
  user-select: none;
  pointer-events: none;
}

JavaScript

(() => {
  
  "use strict";
  
  var clock     = document.getElementById("clock"),
      hours     = getHours(),
      x         = 0,
      y         = 0,
      isVisible = false,
      isTouch   = false;
  
  setInterval(() => {
    hours = getHours();
  }, 1000);
  
  document.addEventListener("mousemove", (evt) => {
    if (!isTouch) {
      x = evt.clientX;
      y = evt.clientY;
      isVisible = true;
      isTouch   = false;
    }
  }, false);
  
  document.addEventListener("mouseleave", (evt) => {
    isVisible = false;
  }, false);
  
  document.addEventListener("touchstart", (evt) => {
    isVisible = true;
    isTouch   = true;
    x = evt.touches[0].clientX;
    y = evt.touches[0].clientY;
  }, false);
  
  document.addEventListener("touchmove", (evt) => {
    evt.preventDefault();
    isVisible = true;
    isTouch   = true;
    x = evt.touches[0].clientX;
    y = evt.touches[0].clientY;
  }, false);

  document.addEventListener("touchend", (evt) => {
    isVisible = false;
    setTimeout(() => {
      isTouch = false;
    }, 50);
  }, false);
  
  requestAnimationFrame(draw);
  
  function getHours() {
    var date    = new Date(),
        hours   = date.getHours() % 12,
        minutes = date.getMinutes();
    
    return ((hours + minutes / 60) * 10) | 0;
  }
  
  function draw() {
    clock.dataset.visible = isVisible;
    clock.dataset.touch   = isTouch;
    clock.style.cssText = "; top: " + y + "px; left: " + x + "px";
    clock.dataset.hours = hours;
    requestAnimationFrame(draw);
  }
  
})();