Skip to content

Commit

Permalink
Animate css properties
Browse files Browse the repository at this point in the history
  • Loading branch information
Koen Bok committed Mar 12, 2013
1 parent 250cb04 commit 2556b6f
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 38 deletions.
69 changes: 56 additions & 13 deletions build/framer.js
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ require.define("/src/css.coffee",function(require,module,exports,__dirname,__fil
return _STYLESHEET.innerHTML += css; return _STYLESHEET.innerHTML += css;
}; };


exports.addStyle(".uilayer { display: block; visibility: visible; position: absolute; top:auto; right:auto; bottom:auto; left:auto; width:auto; height:auto; overflow: visible; z-index:0; opacity:1; box-sizing: border-box; -webkit-box-sizing: border-box;}.uilayer.textureBacked { -webkit-transform: matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); -webkit-transform-origin: 50% 50% 0%; -webkit-backface-visibility: hidden; -webkit-transform-style: flat;}.uilayer.animated { -webkit-transition-duration: 500ms; -webkit-transition-timing-function: linear; -webkit-transition-delay: 0; -webkit-transition-property: none;}"); exports.addStyle(".uilayer { display: block; visibility: visible; position: absolute; top:auto; right:auto; bottom:auto; left:auto; width:auto; height:auto; overflow: visible; z-index:0; opacity:1; box-sizing: border-box; -webkit-box-sizing: border-box;}.uilayer.textureBacked { -webkit-transform: matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); -webkit-transform-origin: 50% 50% 0%; -webkit-backface-visibility: preserve-3d; -webkit-transform-style: flat;}.uilayer.animated { -webkit-transition-duration: 500ms; -webkit-transition-timing-function: linear; -webkit-transition-delay: 0; -webkit-transition-property: none;}");


}).call(this); }).call(this);


