forked from shachaf/jsgif
-
Notifications
You must be signed in to change notification settings - Fork 286
/
rubbable.js
151 lines (118 loc) · 5.24 KB
/
rubbable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*
RubbableGif
Example usage:
<img src="./example1_preview.gif" rel:animated_src="./example1.gif" width="360" height="360" rel:auto_play="1" />
<script type="text/javascript">
$$('img').each(function (img_tag) {
if (/.*\.gif/.test(img_tag.src)) {
var rub = new RubbableGif({ gif: img_tag } );
rub.load();
}
});
</script>
Image tag attributes:
rel:animated_src - If this url is specified, it's loaded into the player instead of src.
This allows a preview frame to be shown until animated gif data is streamed into the canvas
rel:auto_play - Defaults to 1 if not specified. If set to zero, the gif will be rubbable but will not
animate unless the user is rubbing it.
Constructor options args
gif Required. The DOM element of an img tag.
auto_play Optional. Same as the rel:auto_play attribute above, this arg overrides the img tag info.
max_width Optional. Scale images over max_width down to max_width. Helpful with mobile.
Instance methods
// loading
load( callback ) Loads the gif into a canvas element and then calls callback if one is passed
// play controls
play - Start playing the gif
pause - Stop playing the gif
move_to(i) - Move to frame i of the gif
move_relative(i) - Move i frames ahead (or behind if i < 0)
// getters
get_canvas The canvas element that the gif is playing in.
get_playing Whether or not the gif is currently playing
get_loading Whether or not the gif has finished loading/parsing
get_auto_play Whether or not the gif is set to play automatically
get_length The number of frames in the gif
get_current_frame The index of the currently displayed frame of the gif
For additional customization (viewport inside iframe) these params may be passed:
c_w, c_h - width and height of canvas
vp_t, vp_l, vp_ w, vp_h - top, left, width and height of the viewport
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['./libgif'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('./libgif'));
} else {
root.RubbableGif = factory(root.SuperGif);
}
}(this, function (SuperGif) {
var RubbableGif = function( options ) {
var sup = new SuperGif( options );
var register_canvas_handers = function () {
var isvp = function(x) {
return (options.vp_l ? ( x - options.vp_l ) : x );
}
var canvas = sup.get_canvas();
var maxTime = 1000,
// allow movement if < 1000 ms (1 sec)
w = ( options.vp_w ? options.vp_w : canvas.width ),
maxDistance = Math.floor(w / (sup.get_length() * 2)),
// swipe movement of 50 pixels triggers the swipe
startX = 0,
startTime = 0;
var cantouch = "ontouchend" in document;
var aj = 0;
var last_played = 0;
canvas.addEventListener((cantouch) ? 'touchstart' : 'mousedown', function (e) {
// prevent image drag (Firefox)
e.preventDefault();
if (sup.get_auto_play()) sup.pause();
var pos = (e.touches && e.touches.length > 0) ? e.touches[0] : e;
var x = (pos.layerX > 0) ? isvp(pos.layerX) : w / 2;
var progress = x / w;
sup.move_to( Math.floor(progress * (sup.get_length() - 1)) );
startTime = e.timeStamp;
startX = isvp(pos.pageX);
});
canvas.addEventListener((cantouch) ? 'touchend' : 'mouseup', function (e) {
startTime = 0;
startX = 0;
if (sup.get_auto_play()) sup.play();
});
canvas.addEventListener((cantouch) ? 'touchmove' : 'mousemove', function (e) {
e.preventDefault();
var pos = (e.touches && e.touches.length > 0) ? e.touches[0] : e;
var currentX = isvp(pos.pageX);
currentDistance = (startX === 0) ? 0 : Math.abs(currentX - startX);
// allow if movement < 1 sec
currentTime = e.timeStamp;
if (startTime !== 0 && currentDistance > maxDistance) {
if (currentX < startX && sup.get_current_frame() > 0) {
sup.move_relative(-1);
}
if (currentX > startX && sup.get_current_frame() < sup.get_length() - 1) {
sup.move_relative(1);
}
startTime = e.timeStamp;
startX = isvp(pos.pageX);
}
var time_since_last_play = e.timeStamp - last_played;
{
aj++;
if (document.getElementById('tickles' + ((aj % 5) + 1))) document.getElementById('tickles' + ((aj % 5) + 1)).play();
last_played = e.timeStamp;
}
});
};
sup.orig_load = sup.load;
sup.load = function(callback) {
sup.orig_load( function() {
if (callback) callback();
register_canvas_handers( sup );
} );
}
return sup;
}
return RubbableGif;
}));