npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

can-stache-animate

v0.1.0

Published

Animations for can-stache

Downloads

2

Readme

can-stache-animate

Build Status

Animations for can-stache

Basic Usage

In your stache template, use can-import to pull can-stache-animate into the template. Then bind to a property or event, and provide the desired animation.

<can-import from="can-stache-animate" {^value.animations}="*animations" />
<div (. shake)="*animations.shake"></div>

Note: The * syntax is necessary to use the can-import tag to pull a value into the scope.

Note: Use {^value.animations} to get the animations object, and set that to a variable (*animations) in the scope.

Use your own animations

To create your own custom animations, create a file (we'll call it custom-animations.js), and import can-stache-animate. Use the registerAnimation and registerAnimations methods to register your animations.

import $ from 'jquery';
import canStacheAnimate from 'can-stache-animate';

//sets the global duration
canStacheAnimate.setDuration(600);

//register single animation
canStacheAnimate.registerAnimation("myCustomAnimation",function(el, ev, options){
	$(el).animate({
		/* ... */	
	});
});

/* OR */

//register multiple animations
canStacheAnimate.registerAnimations({
	myCustomAnimation:function(el, ev, options){
		$(el).animate({
			/* ... */	
		});
	},
	/* ...other animations... */
});

export default canStacheAnimate;

Then import your custom file instead of can-stache-animate.

<can-import from="my-project/custom-animations" {^value.animations}="*animations" />
<div (. shake)="*animations.myCustomAnimation"></div>

Anatomy of an animation

Animations can be a string, a function, or an object. Let's take a look at how the different types work.

Object

If an animation is an object, it is expected to have the properties:

Object.run - function - required

The run method is the core animation method and is required.

Object.before - function - optional

The before method is called prior to the run method. It is typically used to 'set the stage' for the animation – setting the position or z-index css properties of a parent element, for example.

Object.after - function - optional

The after method is called when the run method has completed. It is typically used to clean up any css properties or state from the element that were only needed for the animation itself and are no longer needed - resetting the position or z-index css properties of a parent element, for example.

Each of these methods receives the following parameters:

element - the element on which the animation is being used
event - the event that triggered the animation
options - a set of options such as duration

If any of these methods contain asynchronous functionalty, they should return a Promise.

Example:

canStacheAnimate.registerAnimation("myCustomShakeAnimation",{
	before: function(vm, el, ev){
		var $el = $(el);
		$el.parent().css({
			"position":"relative"
		})
		$el.css({
			"position":"absolute"
		})
	},
	run: function(vm, el, ev){
	 var $el = $(el);
	 return $el.animate({
	 	"left":"-100px"
	 }).promise().then(function(){
	 	return $el.animate({
	 		"left":"100px"
	 	}).promise().then(function(){
	 		return $el.animate({
	 			"left": "0px"
	 		}).promise();
	 	})
	 }).promise()
	},
	after: function(vm, el, ev){
		var $el = $(el);
		$el.parent().css({
			"position":""
		})
		$el.css({
			"position":""
		})
	}
});

Note: Returning false from either the before or run methods will stop further animations from being executed.

Note: When adding animations to the before, run, after methods, there is no need to us an onComplete (or similar) callback function. Simply return a Promise, ans resolve it when any async functionality has completed.

Note: For jQuery animations, you can simply use the .promise() method.

Object.stop - function - optional

The stop method is called when any one of the before, run, or after methods returns either false or a Promise that rejects. It is used to revert any changes that were made during the animation so that the element can be set back to its "ground state".

Example:

	canStacheAnimate.registerAnimation("myCustomHopAnimation",{
		duration: 1000,
		before: function(el, ev, options){
			return new Promise(function(resolve, reject){
				$(el).animate({
					"margin-top":"-20px"
				}, options.duration).promise().then(function(){
					resolve();
				});

				//when there is a click in the window,
				//reject this promise which will cause
				//the stop method to be called
				$(window).one('click', function(){
					reject();
				});
			});
		},
		run: function(el, ev, options){
			return $(el).animate({
				"margin-top":"0px"
			}, 400).promise();
		},
		stop: function(el, ev, options){
			$(el).stop().animate({
				"margin-top": 0
			}, options.duration);
		}
	});

Function

If an animation is a function, it is the same as providing that function as an object's run property and providing null to the before and after properties.

Example:

canStacheAnimate.registerAnimation("myCustomAnimation",function(el, ev, options){
	$(el).animate({
		"opacity": 0.5
	})
});

String

If an animation is a string, it is simply set up as an alias to an animation that has already been registered.

Example:

canStacheAnimate.registerAnimation("myCustomAnimation":"fadeIn");

Note: "Already registered animations" include the out-of-the-box animations provided by can-stache-animate.

Strings as animation steps

In addition to a registered animation value being a string identifier of another animation, before, run, and after animation properties can be string identifiers of other animations as well. This is useful to chain animations together or provide modifications to things like duration for an existing animation.

canStacheAnimate.registerAnimations({

	"customFadeIn": function(el, ev, options){
		return $(el).animate({
			opacity: 0.8
		}, options.duration).promise();
	},
	"customFadeOut": function(el, ev, options){
		return $(el).animate({
			opacity: 0.2
		}, options.duration).promise();
	},

	"customPulse":{
		before: "customFadeOut",
		run: "customFadeIn"
	},

	"customPulseFast":{
		duration: 100,
		run: "customPulse"
	}
});

Animation events

Sometimes it is useful to know when an animation has started or finished a particular phase. We can accomplish this easily with can-util/dom/dispatch.

Example: Register an custom animation, and dispatch events on the element:

var domDispatch = require('can-util/dom/dispatch/dispatch');
canStacheAnimate.registerAnimation("myCustomAnimation", {
	before: function(el, ev, options){
	  domDispatch.apply(el, ["mycustomanimationbefore", [{test: "foo"}], false]);
		$(el).hide().css({
			"opacity": 0
		})
	},
	run: function(el, ev, options){
		domDispatch.apply(el, ["mycustomanimationrunning", [{test: "foo"}], false]);
		$(el).show().animate({
			"opacity": 0
		})
	},
	after: function(el, ev, options){
		domDispatch.apply(el, ["mycustomanimationcomplete", [{test: "foo"}], false]);
	}
});

Listen for those events via stache:

<div
 (. animate)="*animationsModule.default.animations.myCustomAnimation"
 ($mycustomanimationbefore)="handleAnimationBefore"
 ($mycustomanimationrunning)="handleAnimationRunning"
 ($mycustomanimationcomplete)="handleAnimationComplete"
  />

Then handle the events from within the scope or viewmodel:

DefineMap.extend({
	handleAnimationBefore(vm, el, ev){
		console.log("handleAnimationBefore");
	},
	handleAnimationRunning(vm, el, ev){
		console.log("handleAnimationRunning");
	},
	handleAnimationComplete(vm, el, ev){
		console.log("handleAnimationAfter");
	}
})

Special event handling

Some events require additional setup.

$inserted

When importing animations with can-import, elements' $inserted events will fire before the imported animations make it into the scope.

Wait for the animations to be in the scope before rendering the elements like this:

<can-import from="can-stache-animate" {^value.animations}="*animations" />
{{#*animations}}
	<div style="display:none;" ($inserted)="*animations.fadeIn" />
{{/*animations}}

Note: Set the element's style initially to display:none; because the *animations.fadeIn helper expects the element to not be displayed.

$beforeremove

It is sometimes useful to perform an animation on an element prior to its being removed from the DOM. can-stache-animate provides a $beforeremove event that can be used to accomplish this. Here's how it works:

dispatch-async

The $beforeremove event is an async event which means that it has some additional methods that can be used during the event's lifetime.

The most important of these methods are:

event.pause()

Delay the execution of the event's default behavior until event.resume() is called. In the case above, pausing the $beforeremove event would delay execution of the $remove event.

event.resume()

Continue executing the event's default behavior

event.cancel()

Prevent the event's default behavior similar to .preventDefault() in standard events.

Writing the animation for $beforeremove

Here is an example of how to use the async event to write a beforeremove animation:

canStacheAnimate.registerAnimation('customFadeOut', {
	before: function(el, ev, options){

		// cancel the event under specified circumstances
		if($(el).is(".cancel")){
			ev.cancel();

			// return false to stop the remaining animation methods from running 
			// (`run` and `after`)
			return false;
		}

		// the event wasn't cancelled, pause it until our animation is done
		ev.pause();
	},

	run: function(el, ev, options){
		return $(el).fadeOut().promise()
	},

	after: function(el, ev, options){
		// the animation has completed, so we can continue with the default behavior
		ev.resume();
	}
});

Use Stache for adding/removing elements

For example, conditionally render an element based on a scope property:

{{#if showElement}}
	<div ($beforeremove)="*animations.customFadeOut" />
{{/if}}

can-stache-animate-jquery

can-stache-animate provides a jQuery extension for a bit of extra functionality. It adds the ability to provide an object for each of the before, run, and after methods of an animation.

Providing an object

Provide an object to an animation property, and it will be treated as a css object. For before and after, $.fn.css will be used, and for run, $.fn.animate will be used.

Example:

var canStacheAnimate = require('can-stache-animate/can-stache-animate-jquery');
canStacheAnimate.registerAnimation('blueRed', {

	//background will be set to blue via $.fn.css
	before:{
		"background-color": "blue"
	},

	//blue will be animated to red
	run: {
		"background-color": "red"
	},
	after:{
		"background-color": ""
	}
})