Vue.js SVG Loader
HTML
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<script src="https://rawgit.com/vuejs/vue-router/dev/dist/vue-router.js"></script>
<script src="https://rawgit.com/vuejs/vue-resource/master/dist/vue-resource.js"></script>
<div id="app">
<svg-loader></svg-loader>
</div>
<script type="text/template" id="svg-loader">
<svg class="loader" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="s--circle">
<circle r="10" cx="20" cy="20"></circle>
</symbol>
<g class="g-circles g-circles--v4">
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
<g class="g--circle">
<use xlink:href="#s--circle" class="u--circle" />
</g>
</g>
</svg>
</script>
SCSS
$max: 12;
$angle: 360/$max;
$size: 120px;
$fill: dodgerblue;
.loader {
height: $size;
width: $size;
overflow: visible;
/* border: 1px solid red; */
}
@function transform($item: 1) {
$base: rotate(#{-$angle*$item}deg) translate(5px, 5px);
@return $base;
}
.g--circle {
transform-origin: $size/2 $size/2;
fill: $fill;
animation: opacity 1.2s linear infinite;
@for $item from 1 through $max {
&:nth-child(#{$max}n + #{$item}) {
animation-delay: -#{$item/10}s;
transform: transform($item) scale(.9);
}
}
}
.g-circles--v1 .g--circle {
fill-opacity: 0;
animation-name: opacity;
}
.g-circles--v2 .g--circle {
fill-opacity: 0;
stroke-opacity: 0;
stroke-width: 1;
stroke: yellowgreen;
animation-name: opacity-stroke, colors, colors-stroke;
.u--circle {
//transform: scale(.6) translate(10px,10px);
//transform-origin: 10px 10px;
animation: transform-2 1.2s linear infinite;
}
}
.g-circles--v2 .g--circle {
@for $item from 1 through $max {
&:nth-child(#{$max}n + #{$item}) .u--circle {
animation-delay: -#{$item/10}s;
}
}
}
.g-circles--v3 .g--circle {
fill-opacity: 1;
animation-name: opacity, colors;
}
.g-circles--v4 {
.g--circle {
fill-opacity: 1;
fill: orange;
animation-name: opacity, colors-3;
}
.u--circle {
animation: transform 1.2s linear infinite;
}
}
.g-circles--v4 .g--circle {
@for $item from 1 through $max {
&:nth-child(#{$max}n + #{$item}) .u--circle {
animation-delay: -#{$item/10}s;
}
}
}
@keyframes opacity {
3% {
fill-opacity: 1;
}
75% {
fill-opacity: 0;
}
}
@keyframes opacity-stroke {
10% {
stroke-opacity: 1;
}
85% {
stroke-opacity: 0;
}
}
@keyframes colors {
0% {
fill: yellowgreen;
}
10% {
fill: gold;
}
75% {
fill: crimson;
}
}
@keyframes colors-stroke {
0% {
stroke: yellowgreen;
}
10% {
stroke: gold;
}
75% {
stroke: crimson;
}
}
@keyframes colors-2...
Babel + JSX
Vue.component('svg-loader', {
template: '#svg-loader'
});
new Vue({
el: '#app'
});