GithubHelp home page GithubHelp logo

just-animate / just-animate Goto Github PK

View Code? Open in Web Editor NEW
264.0 9.0 19.0 7.13 MB

Making Animation Simple

Home Page: https://just-animate.github.io/

JavaScript 4.03% TypeScript 95.97%
animation typescript web-animation waapi transitions animation-controller multiple-animations easings timeline css-variables

just-animate's People

Contributors

notoriousb1t avatar notoriousbot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

just-animate's Issues

Add transform compositing for property syntax

Add a transform compositing strategy field and default it to add and could be changed to replace. For example:

just.animate({
     to: '2s', 
     targets: '.element',
     css: {
         transformComposite: 'add',
         rotate: [0, '90deg', '360deg'],
         x: [0, '40px']
     }
})

'add' would translate to

just.animate({
     to: '2s', 
     targets: '.element',
     css: [
         { transform: 'translatex(0) rotate(0)' },
         { transform: 'translatex(20px) rotate(90deg)' },
         { transform: 'translatex(40px) rotate(360deg)' }
     }
})

Whereas with 'replace', it would translate to

just.animate({
     to: '2s', 
     targets: '.element',
     css: [
         { transform: 'translatex(0) rotate(0)' },
         { transform: 'rotate(90deg)' },
         { transform: 'translatex(40px) rotate(360deg)' }
     }
})

Alternatively, the commands could be reduced to 4x4 or 3x3 matrices and combined that way. In that scenario, waapi would always be sent matrix or matrix3d

Add target and targets to onupdate context

just.animate({
    to: 2000,
    targets: '.target'
    onupdate(ctx) {
         ctx.target; // provides target that is being updated
         ctx.targets; // provides full list of targets from "targets"
    }
})

Add NativeScript support

NativeScript has great integration with Angular2. The animation api for NativeScript is different than Web Animations API but should be compatible enough to bridge for their subset of properties:

https://docs.nativescript.org/ui/animation.html

view.animate({
    translate: { x: 0, y: 100},    
    duration: 1000,
    curve: enums.AnimationCurve.easeIn
});

Some obvious items are:

  • bridging JustAnimate.animate() => view.animate()
  • adding animation curve definitions like nativescript and backporting existing easings
  • creating property maps between NativeScript properties and web animation properties
    translateX: 5 => tranform: ''translateX(5)"
    • updating existing animations to use the shorthand versions
    • detecting if the environment is NativeScript if possible and switching to that provider or providing an alternate version to import e.g.: import { JustAnimateNS } from 'just-animate';

cssVar() helper

It is helpful in some situations to access the current value of a CSS Variable. Rather than adding this into the code, I propose we add the following property value helper:

function cssVar(name) {
   return t => getComputedStyle(t).getPropertyValue(name)
}


// then usage
import { cssVar } from 'just-animate/extras'

strokeDashoffset: [cssVar('--targaryen-head'), 0]

This is a simple implementation, we may want to do additional work to reduce using getComputedStyle when this is used in multiple places.

Stagger on Interpolation

Hello,

I'm using just animate combined with polymorph to animate a svg object. The animation looks good, but it seems that the stagger property is not being set, the animation runs without stoping between the path sequences.

  var shape = just.animate({
    targets: '#shape14_target',
    duration: 40000,
    stagger: 2500,
    props: {
      d: {
        interpolate: svgMorph,
        easing: 'easeInOut',
        value: [
              '#shape14_state1 path',
              '#shape14_state2 path',
              '#shape14_state3 path',
              '#shape14_state4 path',
              '#shape14_state3 path',
              '#shape14_state2 path',
              '#shape14_state1 path'
            ]
      }
    }
  })

  shape.play('Infinity');

Allow '1.2s' and '+=200ms' notation on delays

Add support for delays as a time string

// basic support
just.animate({
    targets: '.target',
    mixins: ['fadeIn'],
    delay: '1.2s'
})

// staggered time
just.animate({
    targets: '.target',
    mixins: ['fadeIn'],
    delay: '+=100ms'
})

Add "references" feature to support devtools

The "refs" feature is going to allow a person to swap out parts of the timeline quickly by defining those parts as refs at initialization.

Proposed usage:

var t1 = just.timeline({
    refs: {
        target: pixiObj
    }
})

t1.add({
     targets: '@target',
    /* ... */
})

At first glance, it seems like targets will always have to be evaluated immediately because of stagger.

CSS Properties don't mixin properly

just.register({
    name: 'fadeIn',
    css: {
          opacity: [0, 1]
    }
});

just.register({
    name: 'slideIn',
    css: {
        x: ['-200px', 0]
    }
});


just.animate({
      mixins: ['fadeIn', 'slideIn']
});

// should be
just.animate({
    css: [
         { opacity: 0. transform: 'translatex(-200px)' },
         { opacity: 1. transform: 'translatex(0)' },
    ]
})

It takes the first mixin and disregards the css properties on subsequent mixins

Add element provider function to .animate()

Add the ability to use a function instead of an element in .animate(). The function will be called when the element is needed. This will support more sophisticated use cases and will work nicely with arrow functions:

