Skip to content

Commit b246ace

Browse files
committed
using ES6 here makes this so much nicer!
1 parent 6625eb1 commit b246ace

File tree

9 files changed

+158
-130
lines changed

9 files changed

+158
-130
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
bower_components
22
node_modules
33
demos/audio
4+
dist/images

README.md

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,47 @@ _The GIF tag the internet deserves_
66

77
**<x-gif>** is a web component for flexible GIF playback. Speed them up, slow them down, play them in reverse, synch multiple beats to a rhythm, synch them to audio, whatever you like.
88

9-
1. Import Polymer
10-
```html
11-
<script src="bower_components/platform/platform.js"></script>
12-
```
9+
```html
10+
<x-gif src="probably_cats.gif"></x-gif>
11+
```
12+
13+
Playback modes:
14+
15+
Mutually exclusive. Can't be changed once initialised (create a new x-gif if you want a new mode)
16+
17+
`speed="1.0"` (default mode)
18+
Plays back the GIF at its natural framerate multiplied by the value of the attribute. Can be updated and will have immediate effect.
19+
20+
`sync`
21+
Defers playback to an external object. The DOM element will then expose a `clock` function to facilitate playback. Cannot be changed.
22+
23+
`bpm="120"`
24+
Syncs GIFs to a given beats-per-minute. If multiple x-gifs are on the page, they will all be synced together. By default, will spread long GIFs over multiple beats, unless the `snap` option is also included. Uses `sync` and `clock` under the hood. Can be changed and will take immediate effect.
25+
26+
Options:
27+
28+
`stopped`
29+
Regardless of playback mode, this will prevent the GIF from animating. Removing this attribute resumes playback. In `speed` mode, the GIF will always resume playback from the beginning.
30+
31+
`fill`
32+
Causes the GIF to expand to cover its container, like if you had used `background-size: cover; background-position: 50% 50%` with a normal GIF. Without `fill`, an x-gif behaves like an inline-block element, just like a normal <img> tag.
33+
34+
`n-times="3.0"` (speed mode only)
35+
Stops playback (by adding the attribute `stopped`) after a set number of times. Can be fractional e.g. `0.9` will play the first 90% of the GIF then stop. Removing the `stopped` attribute will restart the playback.
36+
37+
`hard` (sync & bpm modes only)
38+
Instead of allowing longer GIFs to sync to multiple beats, force them to fit into only one.
39+
40+
`ping-pong`
41+
Boolean attribute. Plays the GIF front-to-back then back-to-front, which looks more awesome for some GIFs. Works with all playback modes. Can be removed/added at any time.
42+
43+
Debugging:
1344

14-
2. Import X-Gif
15-
```html
16-
<link rel="import" href="bower_components/x-gif/dist/x-gif.html">
17-
```
45+
`debug`
46+
Turns on debug output from the Gif Exploder, which can help track down errors with some GIFs being parsed incorrectly.
1847

19-
3. Enjoy limitless GIF possibilities
20-
```html
21-
<x-gif src="probably_cats.gif"></x-gif>
22-
```
48+
`exploded`
49+
For visual inspection of the frames. Stops playback, and renders each frame out side-by-side. Many frames will appear semi-transparent, because that's how GIFs work. But this might come in handy.
2350

2451
What does it do?
2552

@@ -77,10 +104,11 @@ Defers playback to an external clock, such as beat data from an audio stream to
77104

78105
## Status
79106

80-
* **Polymer element - DONE!**
81-
* Angular directive - TODO
82-
* React component - TODO
83-
* Ember component - TODO
107+
* Web Component - YES! (zero-dependencies on Chrome 36!)
108+
* Polymer element - Nah, just use the Web Component
109+
* Angular directive - Nah, just use the Web Component
110+
* React component - Nah, just use the Web Component
111+
* Ember component - Nah, just use the Web Component
84112

85113
## Contributing
86114

