Skip to content
This repository has been archived by the owner on Aug 2, 2020. It is now read-only.

Latest commit

 

History

History
73 lines (55 loc) · 2.72 KB

README.md

File metadata and controls

73 lines (55 loc) · 2.72 KB

diceroll

Roll the dice!


demo

This is a 3D motion-activated dice built with React, Next.js, Typescript and the Web Sensors API.

Try it live at diceroll.gaby.dev!

Compatibility

This should work on any web browser, however:

  • Browsers without sensors support (gyroscope + accelerometer) will graciously fall back to a static version of the cube without the orientation animation.
  • Desktop browsers will display a pop-up with a QR code to encourage users to try it on their phone.

Technical

The cube itself is made with CSS perspective and transforms on a bunch of <div>s. A .svg texture file contains the dots and is placed on each face and aligned with background-position.

demo

The gyroscope API is used to detect when angular velocity of the device is past a certain threshold, to trigger a dice roll.

A random number is chosen using Math.random() and after a little CSS animation, the cube is rotated to put the correct face on top, using an array of X/Y/Z rotation values (in deg):

this.faceViews = [
  [0, 0, 0],
  [90, 0, 0],
  [0, 90, 0],
  [0, -90, 0],
  [-90, 0, 0],
  [-180, 0, 0]
]

Using the RelativeOrientationSensor API or the DeviceOrientationEvent API depending on browser support, an offset is applied to those values to factor in the device's orientation for a cool 3D effect.

// Calculate perspective rotation with device orientation effect
rx = x + (ax * 40)
if (this.state.face === 5) {
  ry = y
  rz = z + (-ay * 40)
} else if (this.state.face === 2) {
  ry = y
  rz = z + (ay * 40)
} else if (this.state.face === 6) {
  ry = y + (ay * 40)
  rz = z
} else {
  ry = y + (-ay * 40)
  rz = z
}
.cube {
  transform-style: preserve-3d;
  transform: rotateX(${rx}deg) rotateY(${ry}deg) rotateZ(${rz}deg);
}

Finally, the rounded edges of the cube's faces are filled with a second layer that is offset by the border-radius in px, so you can't see inside the cube through the edges:

demo


© 2020 Gabriel Saillard [email protected]