console
var $badges = $('.js-progress-badge')
, $window = $(window)
, windowOrientation = window.orientation
, firstRun = true
window.addEventListener('orientationchange', function() {
windowOrientation = window.orientation
console.log('orientation change')
}, false);
function tilt (rotation, $el) {
if (rotation === null) return
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')
}
<h2>Gyro filling</h2>
<div class="progress-badge js-progress-badge is-filling is-filling-from-empty">
<div class="badge badge--empty">
<div class="badge__fill js-badge-gyro">
<div class="badge__fill-inner"></div>
</div>
<div class="badge__content">
<div class="badge__content-inner">
<div class="badge__value"><span class="js-badge-value" data-target="5">0</span></div>
<div class="badge__label">Action here</div>
</div>
</div>
</div>
</div>
.grid {
margin-left: -20px;
}
.grid__item {
padding-left: 20px;
box-sizing: border-box;
vertical-align: top;
display: inline-block;
width: 100%;
}
.grid--reverse {
direction: rtl;
text-align: right;
}
.grid--reverse > .grid__item {
direction: ltr;
text-align: left;
}
.one-whole {
width: 100%;
}
.one-half {
width: 50%;
}
.one-third {
width: 33.3333%;
}
.two-thirds {
width: 66.6667%;
}
.one-quarter {
width: 25%;
}
.two-quarters {
width: 50%;
}
.three-quarters {
width: 75%;
}
.one-fifth {
width: 20%;
}
.two-fifths {
width: 40%;
}
.three-fifths {
width: 60%;
}
.four-fifths {
width: 80%;
}
.one-sixth {
width: 16.6667%;
}
.two-sixths {
width: 33.3333%;
}
.three-sixths {
width: 50%;
}
.four-sixths {
width: 66.6667%;
}
.five-sixths {
width: 83.3333%;
}
@media screen and (max-width: 599px) {
.mobile-one-whole {
width: 100%;
}
.mobile-one-half {
width: 50%;
}
.mobile-one-third {
width: 33.3333%;
}
.mobile-two-thirds {
width: 66.6667%;
}
.mobile-one-quarter {
width: 25%;
}
.mobile-two-quarters {
width: 50%;
}
.mobile-three-quarters {
width: 75%;
}
.mobile-one-fifth {
width: 20%;
}
.mobile-two-fifths {
width: 40%;
}
.mobile-three-fifths {
width: 60%;
}
.mobile-four-fifths {
width: 80%;
}
.mobile-one-sixth {
width: 16.6667%;
}
.mobile-two-sixths {
width: 33.3333%;
}
.mobile-three-sixths {
width: 50%;
}
.mobile-four-sixths {
width: 66.6667%;
}
.mobile-five-sixths {
width: 83.3333%;
}
}
@media screen and (min-width: 600px) {
.tablet-one-whole {
width: 100%;
}
.tablet-one-half {
width: 50%;
}
.tablet-one-third {
width: 33.3333%;
}
.tablet-two-thirds {
width: 66.6667%;
}
.tablet-one-quarter {
width: 25%;
}
.tablet-two-quarters {
width: 50%;
}
.tablet-three-quarters {
width: 75%;
}
.tablet-one-fifth {
width: 20%;
}
.tablet-two-fifths {
width: 40%;
}
.tablet-three-fifths {
width: 60%;
}
.tablet-four-fifths {
width: 80%;
}
.tablet-one-sixth {
width: 16.6667%;
}
.tablet-two-sixths {
width: 33.3333%;
}
.tablet-three-sixths {
width: 50%;
}
.tablet-four-sixths {
width: 66.6667%;
}
.tablet-five-sixths {
width: 83.3333%;
}
}
@media screen and (min-width: 900px) {
.desktop-one-whole {
width: 100%;
}
.desktop-one-half {
width: 50%;
}
.desktop-one-third {
width: 33.3333%;
}
.desktop-two-thirds {
width: 66.6667%;
}
.desktop-one-quarter {
width: 25%;
}
.desktop-two-quarters {
width: 50%;
}
.desktop-three-quarters {
width: 75%;
}
.desktop-one-fifth {
width: 20%;
}
.desktop-two-fifths {
width: 40%;
}
.desktop-three-fifths {
width: 60%;
}
.desktop-four-fifths {
width: 80%;
}
.desktop-one-sixth {
width: 16.6667%;
}
.desktop-two-sixths {
width: 33.3333%;
}
.desktop-three-sixths {
width: 50%;
}
.desktop-four-sixths {
width: 66.6667%;
}
.desktop-five-sixths {
width: 83.3333%;
}
}
.progress-badge {
position: relative;
display: inline-block;
}
.badge {
position: relative;
width: 150px;
height: 150px;
border-radius: 50%;
text-align: center;
display: table;
vertical-align: middle;
color: #fff;
background: #ee4432;
z-index: 2;
}
.badge:before,
.badge:after {
position: absolute;
content: '';
border-radius: 50%;
z-index: 10;
}
.badge:before {
top: 5px;
right: 5px;
bottom: 5px;
left: 5px;
border: 2px dotted #fff;
}
.badge:after {
top: 10px;
right: 10px;
bottom: 10px;
left: 10px;
border: 2px solid #fff;
}
.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;
}
.badge--static .badge__fill:after {
content: '';
position: absolute;
top: 0;
right: -50px;
bottom: 0;
left: -50px;
background-image: -webkit-linear-gradient(135deg, transparent 40%, #fff 40%, #fff 60%, transparent 60%);
background-image: linear-gradient(-45deg, transparent 40%, #fff 40%, #fff 60%, transparent 60%);
background-repeat: no-repeat;
z-index: 1;
opacity: 0.3;
-webkit-transform: translateX(-150px);
transform: translateX(-150px);
-webkit-animation: badge-shine 700ms 500ms ease-in-out;
animation: badge-shine 700ms 500ms ease-in-out;
}
.badge__fill-inner {
position: absolute;
right: 0;
bottom: -10px;
left: 0;
top: 0;
background: #ee4432;
-webkit-transform: translateY(100%);
transform: translateY(100%);
will-change: transform;
}
.badge__fill-inner:before {
content: '';
position: absolute;
left: 0;
bottom: 100%;
margin-bottom: -2px;
width: 400px;
height: 12px;
background-repeat: repeat-x;
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iNDAwcHgiIGhlaWdodD0iMTJweCIgdmlld0JveD0iMCAwIDQwMCAxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNDAwIDEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjRUU0NDMyIiBkPSJNMzUwLDVjMCwwLTI0LTUtNDkuOC01QzI3NC4zLDAsMjUwLDUsMjUwLDVzLTIyLDUtNTAsNXMtNTAtNS01MC01cy0yNC01LTQ5LjgtNUM3NC4zLDAsNTAsNSw1MCw1cy0yMiw1LTUwLDV2Mmg0MDB2LTJDMzcyLDEwLDM1MCw1LDM1MCw1eiIvPjwvc3ZnPg==");
}
.badge__value {
font-size: 3.125rem;
line-height: 1;
}
.badge__label {
font-size: 0.875rem;
}
.badge--empty {
color: #ee4432;
border: 4px solid #ee4432;
background: #fff;
}
.badge--empty:before {
top: 7px;
right: 7px;
bottom: 7px;
left: 7px;
border: 1px dotted #ee4432;
}
.badge--empty:after {
top: 10px;
right: 10px;
bottom: 10px;
left: 10px;
border: 1px solid #ee4432;
}
.badge--empty .badge__fill-inner {
-webkit-transform: translateY(50%);
transform: translateY(50%);
}
.is-filling-from-empty .badge--empty .badge__fill-inner:before {
-webkit-animation: badge-wave-move 1000ms linear infinite;
animation: badge-wave-move 1000ms linear infinite;
}
* {
box-sizing: border-box;
}
body {
width: 300px;
margin: 0 auto;
padding: 3.125rem 1.563rem;
text-align: center;
font-family: 'Oswald', sans-serif;
}
hr {
margin: 1.875rem 0;
}
@-webkit-keyframes badge-wave-move {
100% {
-webkit-transform: translateX(-200px);
transform: translateX(-200px);
}
}
@keyframes badge-wave-move {
100% {
-webkit-transform: translateX(-200px);
transform: translateX(-200px);
}
}
@-webkit-keyframes badge-wave-fill {
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}
@keyframes badge-wave-fill {
100% {
-webkit-transform: translateY(0);
transform: translateY(0);
}
}