Just.animate(function() {
  return document.getElementById('some-element');
});
Just.animate(() => document.getElementById('some-element'));

Using in Web Components (animating inside Shadow DOM)

Fantastic library! Thanks for all your work.

Iโ€™m just getting started with just-animate, so I might be missing something obvious โ€“ how can I use this within a web component shadow DOM?

Iโ€™m building a web component using Stencil, and Iโ€™d like to bake in some animations using just-animate. When I build the component, just-animate is clearly working properly (including the awesome player widget), but Iโ€™m not able to target elements inside the Shadow DOM. (Other matching targets outside of the component animate as expected.)

Anyone tried using just-animate in a Stencil web component? How can I get just-animate to target nodes inside the element?

Overload .play(iterations) to provide infinite repeating of a timeline

Since there isn't opportunity to provide playback options for the timeline as a whole, Allow the user to provide options when calling play

MAYBE

just.animate({
      to: '1s',
      targets: '.element',
      mixin: 'fadeIn'
})
.play(Infinity);

OR

just.animate({
    to: '1s',
    targets: '.element',
    mixin: 'fadeIn'
})
.play({
    direction: 'alternate',
    iterations: 2
});

Add sequence function to support chaining together multiple animations

Add the ability to chain animations together in sequence.

Just.sequence(function(builder) {
    return builder
        .fadeIn(el)
        .wait(3000)
        .fadeOut(el)
        .fadeIn(el2)
        .wait(1000)
        .fadeOut(el2);
});
Just.sequence(builder => builder
        .fadeIn(el)
        .wait(3000)
        .fadeOut(el)
        .fadeIn(el2)
        .wait(1000)
        .fadeOut(el2));

Animation option builder in Just.animate()

Allow a function to be passed to Just.animate() to build the animation options instead of using an object for the keyframes and then an object for the timings.

Possible function based approach:

function rotateIt(e) {
    return e.from({ rotateX: '0' })
            .at(0.5, { rotateX: '90deg' })
            .to({ rotateX: '0' });
}

var timing = { duration: 1000, fill: 'none' };
var player = Just.animate(rotateIt, $element, timing);

Current object based approach

var rotateIt = [
    { offset: 0, rotateX: '0' },
    { offset: 0.5, rotateX: '90deg' },
    { offset: 1, rotateX: '0' }
];

var timing = { duration: 1000, fill: 'none' };
var player = Just.animate(rotateIt, $element, timing);

selectPath() helper

When doing SVG morphs with Flubber, getting the path data required extra code that made the experience not as great as it could have been. I propose the following helper to make it easier to select path data:

function selectPath(selector) {
   return () => {
        const el = document.querySelector(selector)
        if (el == null) {
            return '' // or throw error
        }
        return el.getAttribute('d')
   }
}


// then usage
import { selectPath } from 'just-animate/extras'

var t1 = just.animate({
    targets: '#my-target',
    duration: 1000,
    props: { 
        d: [selectPath('#charmander'), selectPath('#charmeleon')] 
    }
})

Invalid calling object IE11

Invalid calling object in this output code

    function isFunction(a) {
        return toString.call(a) === functionTypeString;
    }

Switch Object.prototype.toString to ({}).toString and test

Revisit and modify API

Need to revisit the API contracts. Because of how the signatures evolved, there are situations where the user's code would be hard to read and there are missed opportunities to create a simple experience. I think for the 1.0.0 release, the API should be overhauled to address some of the issues

  • Allow keyframes to accept properties with value arrays (and let JustAnimate figure out the actual keyframes)
  • Change call order of Just.animate() to be more in line with other animation libraries
  • Prep for transition support (when the ending properties are provided and the starting properties are taken from the target)
  • Remove animateSequence and bake it into JustAnimate as an additional .animate() function
  • Flatten timings calls into the options above them
  • add time notation to duration ("2s" instead of 2000 (ms))
  • add "at" property of timings that uses actual time instead of offset. offset will be calculated based on the duration added to and from properties to express duration. In simple cases to is equivelant to existing uses of duration, but makes sense with a timeline
  • rebuild timeline api to be simpler
  • detect initial values from dom when an option is passed

Before

// registration
Just.register({
  name: 'rainbow',
  keyframes: [
    { 'background-color': 'white' },
    { 'background-color': 'red' },
    { 'background-color': 'orange' },
    { 'background-color': 'yellow' },
    { 'background-color': 'green' },
    { 'background-color': 'blue' },
    { 'background-color': 'indigo' },
    { 'background-color': 'violet' }
  ], 
  timings: { 
    duration: 5000, 
    fill: 'both',
    iterations: 1
  }
});

// call registered animation
Just.animate('rainbow', '#target2');

// call registered animation with overrides
Just.animate('rainbow', '#target2', { duration: 1000 });

// call inline animation
var keyframes = [
  { opacity: 0 },
  { opacity: 0.4, offset: 0.2 },
  { opacity: 1 },
];

var timings = {
  duration: 2000,
  fill: 'forwards',
  easing: 'ease-out'
}
Just.animate(keyframes, '#target3', timings);

