Manager, UX Design & Engineering at Trulia (Zillow)
@sarah_edo : twitter || @sdras : codepen
Smashing Conf, New York, June 2016
Manager, UX Design and Engineering at Trulia (Zillow)
This pen.
CSS/SCSS
GSAP (GreenSock)
React-Motion
Bad transform origin bug on rotation, now solved in Firefox.
More in this CSS-Tricks article.
Chrome
IE
Firefox
Safari (zoomed)
The issue with longer CSS animations:
This pen.
This pen.
Viget did an experiment and found that despite some individual variation, novel loaders as a whole had a higher wait time and lower abandon rate than generic ones
From this CSS-Tricks Article
$quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
$quad-out: cubic-bezier(0.55, 0.085, 0.68, 0.53);
.magnifier circle, .magnifier line, .x-out line {
fill: none;
stroke: #fff;
stroke-linecap: round;
transition: 0.25s all $quad-out;
}
.magnifier {
line {
transition: 0.25s all $quad-out;
transform: rotate(0deg) translateY(0px);
}
circle {
transition: 0.25s all $quad-out;
transform: scale(1);
}
}
$( document ).ready(function() {
$(".main").on("click", function() {
var magLine = $(this).find(".magnifier line"),
mainInput = $(this).find("input");
if ($(this).hasClass("open")) {
$(this).removeClass("open");
magLine.attr("x2", 33.1);
mainInput.val("");
} else {
$(this).addClass("open");
magLine.attr("x2", 300);
mainInput.focus();
}
});
});
This pen.
Ugly storyboards save you time!
This pen.
//button hue
function hued() {
var ch1 = "hsl(+=110%, +=0%, +=0%)",
tl = new TimelineMax({
paused: true
});
tl.add("hu");
tl.to(mult, 1.25, {
fill: ch1
}, "hu");
...
tl.to(body, 1.25, {
backgroundColor: ch1
}, "hu");
return tl;
}
var hue = hued();
This pen.
Plugin for GSAP, very simple code.
TweenMax.staggerFromTo($draw, 4,{ drawSVG:'0' }, { drawSVG: true }, 0.1);
Done with stroke-dasharray and stroke-dashoffset
@keyframes dash {
50% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -274;
}
}
This pen.
This pen.
TweenMax.to($firefly1, 6, {
bezier: {
type:"soft",
values:[{x:10, y:30}, {x:-30, y:20}, {x:-40, y:10},
{x:30, y:20}, {x:10, y:30}],
autoRotate:true
},
ease:Linear.easeNone, repeat:-1}, "start+=3");
function displayVals() {
//get the value from the dropdown
var singleValues = $("#single").val();
//the timeline for the changing animation
tl.to($('.s2'), 1.75, {
rotation: 360,
bezier: {
type: 'thru',
values: bezier,
curviness: singleValues
},
ease: Power1.easeInOut
});
}
displayVals();
This pen.
.container
-(1..3).each do |i|
%div{:class => ['unit', "unit#{i}"]}
.shape
.face.bm
.face.tp
-(1..14).each do |i|
%div{:class => ['face', 'side', "s#{i}"]}
HAML
@mixin colors($max-count, $color-frequency){
$color: 360/$max-count;
@for $i from 1 through $max-count {
.s#{$i} {
background: hsl(90%, ($i - 1)*($color / $color-frequency), 40%);
}
}
}
SASS
var bP = $(".face"),
unit = $(".unit"),
tl = new TimelineLite();
tl.add("start");
tl.staggerFrom(bP, 3, {
cycle:{
backgroundColor:["#00a99d", "#0072bc", "#2e3192"],
y:[1000, -500],
x:[500, -500],
opacity:[0.9, 0.7, 0.5],
rotation: function(i) {
return i * 25
}
},
rotation: 360,
ease:Circ.easeInOut
}, 0.006, "start");
JS
Draggable.create(features, {
edgeResistance: 0.65,
type: "x,y",
throwProps: true,
autoScroll: true
});
This pen.
This pen.
TweenMax.set($("#flowers1, #radio, #burst, #magnolia, #flowers2, #starfish, #berries1, #berries2, #berries3, #skulls, #tv, #glitch, #shadow, #lights"), {
visibility: "visible"
});
// the first scene
function sceneOne() {
var tl = new TimelineMax();
tl.add("start");
tl.staggerFromTo($f1, 0.3, {
scale: 0
}, {
scale: 1,
ease: Back.easeOut
}, 0.05, "start");
...
return tl;
}
var master = new TimelineMax({paused:true});
master.add(sceneOne(), "scene1");
Draggable.create($gear, {
type: "rotation",
bounds: {
minRotation: 0,
maxRotation: 360
},
onDrag: function() {
master.progress((this.rotation)/360 );
}
});
Callbacks:
"this" refers to the Draggable instance itself, so you can easily access its "target" or bounds.
If you prefer event listeners, Draggable dispatches events:
yourDraggable.addEventListener("dragend", yourFunc);
This pen.
Start with this technique from Joe Harrison
This pen.
Compare to using text with photos to illustrate an article.
This pen.
function paintPanda() {
var tl = new TimelineMax();
tl.to(lh, 1, {
scaleY: 1.2,
rotation: -5,
transformOrigin: "50% 0",
ease: Circ.easeOut
}, "paintIt+=1");
...
return tl;
}
//create a timeline but initially pause it so that we can control it via click
var triggerPaint = new TimelineMax({
paused: true
});
...
//this button kicks off the panda painting timeline
$("#button").on("click", function(e) {
e.preventDefault();
triggerPaint.restart();
});
...
TweenMax.to("#start", 1, {morphSVG:{shape:"#end"},
ease:Linear.easeNone});
TweenMax.to("#start", 1, {morphSVG:{shape:"#end",
shapeIndex:"1"}});
This pen.
MorphSVGPlugin.convertToPath("ellipse");
function flame() {
var tl = new TimelineMax();
tl.add("begin");
tl.fromTo(blurNode, 2.5, {
attr: {
stdDeviation: 9
}
}, {
attr: {
stdDeviation: 3
}
}, "begin");
var num = 9;
for (var i = 1; i <= num; i++) {
tl.to(fStable, 1, {
morphSVG: {
shape: "#f" + i
},
opacity: ((Math.random() * 0.7) + 0.7),
ease: Linear.easeNone
}, "begin+=" + i);
}
By Blake Bowen
function solve(data) {
var size = data.length;
var last = size - 4;
var path = "M" + [data[0], data[1]];
for (var i = 0; i < size - 2; i +=2) {
var x0 = i ? data[i - 2] : data[0];
var y0 = i ? data[i - 1] : data[1];
var x1 = data[i + 0];
var y1 = data[i + 1];
var x2 = data[i + 2];
var y2 = data[i + 3];
var x3 = i !== last ? data[i + 4] : x2;
var y3 = i !== last ? data[i + 5] : y2;
var cp1x = (-x0 + 6 * x1 + x2) / 6;
var cp1y = (-y0 + 6 * y1 + y2) / 6;
var cp2x = (x1 + 6 * x2 - x3) / 6;
var cp2y = (y1 + 6 * y2 - y3) / 6;
path += "C" + [cp1x, cp1y, cp2x, cp2y, x2, y2];
}
return path;
}
Article about history in computer science.
var poly = document.querySelector("polyline");
var path = document.querySelector("path");
var points = [
100,350,
200,100,
300,350,
400,150,
500,350,
600,200,
700,350
];
poly.setAttribute("points", points);
path.setAttribute("d", solve(points));
var points = [
100,350,
200,150,
300,350,
400,120,
500,350,
600,180,
700,350
];
var points = [
100,350,
200,100,
300,350,
400,150,
500,350,
600,200,
700,350
];
This pen.
Title and associative aria tags: (WIP)
<svg aria-labelledby="title" id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 765 587">
<title id="title" lang="en">Circle of icons that illustrate Global Warming Solutions</title>
You can also add a title for elements in the SVG DOM
This resource, with support charts.
Also, this article by Dudley Storey.
This pen.
This pen.
var graphic = document.getElementById("graphic");
function moveChart(origin, end) {
$(origin).on("click", function() {
var moveTo = document.getElementById(end);
var s = moveTo.getBBox();
var amt = 75;
newView = "" + (s.x - amt) + " " + (s.y - amt) + " " + (s.width + amt*2) + " " + (s.height + amt*2);
TweenMax.to(graphic, 1.5, {
attr: { viewBox: newView },
ease:Circ.easeOut
});
});
}
moveChart(".start-yes", "variation");
moveChart(".start-no", "delorean");
This pen.
This pen.
Fun. Remember fun?
(I don't work for them and they don't pay me)
SVG Immersion Podcast and Web Animation Weekly
These Slides:
slides.com/sdrasner/smashing-ny