Skip to content

Commit 9a4ad12

Browse files
committed
wip: example(1.x/animation): add reusable animated component
Closes angular#47
1 parent a3102cd commit 9a4ad12

22 files changed

+3434
-0
lines changed
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
# Snap.js
2+
A Library for creating beautiful mobile shelfs in Javascript
3+
4+
<a href="http://www.screenr.com/embed/0EJ7" target="_blank">View Video Preview</a>
5+
6+
<a href="http://jakiestfu.github.io/Snap.js/" target="_blank">View Demos</a>
7+
8+
<a href="http://www.screenr.com/embed/0EJ7" target="_blank"><img src="http://i.imgur.com/t3mGcEx.gif"></a>
9+
10+
* [Features](#features)
11+
* [Support](#support)
12+
* [Installation](#installation)
13+
* [Usage](#usage)
14+
* [Settings &amp; Defaults](#settings-and-defaults)
15+
* [Public Methods](#public-methods)
16+
* [Gotchas](#gotchas)
17+
* [FAQ's](#faq)
18+
* [Compliments](#compliments)
19+
* [Licensing](#licensing)
20+
* [Extras](#extras)
21+
22+
## Features
23+
* Library Independent
24+
* High Customization
25+
* Flick Support
26+
* User Intent Detection
27+
* Disable Hyperextension
28+
* Event Hooks
29+
* CSS3 Powered Animations with IE fallbacks
30+
* Drag Support
31+
* Drag Handle Support
32+
* Programatic API
33+
* "No-Drag" Elements
34+
* Definable Easing Mode
35+
* Enable/Disable Events
36+
* Disabled Sides (left or right)
37+
* Supports [Ratchet](http://maker.github.com/ratchet/) (with templates!)
38+
39+
## Support
40+
* Firefox 10+
41+
* Wide Webkit Support (including Android WebKit 2.3.X)
42+
* IE 10
43+
* IE 9 Supports Toggling, Dragging but no Transitions
44+
* IE 7/8 Supports Toggling but no dragging or Transitions
45+
46+
## Installation
47+
48+
As standalone just include the file in a script tag:
49+
50+
```html
51+
<script src="snap.js"></script>
52+
```
53+
54+
As a <a href="http://component.io" target="_blank">web component</a> do:
55+
56+
```shell
57+
$ component install jakiestfu/Snap.js
58+
```
59+
60+
## Usage
61+
62+
```javascript
63+
var snapper = new Snap({
64+
element: document.getElementById('content')
65+
});
66+
```
67+
68+
## Settings and Defaults
69+
```javascript
70+
settings = {
71+
element: null,
72+
dragger: null,
73+
disable: 'none',
74+
addBodyClasses: true,
75+
hyperextensible: true,
76+
resistance: 0.5,
77+
flickThreshold: 50,
78+
transitionSpeed: 0.3,
79+
easing: 'ease',
80+
maxPosition: 266,
81+
minPosition: -266,
82+
tapToClose: true,
83+
touchToDrag: true,
84+
slideIntent: 40,
85+
minDragDistance: 5
86+
}
87+
```
88+
89+
* `element`: The element which the user will be sliding side to side
90+
* `dragger`: The element which the user will be using to slide the target element side to side
91+
* `disable`: String, set to 'left' or 'right' to disable the respective side
92+
* `addBodyClasses`: Add classes to the body to signify which side is being opened
93+
* `hyperextensible`: If false, pane may not be slide past the minPosition and maxPosition
94+
* `resistance`: The cooeficcient used to slow sliding when user has passed max or min threshold
95+
* `flickThreshold`: Number of pixels the user needs to swiftly travel to activate a "flick" open
96+
* `transitionSpeed`: The speed at which the pane slides open or closed
97+
* `easing`: The CSS3 Easing method you want to use for transitions
98+
* `maxPosition`: Maximum number of pixels the pane may be slid to the right
99+
* `minPosition`: Maximum number of pixels the pane may be slid to the left
100+
* `tapToClose`: If true, tapping an open pane will close it
101+
* `touchToDrag`: If true, dragging the target `settings.element` will open/close the pane
102+
* `minDragDistance`: The minimum amount of pixels the user needs to drag within the `slideIntent` degrees to move the pane
103+
* `slideIntent`: The number of degrees the user must initiate sliding in towards the left or right (see diagram below)
104+
105+
Notes on Slide Intent: The slide intent is an int between 0 and 90, and represents the degrees in the first quadrant of a circle that you would like to have mirrored on the X *and* Y axis. For example, if you have 40 set as your `slideIntent` value, the user would only be able to slide the pane by dragging in the blue area in the diagram below. Once intent has been defined, it will not change until the user releases.
106+
107+
<img src="http://i.imgur.com/uG2CNR8.png">
108+
109+
110+
## Public Methods
111+
112+
### `open`: Opens the pane to the specified side
113+
114+
```javascript
115+
snapper.open('left');
116+
// OR
117+
snapper.open('right');
118+
```
119+
120+
### `close`: Closes the pane
121+
122+
```javascript
123+
snapper.close();
124+
```
125+
126+
### `expand`: Opens the pane entirely
127+
128+
```javascript
129+
snapper.expand('left');
130+
// OR
131+
snapper.expand('right');
132+
```
133+
134+
### `disable`: Disables sliding events
135+
136+
```javascript
137+
snapper.disable();
138+
```
139+
140+
### `enable`: Enables sliding events after disabling
141+
142+
```javascript
143+
snapper.enable();
144+
```
145+
146+
### `on`: Adds an event hook
147+
148+
```javascript
149+
snapper.on('start', function(){
150+
// Do Something
151+
});
152+
```
153+
The available methods to hook into are as follows:
154+
155+
* `start`: Fired when touching down on the draggable pane and it begins to move
156+
* `drag`: Fired when the pane has been moved or slid
157+
* `end`: Fired when the pane has been let go of
158+
* `animating`: Fired when the pane is animating
159+
* `animated`: Fired when the pane is finished it's animations
160+
* `ignore`: Fired when trying to drag the pane but ended up dragging on an ignored element
161+
* `close`: Fired when close is called directly or if tapToClose is set to true
162+
* `open`: Fired when the menu is opened
163+
* `expandLeft`: Fired on expand('left')
164+
* `expandRight`: Fired on expand('right')
165+
* `enable`: Fired on enable
166+
* `disable`: Fired on disable
167+
168+
### `off`: Removes an event hook
169+
170+
```javascript
171+
snapper.off('drag');
172+
```
173+
The event names listed above apply for the `off` method.
174+
175+
176+
### `settings`: Updates the settings for an already instantiated object
177+
```javascript
178+
snapper.settings({yourSettings});
179+
```
180+
Currently, `settings.element`, `settings.touchToDrag` cannot be updated. To update the element, instantiate a new object. To allow listening to a drag, use `snapper.enable()`
181+
182+
### `state`: Returns detailed information about the state of the pane
183+
184+
```javascript
185+
var data = snapper.state();
186+
```
187+
The data returned from the `state` method will look like the following:
188+
189+
```javascript
190+
{
191+
state: "closed", // State of the Pane
192+
info:{
193+
opening: "left", // Side which user intends to open
194+
towards: "right", // Direction user is dragging towards
195+
hyperExtending: false, // True if user is pulling past predefined bounds
196+
halfway: false, // True if pane is at least halfway open
197+
flick: false, // True if user has moved pane X amount of pixels in the open/close direction without changing directions
198+
translation:{
199+
absolute: 20, // Pixels pane has translated
200+
relative: 21, // Pixels pane has translated relative to starting translation
201+
sinceDirectionChange: 10, // Pixels pane has translated since the direction of the pane has changed
202+
percentage: 40.571649 // The percentage that the Pane is open. Good or animating other things
203+
}
204+
}
205+
}
206+
```
207+
208+
## Gotchas
209+
210+
### Layout
211+
The layout itself is what most people will have a hard time emulating, so the simplest approach I have found is as follows:
212+
213+
Two absolute elements, one to represent *all* the content, and another to represent *all* the drawers. The content has a higher z-index than the drawers. Within the drawers element, it's direct children should represent the containers for the drawers, these should be `fixed` or `absolute`. Assigning classes to your drawers to specify which side it is on is recommended. All absolutely positioned elements should have 0 for `top, left, right, bottom` properties, excluding your panes which will have `auto` set to their respective sides and a width assigned. The width of your drawers is usually the same number you want to use for `minPosition` and `maxPosition`
214+
215+
```html
216+
div.drawers {position: absolute;}
217+
div.left-drawer {position: absolute;}
218+
[content]
219+
div.right-drawer {position: absolute;}
220+
[content]
221+
div#content {position: absolute;}
222+
[top-bars]
223+
[content] {overflow: auto}
224+
[bottom-bars]
225+
```
226+
227+
A sample layout is found in demo/apps/default.html.
228+
229+
### Independent Scrolling
230+
Some CSS is required to get some smooth ass scrolling. Utilize the CSS below to apply this to any of your elements:
231+
```css
232+
.scrollable{
233+
overflow: auto;
234+
-webkit-transition-property: top, bottom;
235+
transition-property: top, bottom;
236+
-webkit-transition-duration: .2s, .2s;
237+
transition-duration: .2s, .2s;
238+
-webkit-transition-timing-function: linear, linear;
239+
transition-timing-function: linear, linear;
240+
-webkit-overflow-scrolling: touch;
241+
}
242+
```
243+
244+
### Z-Indeces and Display
245+
Because of the nature of this code, drawers are just kind of stacked behind the content. To bring the proper drawer to the front, you can hook into Snaps.js' CSS classes:
246+
247+
With `addBodyClasses` set to `true` in your initialize options, one of the two classess will be added to the body tag: `.snapjs-left` or `.snapjs-right`, depending on which pane is being open, respectively. This being said, you can apply your CSS like the following to show the proper drawers:
248+
249+
```css
250+
.snapjs-right .left-drawer,
251+
.snapjs-left .right-drawer {
252+
display: none;
253+
}
254+
```
255+
256+
## FAQ
257+
258+
### - How do I make a toggle button?
259+
Toggles have been a popular request, but rather than bog the library down with additional methods, you can utilize the powerful API of Snap.js to create your own toggle. Toggles can be done like the following:
260+
261+
```javascript
262+
myToggleButton.addEventListener('click', function(){
263+
264+
if( snapper.state().state=="left" ){
265+
snapper.close();
266+
} else {
267+
snapper.open('left');
268+
}
269+
270+
});
271+
```
272+
273+
### - How do I disable Snap.js dragging for my touch slider?
274+
Snap.js supports cascading cancellation of events via a data attribute `data-snap-ignore`. If you were to use a slider, your markup might look like the following:
275+
276+
```html
277+
<div class="slider" data-snap-ignore="true">
278+
<ul>
279+
<li><img src="slide.jpg"></li>
280+
<li><img src="slide.jpg"></li>
281+
<li><img src="slide.jpg"></li>
282+
<li><img src="slide.jpg"></li>
283+
<li><img src="slide.jpg"></li>
284+
</ul>
285+
</div>
286+
```
287+
288+
All interactions on children elements of the element with the `data-snap-ignore` attribute will have their Snap.js events ignored.
289+
290+
291+
### - I am using Push.js from Ratchet, I keep losing my events on my elements, how can I fix this?
292+
Simple. As wack as Push.js is (yes, it is in desperate need of attention as of v1.0.0), we can still solve this problem with it's only callback, `'push'`.
293+
294+
```javascript
295+
// The function that will initialize your Snap.js instance
296+
var doSnap = function(){
297+
if(window.snapper){
298+
// Snap.js already exists, we just need to re-bind events
299+
window.snapper.enable();
300+
} else {
301+
// Initialize Snap.js
302+
window.snapper = new Snap({
303+
element: document.getElementById('content')
304+
});
305+
}
306+
};
307+
308+
window.addEventListener('push', doSnap);
309+
doSnap();
310+
```
311+
312+
### - Snap.js works on my Android device but i cannot scroll the content in my drawers, what gives?
313+
Older Android devices (and iPhone as well) do not have native support for overflow scrolling. To solve this, you may use the wonderful library called [iScroll](https://github.com/cubiq/iscroll)
314+
315+
### - `transform: translate3d()` breaks my fixed child elements, how can I solve this?
316+
[This is a problem with Chromium](https://code.google.com/p/chromium/issues/detail?id=20574) and should be fixed soon. I would advise not having your direct children element set to fixed, that may possibly solve your problem.
317+
318+
### - I am experiencing a weird flicker when the CSS transform is applied
319+
To solve the flicker, apply the following CSS to the element in question
320+
```css
321+
#content{
322+
backface-visibility:hidden;
323+
-webkit-backface-visibility:hidden; /* Chrome and Safari */
324+
-moz-backface-visibility:hidden; /* Firefox */
325+
-ms-backface-visibility:hidden; /* Internet Explorer 10+ */
326+
}
327+
```
328+
329+
## Compliments
330+
331+
This code attempts to make your webapp's feel more "native". These other repos go well with it, too!
332+
333+
* [Snap.js](https://github.com/jakiestfu/Snap.js)
334+
* [AppScroll.js](https://github.com/jakiestfu/AppScroll)
335+
* [fastclick](https://github.com/ftlabs/fastclick)
336+
337+
## Licensing
338+
339+
MIT, dawg

examples/angular-1/animation/components/routable-panel/demo/apps/classNames.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!DOCTYPE HTML><html lang="en-US"> <head> <title>Snap.js</title> <meta http-equiv="x-ua-compatible" content="IE=edge" /> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-touch-fullscreen" content="yes"> <link rel="stylesheet" type="text/css" href="../../snap.css" /> <link rel="stylesheet" type="text/css" href="../assets/demo.css" /> </head> <body> <div class="snap-drawers"> <div class="snap-drawer snap-drawer-left"> <div> <h3>Snap.js</h3> <div class="demo-social"> <a href="https://twitter.com/share" class="twitter-share-button" data-lang="en" data-text="Snap.js - A Library for creating beautiful mobile shelfs in Javascript" data-url="http://jakiestfu.github.com/Snap.js/" data-count="none" data-via="jakiestfu">Tweet</a> <a href="https://twitter.com/jakiestfu" class="twitter-follow-button" data-show-count="false" data-lang="en">Follow @jakiestfu</a> <iframe src="http://ghbtns.com/github-btn.html?user=jakiestfu&amp;repo=Snap.js&amp;type=watch&amp;count=true" allowtransparency="true" frameborder="0" scrolling="0" width="120" height="20"></iframe> </div> <h4>Demos</h4> <ul> <li><a href="default.html">Default</a></li> <li><a href="noDrag.html">No Drag</a></li> <li><a href="dragElement.html">Drag Element</a></li> <li><a href="rightDisabled.html">Right Disabled</a></li> <li><a href="hyperextend.html">Hyperextension Disabled</a></li> <li><a href="skinnyThreshold.html">Skinny Threshold</a></li> <li><a href="toggles.html">Toggles</a></li> <li><a href="classNames.html">Class Names</a></li> <li><a href="expand.html">Expanding</a></li> <li><a href="settings.html">Settings</a></li> <li><a href="ratchet/template.html">Ratchet</a></li> </ul> <div> <p>The class names demo shows how you can utilize the classess added by Snap.js to adjust hidden content. In this case, we're showing the same menu on both sides of the app via CSS and classess.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla non erat ac leo ultrices blandit sed vel risus. Pellentesque facilisis blandit auctor. Maecenas vestibulum vulputate tincidunt. Mauris nec quam libero. Fusce eget ligula non leo varius condimentum quis ac elit. Donec id urna ut neque semper ultrices. Proin ut suscipit felis. Nullam neque felis, ullamcorper scelerisque volutpat vel, vehicula vehicula neque. Aenean scelerisque elit ac erat sagittis ullamcorper.</p> </div> </div> </div> <div class="snap-drawer snap-drawer-right"></div> </div> <div id="content" class="snap-content" style="opacity:0.8;"> <div id="toolbar"> <a href="#" id="open-left"></a> <h1>Class Names</h1> </div> </div> <script type="text/javascript" src="../../snap.js"></script> <script type="text/javascript"> var snapper = new Snap({ element: document.getElementById('content') }); </script> <script type="text/javascript" src="../assets/demo.js"></script> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script> </body></html>

0 commit comments

Comments
 (0)