// animate a sequence
Just.animateSequence({
    steps: [
      { 
        el: '#target1',
        name: 'fadeIn'
      },
      { 
        el: '#target2',
        name: 'fadeOut'
      }
    ],
    autoplay: true
});

// call timeline
Just.animateTimeline({
    autoplay: true,
    duration: 5000,
    events: [
        {
            offset: 0,
            el: '#target1', 
            keyframes: [
                { translateX: 0 },
                { translateX: '-700px' }
            ],
            timings: {
                duration: 4200,
                fill: 'both',
                easing: 'ease-in'
            }
        },
        {
            offset: 0.1,
            el: '#target2', 
            name: 'rubberBand',
            timings: {
                iterations: 1
            }
        }
    ]
});

After

// register animation/transition
Just.register({
  name: 'rainbow',
  duration: 5000, 
  fill: 'both',
  properties: {
    backgroundColor: ['white', 'red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
  }
});

// call registered animation/transition
Just.animate('#target2', 'rainbow');

// call registered animation/transition with overrides
Just.animate('#target2', {
  name: 'rainbow',
  duration: "1s"
});

// call inline animation/transition
Just.animate('#target3', {
  keyframes: [
    { opacity: 0 }, 
    { opacity: 0.4, at: '400ms' }, 
    { opacity: 1 }
  ],
  duration: "2s",
  fill: 'forwards',
  easing: 'ease-out'
});

// animate a sequence
Just.animate('#target1', 'fadeIn')
  .animate('#target2', 'fadeOut');

// call timeline
Just.timeline({
    autoplay: true,
    duration: '5s',
    events: [
        { 
           target: '#target1',
           from: 0,
           to: '4.2s'
           fill: 'both',
           easing: 'ease-in'
           properties: {
              translateX: [0, '-700px']
           }
        },
        { 
           target: '#target2',
           from: '500ms',
           name: 'rubberBand',
           iterations: 1
        }
    ]
});

Add onIteration hook

just.animate({
  targets: '.confetti',
  onIteration: function (ctx) {
     // log current iteration
     console.log(ctx.iteration);
  }
  /* ... */
})

should have the same behavior as

just.animate({
  targets: '.confetti'
  /* ... */
}).on('iteration', function (ctx) {
   // log current iteration
   console.log(ctx.iteration);
})

Change just.random behavior

Make the following changes to just.random()

  • add a third optional argument for unit. If a unit is null or undefined, return a number. If unit is not null or undefined, return a string with that unit as a suffix
  • add a fourth optional argument that is true if the result should have floor applied. It should default to false

error: rotateZ must be a property

Remove keyframe properties with undefined/null/empty strings. If a keyframe has a property that doesn't have a value, it should be ignored.

Add create hook

Provide a create hook for modifying the target prior to starting the animation.

Before:

just.animate({
  targets: function () {
    var confetti = document.querySelectorAll('.confetti')
    for (var i = 0, len = confetti.length; i < len; ++i) {
      confetti[i].innerHTML = '<div class="rotate"><div class="askew"></div></div>'
    }
    return confetti
  },
  /* ... */
})

After

just.animate({
  targets: '.confetti',
  on: {
    create(target, index, targets) {
      target.innerHTML = '<div class="rotate"><div class="askew"></div></div>'
    }
  }
/* ... */
});

Add support for Animation Sheets

Support the ability to play animations on a timeline. Possible usage:

var player = Just.animateSheet({
    duration: 3000,
    events: [
        {
            offset: 0,
            name: 'fadeIn',
            el: '.target',
        },
        {
            offset: 0.3,
            name: 'fadeOut',
            el: '.target'
        },
        {
            offset: 0.6,
            name: 'fadeIn',
            el: '.target2',
        },
    ]
});

Over the course of 3000ms:

  • At 0%, elements with class target will fade in
  • At 30%, elements with class target will fade out
  • Ad 60%, elements with class target2 will fade in

Player returns an IAnimation, so it supports play, reverse, cancel, etc. like all other animations.

If a subanimation's duration is past the duration of the sheet, the animation will cancel at the end. If the player calls reverse, the subanimation will start from the point it would have been canceled.

Add transitions

Just Animate can animate when specifying the start and end states of the elements. I think a way to transition from wherever an element currently is to a new state would add a lot of value. Problems to solve:

  • standalone transitions, perhaps make .animate() more forgiving when missing properties
  • transitions in sequences (maybe a way to fold transitions into the sequencer or a promise chain)
  • transitions in timelines (maybe provide additional logic and prefill keyframes based on expected state of the element at that point of the animation

Possible Simple transition to

Just.transition({
     el: '#element',
     timings: { duration: 1000 },
     to: { translateX: '100%'  }
});

Possible chaining transitions to create sequences

Just.transition({
        el: '#element',
        timings: { duration: 1000 },
        to: { translateX: '100%' , skewX: '20deg' } 
    })
    .wait(250)
    .transition({
        el: '#element',
        timings: { duration: 1000 },
        to: { translateX: '0'  } 
     });

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.