Skip to content

Commit b103682

Browse files
committed
got the hard flag working. Need a better name.
1 parent b6b0b04 commit b103682

File tree

7 files changed

+113
-88
lines changed

7 files changed

+113
-88
lines changed

demos/synched_playback.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var setupAudioSynching = function (audio, xGif, metadata) {
1+
var setupAudioSynching = function (audio, xGifs, metadata) {
22
var synchOffset = -0.1;
33

44
audio.addEventListener('playing', function () {
@@ -24,7 +24,9 @@ var setupAudioSynching = function (audio, xGif, metadata) {
2424

2525
var sinceLastBeat = currentTime - beat.start,
2626
beatFraction = sinceLastBeat / beat.duration;
27-
xGif.clock(beatIndex, beat.duration * 1000 / audio.playbackRate, beatFraction);
27+
[].forEach.call(xGifs, function (xGif) {
28+
xGif.clock(beatIndex, beat.duration * 1000 / audio.playbackRate, beatFraction);
29+
})
2830
}
2931
}
3032
animationLoop();

dist/x-gif.angular.js

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,6 +2113,7 @@ var $__default = (function() {
21132113
this.pingPong = opts.pingPong;
21142114
this.fill = opts.fill;
21152115
this.stopped = opts.stopped;
2116+
this.hard = opts.hard;
21162117
this.ready = new Promise((function(resolve, reject) {
21172118
var exploder = new Exploder(file);
21182119
exploder.load().then((function(gif) {
@@ -2172,34 +2173,23 @@ var $__default = (function() {
21722173
},
21732174
fromClock: function(beatNr, beatDuration, beatFraction) {
21742175
var speedup = 1.5,
2175-
lengthInBeats = Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
2176+
lengthInBeats = this.hard ? 1 : Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
21762177
subBeat = beatNr % lengthInBeats,
21772178
repeatCount = beatNr / lengthInBeats,
21782179
subFraction = (beatFraction / lengthInBeats) + subBeat / lengthInBeats;
21792180
this.setFrame(subFraction, repeatCount);
21802181
},
2181-
startHardBpm: function(bpm) {
2182-
var $__0 = this;
2183-
var beatLength = 60 * 1000 / bpm;
2184-
this.animationLoop = (function() {
2185-
var duration = performance.now() - $__0.startTime,
2186-
repeatCount = duration / beatLength,
2187-
fraction = repeatCount % 1;
2188-
$__0.setFrame(fraction, repeatCount);
2189-
if (!$__0.stopped)
2190-
requestAnimationFrame($__0.animationLoop);
2191-
});
2192-
if (!this.stopped)
2193-
this.start();
2182+
changeBpm: function(bpm) {
2183+
this.beatLength = 60 * 1000 / bpm;
21942184
},
21952185
startBpm: function(bpm) {
21962186
var $__0 = this;
2197-
var beatLength = 60 * 1000 / bpm;
2187+
this.changeBpm(bpm);
21982188
this.animationLoop = (function() {
21992189
var duration = performance.now() - $__0.startTime,
2200-
beatNr = Math.floor(duration / beatLength),
2201-
beatFraction = (duration % beatLength) / beatLength;
2202-
$__0.fromClock(beatNr, beatLength, beatFraction);
2190+
beatNr = Math.floor(duration / $__0.beatLength),
2191+
beatFraction = (duration % $__0.beatLength) / $__0.beatLength;
2192+
$__0.fromClock(beatNr, $__0.beatLength, beatFraction);
22032193
if (!$__0.stopped)
22042194
requestAnimationFrame($__0.animationLoop);
22052195
});

dist/x-gif.js

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,7 @@ var $__default = (function() {
21152115
this.pingPong = opts.pingPong;
21162116
this.fill = opts.fill;
21172117
this.stopped = opts.stopped;
2118+
this.hard = opts.hard;
21182119
this.ready = new Promise((function(resolve, reject) {
21192120
var exploder = new Exploder(file);
21202121
exploder.load().then((function(gif) {
@@ -2174,34 +2175,23 @@ var $__default = (function() {
21742175
},
21752176
fromClock: function(beatNr, beatDuration, beatFraction) {
21762177
var speedup = 1.5,
2177-
lengthInBeats = Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
2178+
lengthInBeats = this.hard ? 1 : Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
21782179
subBeat = beatNr % lengthInBeats,
21792180
repeatCount = beatNr / lengthInBeats,
21802181
subFraction = (beatFraction / lengthInBeats) + subBeat / lengthInBeats;
21812182
this.setFrame(subFraction, repeatCount);
21822183
},
2183-
startHardBpm: function(bpm) {
2184-
var $__0 = this;
2185-
var beatLength = 60 * 1000 / bpm;
2186-
this.animationLoop = (function() {
2187-
var duration = performance.now() - $__0.startTime,
2188-
repeatCount = duration / beatLength,
2189-
fraction = repeatCount % 1;
2190-
$__0.setFrame(fraction, repeatCount);
2191-
if (!$__0.stopped)
2192-
requestAnimationFrame($__0.animationLoop);
2193-
});
2194-
if (!this.stopped)
2195-
this.start();
2184+
changeBpm: function(bpm) {
2185+
this.beatLength = 60 * 1000 / bpm;
21962186
},
21972187
startBpm: function(bpm) {
21982188
var $__0 = this;
2199-
var beatLength = 60 * 1000 / bpm;
2189+
this.changeBpm(bpm);
22002190
this.animationLoop = (function() {
22012191
var duration = performance.now() - $__0.startTime,
2202-
beatNr = Math.floor(duration / beatLength),
2203-
beatFraction = (duration % beatLength) / beatLength;
2204-
$__0.fromClock(beatNr, beatLength, beatFraction);
2192+
beatNr = Math.floor(duration / $__0.beatLength),
2193+
beatFraction = (duration % $__0.beatLength) / $__0.beatLength;
2194+
$__0.fromClock(beatNr, $__0.beatLength, beatFraction);
22052195
if (!$__0.stopped)
22062196
requestAnimationFrame($__0.animationLoop);
22072197
});

dist/x-gif.raw.js

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,15 +2019,26 @@ var XGifController = function XGifController(xgif) {
20192019
console.log("Loading " + src);
20202020
this.playback = new Playback(this, this.shadow.querySelector('#frames'), src, this.xgif.options);
20212021
this.playback.ready.then((function() {
2022-
if ($__0.xgif.playbackMode === 'speed') {
2022+
if ($__0.xgif.playbackMode == 'speed') {
20232023
$__0.playback.startSpeed($__0.xgif.speed);
2024+
} else if ($__0.xgif.playbackMode == 'bpm') {
2025+
$__0.playback.startBpm($__0.xgif.bpm);
20242026
}
20252027
}));
20262028
},
20272029
speedChanged: function(speed) {
20282030
if (this.playback)
20292031
this.playback.speed = speed;
20302032
},
2033+
bpmChanged: function(bpm) {
2034+
if (this.playback)
2035+
this.playback.changeBpm(bpm);
2036+
},
2037+
hardChanged: function(hard) {
2038+
console.log("TURN DOWN");
2039+
if (this.playback)
2040+
this.playback.hard = hard;
2041+
},
20312042
stoppedChanged: function(nowStop) {
20322043
if (this.playback) {
20332044
if (nowStop && !this.playback.stopped) {
@@ -2064,12 +2075,12 @@ var $XGif = XGif;
20642075
},
20652076
determinePlaybackMode: function() {
20662077
if (this.hasAttribute('exploded') || this.hasAttribute('sync')) {
2067-
this.playbackStrategy = undefined;
2078+
this.playbackMode = undefined;
20682079
return;
20692080
}
20702081
var maybeBPM = parseFloat(this.getAttribute('bpm'));
20712082
if (!isNaN(maybeBPM)) {
2072-
this.playbackStrategy = 'bpm';
2083+
this.playbackMode = 'bpm';
20732084
this.bpm = maybeBPM;
20742085
return;
20752086
}
@@ -2088,20 +2099,25 @@ var $XGif = XGif;
20882099
};
20892100
},
20902101
attributeChangedCallback: function(attribute, oldVal, newVal) {
2102+
console.log(attribute);
20912103
if (attribute == "src") {
20922104
this.controller.srcChanged(newVal);
20932105
} else if (attribute == "speed") {
20942106
this.determinePlaybackMode();
20952107
this.controller.speedChanged(this.speed);
20962108
} else if (attribute == "bpm") {
20972109
this.determinePlaybackMode();
2098-
this.controller.speedChanged(this.bpm);
2110+
this.controller.bpmChanged(this.bpm);
20992111
} else if (attribute == "stopped") {
21002112
this.determinePlaybackOptions();
21012113
this.controller.stoppedChanged(this.options.stopped);
21022114
} else if (attribute == "ping-pong") {
21032115
this.determinePlaybackOptions();
21042116
this.controller.pingPongChanged(this.options.pingPong);
2117+
} else if (attribute == "hard") {
2118+
console.log("TURN DOWN");
2119+
this.determinePlaybackOptions();
2120+
this.controller.hardChanged(this.options.hard);
21052121
}
21062122
},
21072123
clock: function(beatNr, beatDuration, beatFraction) {
@@ -2173,6 +2189,7 @@ var $__default = (function() {
21732189
this.pingPong = opts.pingPong;
21742190
this.fill = opts.fill;
21752191
this.stopped = opts.stopped;
2192+
this.hard = opts.hard;
21762193
this.ready = new Promise((function(resolve, reject) {
21772194
var exploder = new Exploder(file);
21782195
exploder.load().then((function(gif) {
@@ -2232,34 +2249,23 @@ var $__default = (function() {
22322249
},
22332250
fromClock: function(beatNr, beatDuration, beatFraction) {
22342251
var speedup = 1.5,
2235-
lengthInBeats = Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
2252+
lengthInBeats = this.hard ? 1 : Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
22362253
subBeat = beatNr % lengthInBeats,
22372254
repeatCount = beatNr / lengthInBeats,
22382255
subFraction = (beatFraction / lengthInBeats) + subBeat / lengthInBeats;
22392256
this.setFrame(subFraction, repeatCount);
22402257
},
2241-
startHardBpm: function(bpm) {
2242-
var $__0 = this;
2243-
var beatLength = 60 * 1000 / bpm;
2244-
this.animationLoop = (function() {
2245-
var duration = performance.now() - $__0.startTime,
2246-
repeatCount = duration / beatLength,
2247-
fraction = repeatCount % 1;
2248-
$__0.setFrame(fraction, repeatCount);
2249-
if (!$__0.stopped)
2250-
requestAnimationFrame($__0.animationLoop);
2251-
});
2252-
if (!this.stopped)
2253-
this.start();
2258+
changeBpm: function(bpm) {
2259+
this.beatLength = 60 * 1000 / bpm;
22542260
},
22552261
startBpm: function(bpm) {
22562262
var $__0 = this;
2257-
var beatLength = 60 * 1000 / bpm;
2263+
this.changeBpm(bpm);
22582264
this.animationLoop = (function() {
22592265
var duration = performance.now() - $__0.startTime,
2260-
beatNr = Math.floor(duration / beatLength),
2261-
beatFraction = (duration % beatLength) / beatLength;
2262-
$__0.fromClock(beatNr, beatLength, beatFraction);
2266+
beatNr = Math.floor(duration / $__0.beatLength),
2267+
beatFraction = (duration % $__0.beatLength) / $__0.beatLength;
2268+
$__0.fromClock(beatNr, $__0.beatLength, beatFraction);
22632269
if (!$__0.stopped)
22642270
requestAnimationFrame($__0.animationLoop);
22652271
});

index.html

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ <h6><a href="https://github.com/geelen/x-gif" target="_blank">View source on Git
7575
</label>
7676

7777
<h3>Normal playback</h3>
78-
<p class="small">Something not look right? <a href="https://github.com/geelen/x-gif/issues" target="_blank">Post an issue on GitHub</a> with the URL of the image</p>
78+
79+
<p class="small">Something not look right? <a href="https://github.com/geelen/x-gif/issues" target="_blank">Post an
80+
issue on GitHub</a> with the URL of the image</p>
7981
<figure>
8082
<x-gif ng-src="{{ trustedUrl() }}"></x-gif>
8183
<figcaption>
@@ -102,6 +104,21 @@ <h3>Speed</h3>
102104
</figcaption>
103105
</figure>
104106

107+
<h3>BPM</h3>
108+
<figure>
109+
<label>
110+
<input type="range" min="30" max="240" step="1" ng-model="gif.bpm"/> {{ gif.bpm }}
111+
</label>
112+
<x-gif ng-src="{{ trustedUrl() }}" bpm="{{ gif.bpm }}"></x-gif>
113+
<figcaption>
114+
<pre>&lt;x-gif src="{{ trustedUrl() }}" bpm="{{ gif.bpm }}" &gt;&lt;/x-gif&gt;</pre>
115+
</figcaption>
116+
<x-gif ng-src="{{ trustedUrl() }}" bpm="{{ gif.bpm }}" hard></x-gif>
117+
<figcaption>
118+
<pre>&lt;x-gif src="{{ trustedUrl() }}" bpm="{{ gif.bpm }}" hard&gt;&lt;/x-gif&gt;</pre>
119+
</figcaption>
120+
</figure>
121+
105122
<h3>Synced to Audio</h3>
106123
<figure>
107124
<div ng-show="gif.metadata">
@@ -114,9 +131,13 @@ <h3>Synced to Audio</h3>
114131
</p>
115132
</div>
116133
<div ng-hide="gif.metadata">Loading beat data...</div>
117-
<x-gif id="synced" ng-src="{{ trustedUrl() }}" sync></x-gif>
134+
<x-gif class="x-gif-synced-demo" ng-src="{{ trustedUrl() }}" sync></x-gif>
118135
<figcaption>
119136
<pre>&lt;x-gif src="{{ trustedUrl() }}" synced&gt;&lt;/x-gif&gt;</pre>
137+
</figcaption>
138+
<x-gif class="x-gif-synced-demo" ng-src="{{ trustedUrl() }}" sync hard></x-gif>
139+
<figcaption>
140+
<pre>&lt;x-gif src="{{ trustedUrl() }}" synced hard&gt;&lt;/x-gif&gt;</pre>
120141
<p>
121142
Audio: Encom Part II by Daft Punk. CC0 1.0 Universal.
122143
<br/>
@@ -163,6 +184,7 @@ <h5>Made with <3 by</h5>
163184
$scope.gif = {
164185
url: $scope.gifs[0],
165186
speed: 2,
187+
bpm: 120,
166188
playbackRate: 1
167189
};
168190
var audio = document.querySelector('audio');
@@ -174,7 +196,7 @@ <h5>Made with <3 by</h5>
174196
$http.get('demos/cc_audio/encom_part_ii.json').then(function (response) {
175197
$scope.gif.metadata = response.data;
176198
setupAudioSynching(audio,
177-
document.querySelector('#synced'),
199+
document.querySelectorAll('.x-gif-synced-demo'),
178200
$scope.gif.metadata)
179201
})
180202
$scope.trustedUrl = function () {
@@ -190,10 +212,17 @@ <h5>Made with <3 by</h5>
190212
});
191213
</script>
192214
<script>
193-
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
194-
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
195-
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
196-
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
215+
(function (i, s, o, g, r, a, m) {
216+
i['GoogleAnalyticsObject'] = r;
217+
i[r] = i[r] || function () {
218+
(i[r].q = i[r].q || []).push(arguments)
219+
}, i[r].l = 1 * new Date();
220+
a = s.createElement(o),
221+
m = s.getElementsByTagName(o)[0];
222+
a.async = 1;
223+
a.src = g;
224+
m.parentNode.insertBefore(a, m)
225+
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
197226

198227
ga('create', 'UA-32408977-5', 'geelen.github.io');
199228
ga('send', 'pageview');

src/playback.js

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export default class Playback {
2121
this.pingPong = opts.pingPong;
2222
this.fill = opts.fill;
2323
this.stopped = opts.stopped;
24+
this.hard = opts.hard;
2425

2526
this.ready = new Promise((resolve, reject) => {
2627
var exploder = new Exploder(file)
@@ -88,36 +89,27 @@ export default class Playback {
8889
}
8990

9091
fromClock(beatNr, beatDuration, beatFraction) {
92+
// Always bias GIFs to speeding up rather than slowing down, it looks better.
9193
var speedup = 1.5,
92-
lengthInBeats = Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
94+
lengthInBeats = this.hard ? 1 : Math.max(1, Math.round((1 / speedup) * 10 * this.gif.length / beatDuration)),
9395
subBeat = beatNr % lengthInBeats,
9496
repeatCount = beatNr / lengthInBeats,
9597
subFraction = (beatFraction / lengthInBeats) + subBeat / lengthInBeats;
9698
this.setFrame(subFraction, repeatCount);
9799
}
98100

99-
startHardBpm(bpm) {
100-
var beatLength = 60 * 1000 / bpm;
101-
this.animationLoop = () => {
102-
var duration = performance.now() - this.startTime,
103-
repeatCount = duration / beatLength,
104-
fraction = repeatCount % 1;
105-
this.setFrame(fraction, repeatCount);
106-
107-
if (!this.stopped) requestAnimationFrame(this.animationLoop);
108-
}
109-
110-
if (!this.stopped) this.start();
101+
changeBpm(bpm) {
102+
this.beatLength = 60 * 1000 / bpm;
111103
}
112104

113105
startBpm(bpm) {
114-
var beatLength = 60 * 1000 / bpm;
106+
this.changeBpm(bpm);
115107
this.animationLoop = () => {
116108
var duration = performance.now() - this.startTime,
117-
beatNr = Math.floor(duration / beatLength),
118-
beatFraction = (duration % beatLength) / beatLength;
109+
beatNr = Math.floor(duration / this.beatLength),
110+
beatFraction = (duration % this.beatLength) / this.beatLength;
119111

120-
this.fromClock(beatNr, beatLength, beatFraction);
112+
this.fromClock(beatNr, this.beatLength, beatFraction);
121113

122114
if (!this.stopped) requestAnimationFrame(this.animationLoop);
123115
}

0 commit comments

Comments
 (0)