Everyone hates accident actions (like file removement). You will think twice while holding this action button!
A Pen by Sergey Berkin on CodePen.
| doctype html | |
| html | |
| head | |
| title Prevent accident action | |
| body | |
| p.aligned | |
| button.button--remove Hold to remove | |
| span.button--remove__indicator | |
| span.button--remove__indicator__progress | |
| span.button--remove__indicator__mask |
Everyone hates accident actions (like file removement). You will think twice while holding this action button!
A Pen by Sergey Berkin on CodePen.
| $ -> | |
| removeTimeout = 2000 | |
| startN = 5 | |
| n = startN | |
| interval = null | |
| $button = $ 'button' | |
| $mask = $button.find '.button--remove__indicator__mask' | |
| $progress = $button.find '.button--remove__indicator__progress' | |
| $progress50 = null | |
| $button | |
| .on 'mousedown', -> | |
| interval = window.setInterval (-> | |
| degree = n / (removeTimeout / 90) | |
| # Check if indicator is done | |
| if degree >= 360 | |
| $button.addClass 'button--remove--done' | |
| $button.trigger 'mouseup' | |
| return | |
| else if degree >= 180 and $progress50 is null | |
| $progress50 = $progress.clone() | |
| $progress50.css | |
| zIndex: 3 | |
| transform: 'rotateZ(180deg)' | |
| $progress.after $progress50 | |
| $progress.css zIndex: 5 | |
| # Update indicator | |
| $target = $progress50 or $progress | |
| $target.css transform: 'rotateZ(' + degree + 'deg)' | |
| n += removeTimeout / 10 | |
| ), removeTimeout / 90 | |
| .on 'mouseup mouseleave', -> | |
| # Clear interval | |
| if interval isnt null | |
| clearInterval interval | |
| n = startN | |
| # Reset styles | |
| if $progress50 isnt null | |
| $progress50.remove() | |
| $progress50 = null | |
| $progress.css | |
| transform: 'rotateZ(0deg)' | |
| zIndex: 'auto' |
| @import url('http://fonts.googleapis.com/css?family=Open+Sans'); | |
| @color-primary: #9E150F; | |
| @color-background: white; | |
| @indicator-width: 2px; | |
| @color-text: #999; | |
| @font-size: 32px; | |
| @keyframes removement { | |
| 0% { | |
| transform: scale(1); | |
| } | |
| 50% { | |
| transform: scale(1.1); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: scale(0.2); | |
| opacity: 0; | |
| } | |
| } | |
| body { | |
| font: 16px Arial, Helvetica, sans-serif; | |
| background: @color-background; | |
| color: @color-text; | |
| padding: 0; | |
| margin: 0; | |
| } | |
| .aligned { | |
| text-align: center; | |
| margin: 5%; | |
| } | |
| .button--remove { | |
| font-family: 'Open Sans', sans-serif; | |
| transition: color 2s ease; | |
| background: transparent; | |
| display: inline-block; | |
| font-size: @font-size; | |
| user-select: none; | |
| cursor: pointer; | |
| padding: 10px; | |
| border: none; | |
| &:active { | |
| color: @color-primary; | |
| } | |
| &:active, | |
| &:focus { | |
| outline: none; | |
| } | |
| &--done { | |
| animation-name: removement; | |
| animation-duration: 1s; | |
| animation-fill-mode: forwards; | |
| } | |
| &__indicator { | |
| border: @indicator-width solid transparent; | |
| margin-bottom: -(@font-size / 3); | |
| margin-left: @font-size / 3; | |
| border-radius: @font-size; | |
| height: @font-size * 1.25; | |
| width: @font-size * 1.25; | |
| box-sizing: border-box; | |
| display: inline-block; | |
| position: relative; | |
| &:before, | |
| &:after { | |
| @height: @font-size * 0.85; | |
| @width: @font-size * 0.1; | |
| background: @color-primary; | |
| margin-top: -(@height / 2); | |
| margin-left: -(@width / 2); | |
| display: inline-block; | |
| position: absolute; | |
| height: @height; | |
| width: @width; | |
| content: ''; | |
| z-index: 6; | |
| left: 50%; | |
| top: 50%; | |
| } | |
| &:before { transform: rotateZ(45deg); } | |
| &:after { transform: rotateZ(-45deg); } | |
| &__progress, | |
| &__mask { | |
| border-radius: ~'100% 0 0 100% / 50% 0 0 50%'; | |
| background: @color-background; | |
| transform-origin: 100% 50%; | |
| left: -@indicator-width; | |
| top: -@indicator-width; | |
| position: absolute; | |
| display: block; | |
| height: 100%; | |
| width: 50%; | |
| } | |
| &__progress { | |
| border: @indicator-width solid @color-primary; | |
| border-right: none; | |
| } | |
| &__mask { | |
| box-shadow: -@indicator-width 0 0 0 @color-background; | |
| padding: @indicator-width; | |
| padding-right: 0; | |
| } | |
| } | |
| } |