demos/stoppable.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
</head>
1717
<body>
1818
<h1>Click a gif to stop or start it</h1>
19-
<x-gif src="http://i.imgur.com/ifR7csn.gif"></x-gif>
20-
<x-gif stopped src="http://i.imgur.com/ifR7csn.gif"></x-gif>
19+
<x-gif src="/dist/images/stars.gif"></x-gif>
20+
<x-gif stopped src="/dist/images/stars.gif"></x-gif>
2121
<script>
2222
[].forEach.call(document.querySelectorAll('x-gif'), function (el) {
2323
el.addEventListener('click', function () {

dist/x-gif.angular.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2086,7 +2086,6 @@ var $__default = (function() {
20862086

20872087
},{}],6:[function(require,module,exports){
20882088
"use strict";
2089-
"use strict";
20902089
Object.defineProperties(exports, {
20912090
default: {get: function() {
20922091
return $__default;

dist/x-gif.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,7 +1998,6 @@ var $__default = (function() {
19981998

19991999
},{"./gif.js":5,"./stream_reader.js":8,"./utils.js":9}],4:[function(require,module,exports){
20002000
"use strict";
2001-
"use strict";
20022001
var Playback = $traceurRuntime.assertObject(require('./playback.js')).default;
20032002
var Strategies = $traceurRuntime.assertObject(require('./strategies.js')).default;
20042003
var XGif = function() {
@@ -2089,7 +2088,6 @@ var $__default = (function() {
20892088

20902089
},{}],6:[function(require,module,exports){
20912090
"use strict";
2092-
"use strict";
20932091
Object.defineProperties(exports, {
20942092
default: {get: function() {
20952093
return $__default;

dist/x-gif.raw.js

Lines changed: 73 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,86 +1998,90 @@ var $__default = (function() {
19981998

19991999
},{"./gif.js":5,"./stream_reader.js":8,"./utils.js":9}],4:[function(require,module,exports){
20002000
"use strict";
2001-
"use strict";
20022001
var Playback = $traceurRuntime.assertObject(require('./playback.js')).default;
20032002
var Strategies = $traceurRuntime.assertObject(require('./strategies.js')).default;
2004-
(function(document, owner) {
2005-
var XGifController = function(context) {
2006-
var $__0 = this;
2007-
this.context = context;
2008-
this.shadow = this.context.createShadowRoot();
2009-
var template = owner.querySelector("#template").content.cloneNode(true);
2010-
this.shadow.appendChild(template);
2011-
if (context.hasAttribute('exploded')) {
2012-
this.playbackStrategy = 'noop';
2013-
} else if (context.hasAttribute('sync')) {
2014-
this.playbackStrategy = 'noop';
2015-
} else if (context.getAttribute('hard-bpm')) {
2016-
this.playbackStrategy = 'hardBpm';
2017-
} else if (context.getAttribute('bpm')) {
2018-
this.playbackStrategy = 'bpm';
2019-
} else {
2020-
this.speed = parseFloat(context.getAttribute('speed')) || 1.0;
2021-
this.playbackStrategy = 'speed';
2022-
}
2023-
this.srcChanged = function(src) {
2024-
if (!src)
2025-
return;
2026-
console.log("Loading " + src);
2027-
var playbackStrategy = Strategies[this.playbackStrategy];
2028-
this.playback = new Playback(this, this.shadow.querySelector('#frames'), src, {
2029-
pingPong: context.hasAttribute('ping-pong'),
2030-
fill: context.hasAttribute('fill'),
2031-
stopped: context.hasAttribute('stopped')
2032-
});
2033-
this.playback.ready.then(playbackStrategy.bind(this));
2034-
};
2035-
this.srcChanged(context.getAttribute('src'));
2036-
this.speedChanged = function(speedStr) {
2037-
this.speed = parseFloat(speedStr) || this.speed;
2038-
if (this.playback)
2039-
this.playback.speed = this.speed;
2040-
};
2041-
this.stoppedChanged = function(newVal) {
2042-
var nowStop = newVal != null;
2043-
if (this.playback && nowStop && !this.playback.stopped) {
2044-
this.playback.stop();
2045-
} else if (this.playback && !nowStop && this.playback.stopped) {
2046-
this.playback.start();
2047-
}
2048-
};
2049-
context.togglePingPong = (function() {
2050-
if (context.hasAttribute('ping-pong')) {
2051-
context.removeAttribute('ping-pong');
2052-
} else {
2053-
context.setAttribute('ping-pong', '');
2054-
}
2055-
if ($__0.playback)
2056-
$__0.playback.pingPong = context.hasAttribute('ping-pong');
2057-
});
2058-
context.clock = (function(beatNr, beatDuration, beatFraction) {
2059-
if ($__0.playback && $__0.playback.gif)
2060-
$__0.playback.fromClock(beatNr, beatDuration, beatFraction);
2061-
});
2062-
context.relayout = (function() {
2063-
if (context.hasAttribute('fill'))
2064-
$__0.playback.scaleToFill();
2003+
var owner = (document._currentScript || document.currentScript).ownerDocument;
2004+
var XGifController = function XGifController(xgif) {
2005+
var $__0 = this;
2006+
this.xgif = xgif;
2007+
this.shadow = this.xgif.createShadowRoot();
2008+
var template = owner.querySelector("#template").content.cloneNode(true);
2009+
this.shadow.appendChild(template);
2010+
if (xgif.hasAttribute('exploded')) {
2011+
this.playbackStrategy = 'noop';
2012+
} else if (xgif.hasAttribute('sync')) {
2013+
this.playbackStrategy = 'noop';
2014+
} else if (xgif.getAttribute('hard-bpm')) {
2015+
this.playbackStrategy = 'hardBpm';
2016+
} else if (xgif.getAttribute('bpm')) {
2017+
this.playbackStrategy = 'bpm';
2018+
} else {
2019+
this.speed = parseFloat(xgif.getAttribute('speed')) || 1.0;
2020+
this.playbackStrategy = 'speed';
2021+
}
2022+
this.srcChanged = function(src) {
2023+
if (!src)
2024+
return;
2025+
console.log("Loading " + src);
2026+
var playbackStrategy = Strategies[this.playbackStrategy];
2027+
this.playback = new Playback(this, this.shadow.querySelector('#frames'), src, {
2028+
pingPong: xgif.hasAttribute('ping-pong'),
2029+
fill: xgif.hasAttribute('fill'),
2030+
stopped: xgif.hasAttribute('stopped')
20652031
});
2032+
this.playback.ready.then(playbackStrategy.bind(this));
20662033
};
2067-
var XGif = Object.create(HTMLElement.prototype);
2068-
XGif.createdCallback = function() {
2069-
this.controller = new XGifController(this);
2034+
this.srcChanged(xgif.getAttribute('src'));
2035+
this.speedChanged = function(speedStr) {
2036+
this.speed = parseFloat(speedStr) || this.speed;
2037+
if (this.playback)
2038+
this.playback.speed = this.speed;
2039+
};
2040+
this.stoppedChanged = function(newVal) {
2041+
var nowStop = newVal != null;
2042+
if (this.playback && nowStop && !this.playback.stopped) {
2043+
this.playback.stop();
2044+
} else if (this.playback && !nowStop && this.playback.stopped) {
2045+
this.playback.start();
2046+
}
20702047
};
2071-
XGif.attributeChangedCallback = function(attribute, oldVal, newVal) {
2048+
xgif.togglePingPong = (function() {
2049+
if (xgif.hasAttribute('ping-pong')) {
2050+
xgif.removeAttribute('ping-pong');
2051+
} else {
2052+
xgif.setAttribute('ping-pong', '');
2053+
}
2054+
if ($__0.playback)
2055+
$__0.playback.pingPong = xgif.hasAttribute('ping-pong');
2056+
});
2057+
xgif.clock = (function(beatNr, beatDuration, beatFraction) {
2058+
if ($__0.playback && $__0.playback.gif)
2059+
$__0.playback.fromClock(beatNr, beatDuration, beatFraction);
2060+
});
2061+
xgif.relayout = (function() {
2062+
if (xgif.hasAttribute('fill'))
2063+
$__0.playback.scaleToFill();
2064+
});
2065+
};
2066+
($traceurRuntime.createClass)(XGifController, {}, {});
2067+
var XGif = function XGif() {
2068+
$traceurRuntime.defaultSuperCall(this, $XGif.prototype, arguments);
2069+
};
2070+
var $XGif = XGif;
2071+
($traceurRuntime.createClass)(XGif, {
2072+
createdCallback: function() {
2073+
this.controller = new XGifController(this);
2074+
},
2075+
attributeChangedCallback: function(attribute, oldVal, newVal) {
20722076
if (attribute == "src")
20732077
this.controller.srcChanged(newVal);
20742078
if (attribute == "speed")
20752079
this.controller.speedChanged(newVal);
20762080
if (attribute == "stopped")
20772081
this.controller.stoppedChanged(newVal);
2078-
};
2079-
document.registerElement('x-gif', {prototype: XGif});
2080-
})(document, (document._currentScript || document.currentScript).ownerDocument);
2082+
}
2083+
}, {}, HTMLElement);
2084+
document.registerElement('x-gif', XGif);
20812085

20822086

20832087
},{"./playback.js":6,"./strategies.js":7}],5:[function(require,module,exports){
@@ -2115,7 +2119,6 @@ var $__default = (function() {
21152119

21162120
},{}],6:[function(require,module,exports){
21172121
"use strict";
2118-
"use strict";
21192122
Object.defineProperties(exports, {
21202123
default: {get: function() {
21212124
return $__default;

src/playback.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"use strict";
2-
31
import Exploder from './exploder.js';
42

53
// Private functions for setup

src/x-gif.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"use strict";
2-
31
import Playback from './playback.js';
42
import Strategies from './strategies.js';
53

0 commit comments

Comments
 (0)