Expand Down Expand Up @@ -1050,7 +1050,7 @@ require.define("/src/views/view.coffee",function(require,module,exports,__dirnam


View.define("opacity", { View.define("opacity", {
get: function() { get: function() {
return this.style.opacity || 1; return parseFloat(this.style.opacity || 1);
}, },
set: function(value) { set: function(value) {
this.style.opacity = value; this.style.opacity = value;
Expand Down Expand Up @@ -3012,7 +3012,13 @@ require.define("/src/animation.coffee",function(require,module,exports,__dirname


Animation.prototype.AnimationProperties = ["view", "curve", "time", "origin", "tolerance", "precision"]; Animation.prototype.AnimationProperties = ["view", "curve", "time", "origin", "tolerance", "precision"];


Animation.prototype.AnimatableProperties = ["x", "y", "z", "scaleX", "scaleY", "scaleZ", "rotateX", "rotateY", "rotateZ"]; Animation.prototype.AnimatableCSSProperties = {
opacity: "",
width: "px",
height: "px"
};

Animation.prototype.AnimatableMatrixProperties = ["x", "y", "z", "scaleX", "scaleY", "scaleZ", "rotateX", "rotateY", "rotateZ"];


function Animation(args) { function Animation(args) {
this.cleanup = __bind(this.cleanup, this); this.cleanup = __bind(this.cleanup, this);
Expand All @@ -3021,7 +3027,7 @@ require.define("/src/animation.coffee",function(require,module,exports,__dirname


this.start = __bind(this.start, this); this.start = __bind(this.start, this);


var k, p, propertiesA, propertiesB, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4; var k, p, propertiesA, propertiesB, v, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
_ref = this.AnimationProperties; _ref = this.AnimationProperties;
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref.length; _i < _len; _i++) {
p = _ref[_i]; p = _ref[_i];
Expand Down Expand Up @@ -3049,7 +3055,7 @@ require.define("/src/animation.coffee",function(require,module,exports,__dirname
} }
this.propertiesA = {}; this.propertiesA = {};
this.propertiesB = {}; this.propertiesB = {};
_ref4 = this.AnimatableProperties; _ref4 = this.AnimatableMatrixProperties;
for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
k = _ref4[_j]; k = _ref4[_j];
this.propertiesA[k] = propertiesA[k]; this.propertiesA[k] = propertiesA[k];
Expand All @@ -3059,17 +3065,37 @@ require.define("/src/animation.coffee",function(require,module,exports,__dirname
this.propertiesB[k] = propertiesA[k]; this.propertiesB[k] = propertiesA[k];
} }
} }
_ref5 = this.AnimatableCSSProperties;
for (k in _ref5) {
v = _ref5[k];
if (propertiesB.hasOwnProperty(k)) {
this.propertiesA[k] = propertiesA[k];
this.propertiesB[k] = propertiesB[k];
}
}
this.keyFrameAnimationCSS = this._css(); this.keyFrameAnimationCSS = this._css();
} }


Animation.prototype.start = function(callback) { Animation.prototype.start = function(callback) {
var finalize, var finalize, k,
_this = this; _this = this;
console.log("Animation.start " + this.animationName);
for (k in this.propertiesA) {
console.log(" ." + k + " " + this.propertiesA[k] + " -> " + this.propertiesB[k]);
}
this.view._currentAnimations.push(this); this.view._currentAnimations.push(this);
css.addStyle(" " + this.keyFrameAnimationCSS + " ." + this.animationName + " { -webkit-animation-duration: " + (this.time / 1000) + "s; -webkit-animation-name: " + this.animationName + "; -webkit-animation-timing-function: linear; -webkit-animation-fill-mode: both; }"); css.addStyle(" " + this.keyFrameAnimationCSS + " ." + this.animationName + " { -webkit-animation-duration: " + (this.time / 1000) + "s; -webkit-animation-name: " + this.animationName + "; -webkit-animation-timing-function: linear; -webkit-animation-fill-mode: both; }");
this.view.addClass(this.animationName); this.view.addClass(this.animationName);
finalize = function() { finalize = function() {
var calculatedStyles, v, _ref;
_this.view._matrix = utils.extend(new Matrix(), _this.propertiesB); _this.view._matrix = utils.extend(new Matrix(), _this.propertiesB);
calculatedStyles = {};
_ref = _this.AnimatableCSSProperties;
for (k in _ref) {
v = _ref[k];
calculatedStyles[k] = _this.propertiesB[k] + v;
}
_this.view.style = calculatedStyles;
if (typeof callback === "function") { if (typeof callback === "function") {
callback(); callback();
} }
Expand All @@ -3079,8 +3105,17 @@ require.define("/src/animation.coffee",function(require,module,exports,__dirname
}; };


Animation.prototype.stop = function() { Animation.prototype.stop = function() {
var calculatedStyles, computedStyles, k, v, _ref;
this.view.style["-webkit-animation-play-state"] = "paused"; this.view.style["-webkit-animation-play-state"] = "paused";
this.view._matrix = this.view._computedMatrix(); this.view._matrix = this.view._computedMatrix();
calculatedStyles = {};
computedStyles = this.view.computedStyles;
_ref = this.AnimatableCSSProperties;
for (k in _ref) {
v = _ref[k];
calculatedStyles[k] = computedStyles;
}
this.view.style = calculatedStyles;
return this.cleanup(); return this.cleanup();
}; };


Expand All @@ -3104,16 +3139,24 @@ require.define("/src/animation.coffee",function(require,module,exports,__dirname
deltas[propertyName] = (this.propertiesB[propertyName] - this.propertiesA[propertyName]) / 100.0; deltas[propertyName] = (this.propertiesB[propertyName] - this.propertiesA[propertyName]) / 100.0;
} }
this.curveValues.map(function(springValue) { this.curveValues.map(function(springValue) {
var m, position, _ref1; var m, position, unit, _i, _len, _ref1, _ref2;
position = stepIncrement * stepDelta; position = stepIncrement * stepDelta;
cssString.push("\t" + (position.toFixed(2)) + "%\t{ -webkit-transform: "); cssString.push("\t" + (position.toFixed(2)) + "%\t{ -webkit-transform: ");
m = new Matrix(); m = new Matrix();
_ref1 = _this.propertiesA; _ref1 = _this.AnimatableMatrixProperties;
for (propertyName in _ref1) { for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
value = _ref1[propertyName]; propertyName = _ref1[_i];
m[propertyName] = springValue * deltas[propertyName] + _this.propertiesA[propertyName]; value = springValue * deltas[propertyName] + _this.propertiesA[propertyName];
m[propertyName] = value;
}
cssString.push(m.matrix().cssValues() + "; ");
_ref2 = _this.AnimatableCSSProperties;
for (propertyName in _ref2) {
unit = _ref2[propertyName];
value = springValue * deltas[propertyName] + _this.propertiesA[propertyName];
cssString.push("" + propertyName + ":" + (value.toFixed(5)) + unit + "; ");
} }
cssString.push(m.matrix().cssValues() + "; }\n"); cssString.push("}\n");
return stepIncrement++; return stepIncrement++;
}); });
cssString.push("}\n"); cssString.push("}\n");
Expand Down
61 changes: 50 additions & 11 deletions src/animation.coffee
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ parseCurve = (a, prefix) ->
class Animation extends EventEmitter class Animation extends EventEmitter


AnimationProperties: ["view", "curve", "time", "origin", "tolerance", "precision"] AnimationProperties: ["view", "curve", "time", "origin", "tolerance", "precision"]
AnimatableProperties: [ AnimatableCSSProperties: {
opacity: "",
width: "px",
height: "px",
}
AnimatableMatrixProperties: [
"x", "y", "z", "x", "y", "z",
"scaleX", "scaleY", "scaleZ", #"scale", "scaleX", "scaleY", "scaleZ", # "scale",
"rotateX", "rotateY", "rotateZ", #"rotate" "rotateX", "rotateY", "rotateZ", # "rotate"
] # width, height, opacity ] # width, height, opacity


constructor: (args) -> constructor: (args) ->
Expand Down Expand Up @@ -65,7 +70,10 @@ class Animation extends EventEmitter
@propertiesA = {} @propertiesA = {}
@propertiesB = {} @propertiesB = {}


for k in @AnimatableProperties
# Build up the matrix animation properties

for k in @AnimatableMatrixProperties


@propertiesA[k] = propertiesA[k] @propertiesA[k] = propertiesA[k]


Expand All @@ -74,15 +82,25 @@ class Animation extends EventEmitter
else else
@propertiesB[k] = propertiesA[k] @propertiesB[k] = propertiesA[k]


# console.log "#{k} #{@propertiesA[k]} -> #{@propertiesB[k]}" # Build up the css animation properties

for k, v of @AnimatableCSSProperties

if propertiesB.hasOwnProperty k
@propertiesA[k] = propertiesA[k]
@propertiesB[k] = propertiesB[k]



@keyFrameAnimationCSS = @_css() @keyFrameAnimationCSS = @_css()


# console.log @keyFrameAnimationCSS # console.log @keyFrameAnimationCSS


start: (callback) => start: (callback) =>


# console.log "Animation.start #{@animationName}" console.log "Animation.start #{@animationName}"

for k of @propertiesA
console.log " .#{k} #{@propertiesA[k]} -> #{@propertiesB[k]}"


# We stop all other animations on this view. Maybe we should revisit # We stop all other animations on this view. Maybe we should revisit
# this or give an option to disable it, but for now it makes sens because 1) # this or give an option to disable it, but for now it makes sens because 1)
Expand All @@ -101,16 +119,22 @@ class Animation extends EventEmitter
-webkit-animation-name: #{@animationName}; -webkit-animation-name: #{@animationName};
-webkit-animation-timing-function: linear; -webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: both; -webkit-animation-fill-mode: both;
}" }"


@view.addClass @animationName @view.addClass @animationName


finalize = => finalize = =>

# Copy over the end state properties for this animation so we can safely # Copy over the end state properties for this animation so we can safely
# remove the animation. # remove the animation.
@view._matrix = utils.extend new Matrix(), @propertiesB @view._matrix = utils.extend new Matrix(), @propertiesB


# Copy over the end state css properties
calculatedStyles = {}
for k, v of @AnimatableCSSProperties
calculatedStyles[k] = @propertiesB[k] + v
@view.style = calculatedStyles

callback?() callback?()
@cleanup() @cleanup()


Expand All @@ -124,6 +148,13 @@ class Animation extends EventEmitter
# we can safely remove it without the element jumping around. # we can safely remove it without the element jumping around.
@view._matrix = @view._computedMatrix() @view._matrix = @view._computedMatrix()


# Copy over the end state css properties
calculatedStyles = {}
computedStyles = @view.computedStyles
for k, v of @AnimatableCSSProperties
calculatedStyles[k] = computedStyles
@view.style = calculatedStyles

@cleanup() @cleanup()


cleanup: => cleanup: =>
Expand Down Expand Up @@ -155,16 +186,24 @@ class Animation extends EventEmitter


cssString.push "\t#{position.toFixed(2)}%\t{ -webkit-transform: " cssString.push "\t#{position.toFixed(2)}%\t{ -webkit-transform: "


# Add the matrix based values

m = new Matrix() m = new Matrix()


for propertyName, value of @propertiesA for propertyName in @AnimatableMatrixProperties
m[propertyName] = springValue * deltas[propertyName] + @propertiesA[propertyName] value = springValue * deltas[propertyName] + @propertiesA[propertyName]
m[propertyName] = value

cssString.push m.matrix().cssValues() + "; "

for propertyName, unit of @AnimatableCSSProperties
value = springValue * deltas[propertyName] + @propertiesA[propertyName]
cssString.push "#{propertyName}:#{value.toFixed 5}#{unit}; "


cssString.push m.matrix().cssValues() + "; }\n" cssString.push "}\n"


stepIncrement++ stepIncrement++



cssString.push "}\n" cssString.push "}\n"


return cssString.join "" return cssString.join ""
Expand Down
2 changes: 1 addition & 1 deletion src/views/view.coffee
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ class View extends Frame


@define "opacity" @define "opacity"
get: -> get: ->
@style.opacity or 1 parseFloat @style.opacity or 1
set: (value) -> set: (value) ->
@style.opacity = value @style.opacity = value
@style["opacity"] = value @style["opacity"] = value
Expand Down
Loading

0 comments on commit 2556b6f

Please sign in to comment.