jmpressjs / jmpress.js

A jQuery plugin to build a website on the infinite canvas
http://jmpressjs.github.com/jmpress.js
1.5k stars 237 forks source link

Transition, timing curves and animation customization possibilities #116

Closed micsanbr closed 11 years ago

micsanbr commented 11 years ago

Hi, I'm porting a few projects from prezi to jmpress (which looks a lot more stable and reliable than prezi).

The only problem I can't solve is related to css transition timing functions (linear, ease, cubic-bezier, etc.), which seem to be quite limited in terms of look and feel.

For example, in one project I have a large size slide step, followed by a microscopic scaled slide step, and they have with different positions. During this transition the camera moves between the two interpolating correctly, but the end result is a disorienting fly-through, because the camera gets too close to the large slide step, trying to reach the scale of the microscopic one,

It would be awesome to be able to manipulate directly how the camera interpolates between two slides. I have no idea how prezi does that. It would be also helpful to be able to control separately the transition for scaling and translation.

Could you please recommend some way to hack this using what's currently available within the library, perhaps there's already a workaround for this?

shama commented 11 years ago

Check out custom animations: http://jmpressjs.github.io/docs/animation.html

It's all done with CSS3 transitions. Here are some example CSS animations: https://github.com/jmpressjs/jmpress.js/tree/master/src/css/animations/basic

If you want more control, check out this site: http://easings.net/ Look at the bottom where it gives you the CSS way to achieve the easing. This is also a good site for generating CSS transition curves: http://www.roblaplaca.com/examples/bezierBuilder/

micsanbr commented 11 years ago

Hi Shama, thanks a lot for the fast reply.

I've already read about custom animations, but i was referring to the animation between slides ... the mechanism that interpolates the camera position between one slide step and the next one.

The easings website would be perfect if it could be possible to use such curves to drive said interpolation.

shama commented 11 years ago

Oh try the animation property: http://jmpressjs.github.io/docs/core.html

$('#jmpress').jmpress({
    animation: {
        transitionTimingFunction: 'cubic-bezier(.10, .10, .25, .90)'
    },
});
micsanbr commented 11 years ago

Hi Shama, the timing function is exactly what I'm using right now, coupled with custom transition durations for each step in js. The transition looks dizzy and too fast (compared to its prezi counterpart) between two slide steps with extremely different scales and positions, for example:

It just zooms out too slow and translates too fast (in this case). Can you perhaps suggest how I can hack jmpressjs to have the scale TimingFunction separated from the translation TimingFunction?

sokra commented 11 years ago

Translation and Scaling happen already on different elements. Unfortunately they both use the same arguments (animation option). Only the inital delay is different.

You should be able to override the css on the elements:

$(xyz).jmpress("applyTarget", function( active, eventData ) {
  if (eventData.beforeActive) { // Except the page loading
    $.jmpress("css", eventData.area, {
      transitionDuration: "500ms"
    }); // Scaling
    $.jmpress("css", eventData.canvas, {
      transitionDuration: "2s"
    }); // Transition
  }
});
// Untested
micsanbr commented 11 years ago

Man ... thanks a million. I'm working right now on it and your suggestion got me in the right direction finally. Inside applyTarget I'm now using the same duration for both S and T, but i'm using different interpolation timing functions, which is starting to look exactly how it should be! It's still quite difficult to visualize in my head how a cubic bezier of .0, 1, .0, 1 (applied to the area) would interact with a cubic-bezier of 1, 0, .58, 1 (applied to canvas), but that's definitely the right way to create a smooth transition without cheating with delays or stuff like that. Thanks a lot!

micsanbr commented 11 years ago

Hi again, still about animation customization ... is there any way to use css3 keyframe animations or some system to override the standard css3 transitions with path? for example: GSAP - www.greensock.com/gsap-js

sokra commented 11 years ago

hi, I don't know an easy way to do this. They could theoretically be applied to the camera or to steps, but I havn't tried yet.

You could add invisible auto-advancing slides between steps to simulate something like this. (Like here between slide 3 and 4)

micsanbr commented 11 years ago

Hi Sokra, I was thinking something like that too, but is there anyway to just disable the css 3d transform transition? Cause then I could perhaps animate camera and canvas via javascript ...

sokra commented 11 years ago

You should be able to disable it with:

$(..).jmpress({
  animation: {
    transitionProperty: ""
  }
});

Or extract only some transformations from the camera to apply them by animation:

$.jmpress("beforeInit", function( element, eventData ) {
  // additional layer of styling
  var animationCanvas = $('<div />');
  var canvas = $(this).jmpress("canvas");
  canvas.children().each(function() {
    animationCanvas.append( $( this ) );
  });
  canvas.append(animationCanvas);
});

$.jmpress("setActive", function( element, eventData ) {
  // extract some transforms
  var target = eventData.target;
  var transform = target.transform;
  target.transformByAnimation = transform.splice(...);
});

$.jmpress("applyTarget", function( active, eventData ) {
  // apply the extracted transforms as animation
  var target = eventData.target;
  var canvas = eventData.canvas;
  var animationCanvas = canvas.children();
  var transformByAnimation = target.transformByAnimation
  magicApplyTransformByAnimation(animationCanvas, transformByAnimation);
});
micsanbr commented 11 years ago

Hi Sokra thanks again. Unfortunately transitionProperty: "" seems to have no effect and beforeInit seem to never fire

sokra commented 11 years ago

http://jsfiddle.net/ZWsSv/

here is a start for building it....

micsanbr commented 11 years ago

Hi again, and thanks a lot for the example and hints.

After a lot more tweaking I hacked together a few tests, building on the fly (during applyTarget) a set of animation keyframes for transforms and css animation rules with various interpolation methods (lerp, cosLerp, cubic, etc).

Animation interpolation behavior still makes no sense on desktop browser (it's bumpy between keyframes, perhaps I was applying to the wrong target, or something in jmpressjs was compensating those motions).

Anyway I'm now back to css transitions cause found out that css animations are not gpu accelerated on tablets (ipad).

I cannot upload the presentations I'm working on (yet) so I've found a prezi example (made by someone) else to explain visually the problem: http://prezi.com/5_auptg6wjic/prezi-example Is there a way to replicate in jmpressjs the interpolation you see between slide 15 and 16? It looks like it's zooming out a bit, and the timing function seems to drive the scaling and position on a path rather than using a straight linear interpolation.

micsanbr commented 11 years ago

Another thought, perhaps it's possible to drive animations using jquery's animate coupled with a bezier path animation? http://jqbezier.ericlesch.com/

sokra commented 11 years ago

Here is the prezi animation: http://jsfiddle.net/qYdkU/

regarding jQuery.Path: I don't know, could work.

micsanbr commented 11 years ago

Thanks a ton: it's exactly what I'm after. I guess in my case the problem is that the scaling values are extremely different. If instead of section data-y="500" data-x="1000" data-scale="0.5" you had section data-y="500" data-x="1000" data-scale="0.05" Would it still be possible to somehow create a smooth transition with that method?

sokra commented 11 years ago

should be possible... You may need to fit the timings and scaling to your needs.

micsanbr commented 11 years ago

again thanks a lot for your help, I managed to solve the problem with a lot more timing fine-tuning.

your trick works great for some transitions but ONLY when the scaling is not extremely different, due to the behavior of timing functions: for some weird reason certain cubic-bezier timing functions work fine on ipad1 and stutter heavily on chrome (windows).

The trick still doesn't solve extreme scenarios like this one (taken from this presentation I'm on, full of this extreme zoom-in zoom-outs), like in the following jsfiddle: http://jsfiddle.net/KEHS6/6/