-walls = %w(front top right bottom left)
.perspective
  .container
    .scratch
      .scratch_outer
    .buttons
      .buttons_top
        -3.times do
          .button><
            -walls.each do |w|
              %div{class: w}
            .switch.black
              .light
                -walls.each do |w|
                  %div{class: w}
              -walls.each do |w|
                %div{class: w}
      .buttons_bottom
        -4.times do
          .button><
            -walls.each do |w|
              %div{class: w}
            .switch.white
              .light
                -walls.each do |w|
                  %div{class: w}
              -walls.each do |w|
                %div{class: w}
  .blink_button 自動点滅
View Compiled
$button_w: 1em
$button_h_rate: 1.65
$button_h: $button_w * $button_h_rate
$switch_h: $button_w / 5
$switch_border_w: $button_w * 0.005
$button_black_color: rgba(50, 50, 80, 0.9)
$button_white_color: rgba(white, 0.9)

*
  box-sizing: border-box
html, body
  height: 100%
  width: 100%
  overflow: hidden
body
  background: silver
  .perspective
    opacity: 0
    position: absolute
    left: 50%
    top: 50%
    transform: translate(-50%, -50%)
    padding: 20px 0
    display: inline-block
    perspective: $button_w * 9
.container
  padding: 0 40px
  display: inline-block
  transform-origin: 50% 50%
  transform-style: preserve-3d
  transform: rotateX(30deg) rotateZ(0deg)
.buttons_top
  white-space: nowrap
  padding: 0 $button_w * 0.75
.buttons_bottom
  white-space: nowrap
  padding: $button_w * 0.4 0
.button
  position: relative
  display: inline-block
  width: $button_w
  height: $button_h
  margin-right: $button_w / 2
  .switch
    $pad_w: 10%
    width: 100% - $pad_w
    height: 100% - ($pad_w / $button_h_rate)
    display: inline-block
    position: absolute
    left: 50%
    top: 50%
    transform: translateX(-50%) translateY(-50%) translateZ($switch_h)
    transform-style: preserve-3d
    border: $switch_border_w solid black
    &.white
      background: $button_white_color
    &.black
      background: $button_black_color
    &.hover
      transform: translateX(-50%) translateY(-50%) translateZ($switch_h / 2)
      >
        .front, .top, .bottom, .left, .right
          opacity: 0.3
      .light
        z-index: 1
        background: radial-gradient(ellipse farthest-corner at 50%, rgb(255, 10, 0) 0%, transparent 110%)
        box-shadow: 0 0 ($button_w * 0.0125) ($button_w * 0.003) rgba(255, 0, 0, 1) inset
        position: absolute
        left: 50%
        top: 50%
        transform: translate(-50%, -50%)
        width: 100%
        height: 100%

@mixin walls($deg, $bg)
  >
    .front, .top, .right, .bottom, .left
      position: absolute
      background: $bg
    .front
      width: 100%
      height: 100%
    .top, .bottom
      width: 100%
      height: $switch_h
      left: 50%
    .top
      transform-origin: 50% 100%
      transform: rotateX($deg) translateX(-50%)
      bottom: 100%
    .bottom
      transform-origin: 50% 0
      left: 50%
      transform: rotateX(-$deg) translateX(-50%)
      top: 100%
    .left, .right
      height: 100%
      width: $switch_h
      top: 50%
    .left
      transform-origin: 100% 50%
      transform: rotateY(-$deg) translateY(-50%)
      right: 100%
    .right
      transform-origin: 0 50%
      transform: rotateY($deg) translateY(-50%)
      left: 100%
.button, .switch, .light
  transform-style: preserve-3d
.button
  @include walls(45deg, black)
  >
    .bottom, .top, .left, .right
      background: transparent
    .bottom, .top
      box-sizing: content-box
      width: 100%
      height: 0
      border-left: $switch_h * 0.7 solid transparent
      border-right: $switch_h * 0.7 solid transparent
    .top
      border-top: $switch_h solid black
    .bottom
      border-bottom: $switch_h solid black
    .left, .right
      box-sizing: content-box
      height: 100%
      width: 0
      border-top: $switch_h * 0.7 solid transparent
      border-bottom: $switch_h * 0.7 solid transparent
    .left
      border-left: $switch_h solid black
    .right
      border-right: $switch_h solid black
.switch
  @include walls(90deg, inherit)
  >
    .light
      position: absolute
      @include walls(90deg, inherit)
    .front, .top, .right, .bottom, .left
      border: $switch_border_w solid black
.blink_button
  font-size: 20%
  font-weight: bold
  background: #3261AB
  color: white
  padding: 10px 0
  text-align: center
  border-radius: 2em
  width: 50%
  margin: auto
$ ->
  resize = ->
    # ボタンのサイズ調整
    w = $('body').outerWidth()
    h = $('body').outerHeight()
    button_width = if w / h > 2 then h / 5 else w / 8
    $('head').append($('<style>').text('body{font-size: ' + button_width + 'px;}'))
  $(window).on('resize', resize)
  resize()
    
  $('.perspective').animate(opacity: 1)
  
  # 各種イベント定義
  start_event = end_event = null
  if window.ontouchstart == null
    start_event = 'touchstart'
    end_event = 'touchend'
  else
    start_event = 'mousedown'
    end_event = 'mouseup'
  $(document).on start_event, '.switch', ->
    return if blinking
    $(@).addClass('hover')
    #$('body').append($('<div>').text('st'))
  .on end_event, '.switch', ->
    return if blinking
    $(@).removeClass('hover')
    #$('body').append($('<div>').text('en'))
  .on 'mouseup', ->
    return if blinking
    $('.switch.hover').removeClass('hover')
  .on 'mousedown click', (e) ->
    e.preventDefault()
    false
  
  # ボタンを点滅させる
  blinking = false
  do_blink = ->
    return if blinking
    blinking = true
    button_num = [2, 4, 6, 1, 3, 5, 7]
    duration = 150
    switches = $('.switch')
    # ボタン点滅
    blink = (opt) ->
      i = 0
      single_blink = ->
        opt.element.addClass('hover')
        setTimeout ->
          opt.element.removeClass('hover')
          i++
          opt.callback(i) if opt.callback
          setTimeout(single_blink, opt.duration) if i < opt.count
        , opt.duration
      single_blink()

    blink_conf = [1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1]
    $(blink_conf).each (i, b_num) ->
      elm = switches[button_num.indexOf(b_num)]
      setTimeout ->
        blink
          element: $(elm)
          count: 1
          duration: duration
          callback: ->
            if i == blink_conf.length - 1
              switches.removeClass('hover')
              setTimeout ->
                limit = 3
                blink
                  element: switches
                  count: limit
                  duration: duration * 3
                  callback: (count) ->
                    blinking = false if count >= limit
              , duration * 2
        , duration
      , i * duration
  $('.blink_button').on 'click', do_blink
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js