Skip to content

Instantly share code, notes, and snippets.

@jiangtao
Created August 22, 2017 10:24
Show Gist options
  • Save jiangtao/045097ae4807dba3be059393a1bb5bcb to your computer and use it in GitHub Desktop.
Save jiangtao/045097ae4807dba3be059393a1bb5bcb to your computer and use it in GitHub Desktop.
WIP: Gyro fill effect
h2 Gyro filling
.progress-badge.js-progress-badge.is-filling.is-filling-from-empty
// BADGE
.badge.badge--empty
.badge__fill.js-badge-gyro
.badge__fill-inner
.badge__content
.badge__content-inner
.badge__value
span.js-badge-value(data-target='5') 0
.badge__label Action here
var $badges = $('.js-progress-badge')
, $window = $(window)
, windowOrientation = window.orientation
, firstRun = true
// window.orientation accounts for landscape orientations
window.addEventListener('orientationchange', function() {
windowOrientation = window.orientation
console.log('orientation change')
}, false);
function tilt (rotation, $el) {
if (rotation === null) return
// Bump lower numbers so CSS animation doesn't flip between 0 and 360
if (rotation < 180) rotation = rotation + 360
var adjustedRotation = (rotation - windowOrientation).toFixed(1)
console.log(rotation, windowOrientation, adjustedRotation)
$el.css({transform: 'rotate(' + adjustedRotation + 'deg)'})
$el.parent().find('.js-badge-value').text(adjustedRotation)
if (firstRun) {
firstRun = false
$el.css({ transition: 'transform 500ms ease-out' })
}
}
var throttled = _.throttle(tilt, 100)
$badges.each(function () {
var $gyroEl = $(this).find('.js-badge-gyro')
if ($gyroEl.length && window.DeviceOrientationEvent) {
setupGyro($gyroEl)
$gyroEl.on('animationend', function() {
resetGyro($gyroEl)
})
}
})
function setupGyro ($gyroEl) {
$window.on('deviceorientation.gyro', function () {
if (!event.alpha) {
$window.off('deviceorientation.gyro')
return
}
throttled(event.alpha, $gyroEl)
})
}
function resetGyro ($el) {
$window.off('deviceorientation.gyro')
$(this).css({ transform: '' })
console.log('Animation finished')
}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
//
// SETUP
//
$color--red = #ee4432
$color--white = #fff
//
// PROGRESS BADGE
// Contains badge and starburst
//
.progress-badge
position relative
display inline-block
//
// BADGE
//
$badge-fill-duration = 2000ms
$badge-wave-duration = 1000ms
$badge-pop-duration = 300ms
$badge-pop-delay = $badge-fill-duration - 100ms
$badge-full-inner-offset-1 = 5px
$badge-full-inner-offset-2 = 10px
$badge-empty-inner-offset-1 = 7px
$badge-empty-inner-offset-2 = 10px
.badge // Red
position relative
width 150px
height 150px
border-radius 50%
text-align center
display table
vertical-align middle
color $color--white
background $color--red
z-index 2
&:before,
&:after
position absolute
content ''
border-radius 50%
z-index 10
&:before
top $badge-full-inner-offset-1
right $badge-full-inner-offset-1
bottom $badge-full-inner-offset-1
left $badge-full-inner-offset-1
border 2px dotted $color--white
&:after
top $badge-full-inner-offset-2
right $badge-full-inner-offset-2
bottom $badge-full-inner-offset-2
left $badge-full-inner-offset-2
border 2px solid $color--white
.badge__content
display table-cell
vertical-align middle
.badge__content-inner
position relative
.badge__fill
position absolute
top -1px
right -1px
bottom -1px
left -1px
border-radius 50%
overflow hidden
z-index 0
// Transition set with JS to control Gyro movement
// transition none
.badge--static &:after
content ''
position absolute
top 0
right -50px // Avoid cutting corners off gradient
bottom 0
left -50px // Avoid cutting corners off gradient
background-image linear-gradient(-45deg, transparent 40%, $color--white 40%, $color--white 60%, transparent 60%)
background-repeat no-repeat
z-index 1
opacity 0.3
transform translateX(-150px)
animation badge-shine 700ms 500ms ease-in-out
.badge__fill-inner
position absolute
right 0
bottom -10px // Hides wave off-screen
left 0
top 0
background $color--red
transform translateY(100%)
will-change transform
&:before
content ''
position absolute
left 0
bottom 100%
margin-bottom -2px // Hide aliasing gap
width 400px
height 12px
background-repeat repeat-x
background-image url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDAwcHgiIGhlaWdodD0iMTJweCIgdmlld0JveD0iMCAwIDQwMCAxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNDAwIDEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjRUU0NDMyIiBkPSJNMzUwLDVjMCwwLTI0LTUtNDkuOC01QzI3NC4zLDAsMjUwLDUsMjUwLDVzLTIyLDUtNTAsNXMtNTAtNS01MC01cy0yNC01LTQ5LjgtNUM3NC4zLDAsNTAsNSw1MCw1cy0yMiw1LTUwLDV2Mmg0MDB2LTJDMzcyLDEwLDM1MCw1LDM1MCw1eiIvPjwvc3ZnPg==')
.badge__value
font-size rem(50)
line-height 1
.badge__label
font-size rem(14)
.badge--empty
color $color--red
border 4px solid $color--red
background $color--white
&:before
top $badge-empty-inner-offset-1
right $badge-empty-inner-offset-1
bottom $badge-empty-inner-offset-1
left $badge-empty-inner-offset-1
border 1px dotted $color--red
&:after
top $badge-empty-inner-offset-2
right $badge-empty-inner-offset-2
bottom $badge-empty-inner-offset-2
left $badge-empty-inner-offset-2
border 1px solid $color--red
.badge__fill-inner
transform translateY(50%)
.is-filling-from-empty &:before
animation badge-wave-move $badge-wave-duration linear infinite
@keyframes badge-wave-move
100%
transform translateX(-200px)
@keyframes badge-wave-fill
100%
transform translateY(0)
//
// DEMO STYLES
//
*
box-sizing border-box
body
width 300px
margin 0 auto
padding rem(50) rem(25)
text-align center
font-family 'Oswald', sans-serif
hr
margin rem(30) 0
<link href="https://codepen.io/jackbrewer/pen/zvojNZ" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment