Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save ja-k-e/1c412b480b8425d1b499 to your computer and use it in GitHub Desktop.

Select an option

Save ja-k-e/1c412b480b8425d1b499 to your computer and use it in GitHub Desktop.
GIF Recreation 1: CSS SVG Priddy Circle Thing

GIF Recreation 1: CSS SVG Priddy Circle Thing

Faking motion blur with stroke-dasharray.

Colors off in Safari because of filter.

Recreation of this gif from FLRN

FLRN's gif

A Pen by Jake Albaugh on CodePen.

License.

// circles to generate
- var _count = 6
// svg viewbox to set our rotation center for us
svg(
class='svg',
width='400', height='400',
viewBox='-200 -200 400 400'
)
// defining a blur for reference in our CSS
defs
// centering filter at twice scale to avoid hard edges
filter(id='blur',x='-50%',y='-50%',width='200%',height='200%')
//feGaussianBlur(in='SourceGraphic', stdDeviation="0.5")
feConvolveMatrix(order='3',kernelMatrix='0 1 0 1 0 1 0 1 0')
// creating our circles via a loop
- var i = 0
while i <= _count
// radius more or less matches gif
- var radius = (18.5 * (_count - i))
circle(r=radius)
- i++
// reference image from flrn
img(
class='img',
src='http://31.media.tumblr.com/bfaece2581639138ca5fa4958363bb89/tumblr_nmeogmm5KX1tcuj64o1_400.gif',
title='Original Image')
// circles to generate
- var _count = 6
// svg viewbox to set our rotation center for us
svg(
class='svg',
width='400', height='400',
viewBox='-200 -200 400 400'
)
// defining a blur for reference in our CSS
defs
// centering filter at twice scale to avoid hard edges
filter(id='blur',x='-50%',y='-50%',width='200%',height='200%')
//feGaussianBlur(in='SourceGraphic', stdDeviation="0.5")
feConvolveMatrix(order='3',kernelMatrix='0 1 0 1 0 1 0 1 0')
// creating our circles via a loop
- var i = 0
while i <= _count
// radius more or less matches gif
- var radius = (18.5 * (_count - i))
circle(r=radius)
- i++
// reference image from flrn
img(
class='img',
src='http://31.media.tumblr.com/bfaece2581639138ca5fa4958363bb89/tumblr_nmeogmm5KX1tcuj64o1_400.gif',
title='Original Image')
// props to the most-perfect @thebabydino for the tips :)
// colors array
$colors: (
0: #10a0ab,
1: #f03e32,
2: #ffae00
);
// pi cause we dont need compass for a single value
$pi: 3.141592653;
// difference in size
$size-increment: 2 * 18.5; // should be two times radius value in jade loop
// how many circles
$count: 6;
// timing in ms
$duration: 3000ms;
// width of circle strokes
$stroke-width: 9;
// empty diameters list
$diameters: ();
// creating our list of diameters
@for $i from 1 through $count {
$diameter: $size-increment * ($count - $i) + $size-increment;
$diameters: append($diameters, $diameter);
}
// limiting our svg scope using a class
.svg {
// centering our svg on the page
position: fixed;
top: 50%; left: 50%;
transform: translate3d(-50%, -50%, 0);
// circle elements
circle {
fill: none;
stroke: black;
stroke-width: $stroke-width;
filter: url(#blur); // lightens color in safari ??
// for each diameter
@each $di in $diameters {
// get position in diameters list
$i: index($diameters,$di);
// calculating circumference
$circ: $pi * $di;
// space before completion = 20%
$offset: $circ * 0.2;
// each circle
&:nth-of-type(#{$i}) {
// stroke color selection from colors map
stroke: map-get($colors, $i % 3);
// position-specific animation
animation:
line-#{$i} $duration linear infinite,
rotation-#{$i} $duration linear infinite;
// setting delays to handle out-of-sync.
// when loop is at FIRST half, previous loop is at ZERO
// when loop is 1/4 finished, previous loop is 2/4 finished
// delay should equal 1/4
// working this shit out
$half_duration: $duration / 2;
$quarter_duration: $half_duration / 2;
// initial delay = 0
// second delay = 1/2 + 1/4
animation-delay: ($i - 1) * ($half_duration + $quarter_duration);
// initial nothingness
stroke-dasharray: 0,$circ;
stroke-dashoffset: 0;
}
//
// fake blurs by adding tiny scaled dasharrays ||||
//
// initial ones, more added the bigger the diameter
$micro-array: ();
// initial zeroes for animation to recognize them even if they dont visually exist
$micro-array-zeroes: ();
// amount of micro dashes to generate
$dash-count: $count - $i + 1;
// relative to diameter scale, append additional dashes
@for $d from 1 through $dash-count {
$dash-size: 3 * (1 - $d/$dash-count);
$dash-size: 1;
$micro-array: append($micro-array,($dash-size,1),comma);
$micro-array-zeroes: append($micro-array-zeroes,(0,0),comma);
}
// line animations
@keyframes line-#{$i} {
0% {
stroke-dasharray:
// zeroes before line at start
$micro-array-zeroes,
// line at zero at start
0,
// zeroes after line at start
$micro-array-zeroes,
// circumference space at start = no line
$circ;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray:
// micro dash array before line at midpoint
$micro-array,
// almost complete circle at midpoint
$circ - $offset,
// micro dash array after segment to achieve motion blur
$micro-array,
// offset spacing for incomplete circle at midpoint
$offset;
stroke-dashoffset: 0;
}
100% {
stroke-dasharray:
// micro dash array before line at end
$micro-array-zeroes,
// line complete at end (dashoffset moves it invisible)
$circ + $offset,
// zeroes for previous array to animate to
$micro-array-zeroes,
// circumference space at end = no line
$circ;
// dash offset pushes dashes out of visibility
stroke-dashoffset: -$circ - length($micro-array);
}
}
// moving each rotation starting point up 60 degrees
$rotate-offset: (360/6 * ($i - 1));
@keyframes rotation-#{$i} {
from { transform: rotate($rotate-offset * 1deg) }
to { transform: rotate($rotate-offset + 360deg) }
}
}
}
}
//
// global stuff
//
body { background-color: #262626; }
// example gif in bottom left
.img {
position: fixed;
left: 0; bottom: 0;
width: 15%;
// below centers on screen to scale
//left: 50%; top: 50%;
//transform: translate(-50%, -50%);
//width: 400px;
height: auto;
//opacity: 0.5;
z-index: -1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment