datafeed.js | |
---|---|
Effects to take a prefetched data feed (JSON, RSS, ATOM, XML) and use in your video. In combination with the input effects, and a bit of server-side coding, this can yield some interesting possibilities. For all data feeds used by these effects, make sure to include
them in the | var datafeed_map_colours = ['#7E2D95', '#E65008', '#5b6c03', '#9d3e62', '#278699', '#cc0101', '#ffd800'],
datafeed_slideshow_duration = 4,
datafeed_slideshow_limit = false,
datafeed_slideshow_cur = 0,
datafeed_slideshow_n = 0,
datafeed_slideshow_images = [],
datafeed_slideshow_front_img,
datafeed_slideshow_back_img,
datafeed_slideshow_front_burns,
datafeed_slideshow_back_burns,
datafeed_headlines_items = [],
datafeed_headlines_cur = 0,
datafeed_headlines_duration = 4,
datafeed_headlines_limit = false,
datafeed_headlines_last_y = false; |
Make the calculations for performing the Ken Burns effect on an image in the slideshow. Based on the Ken Burns implementation at Adventures in Software. | function datafeed_slideshow_burns (proportion) {
proportion = (isNaN (proportion)) ? 1.5 : proportion;
var burns = {
_x0: 0,
_x1: 0,
_y0: 0,
_y1: 0,
_w0: 0,
_w1: 0,
_h0: 0,
_h1: 0,
apply: function (img, time) {
time *= .02;
img.x = (this._x0 - this._x1) * time - this._x0;
img.y = (this._y0 - this._y1) * time - this._y0;
img.dWidth = (this._w1 - this._w0) * time + this._w0;
img.dHeight = (this._h1 - this._h0) * time + this._h0;
}
}; |
Choose rectangles based on more constrained dimension. | if (proportion < cacophony.width / cacophony.height) {
burns._w0 = cacophony.width * (1 + (.25 * Math.random ()));
burns._w1 = cacophony.width * (1 + (.25 * Math.random ()));
burns._h0 = burns._w0 / proportion;
burns._h1 = burns._w1 / proportion;
} else {
burns._h0 = cacophony.height * (1 + (.25 * Math.random ()));
burns._h1 = cacophony.height * (1 + (.25 * Math.random ()));
burns._w0 = burns._h0 * proportion;
burns._w1 = burns._h1 * proportion;
} |
Calculate the translation to keep image within window. | burns._x0 = (burns._w0 - cacophony.width) * Math.random ();
burns._x1 = (burns._w1 - cacophony.width) * Math.random ();
burns._y0 = (burns._h0 - cacophony.height) * Math.random ();
burns._y1 = (burns._h1 - cacophony.height) * Math.random ();
return burns;
} |
Used by | function datafeed_slideshow_step () {
if (! cacophony.playing) {
setTimeout (datafeed_slideshow_step, (cacophony.beatLength () * datafeed_slideshow_duration) / 25);
return;
}
datafeed_slideshow_n++;
if (datafeed_slideshow_n == 20) {
datafeed_slideshow_cur++;
if (datafeed_slideshow_images[datafeed_slideshow_cur]) {
datafeed_slideshow_front_img = new ImageNode (datafeed_slideshow_images[datafeed_slideshow_cur]);
datafeed_slideshow_front_burns = datafeed_slideshow_burns (datafeed_slideshow_front_img.width / datafeed_slideshow_front_img.height);
datafeed_slideshow_front_img.opacity = 0;
datafeed_slideshow_front_burns.apply (datafeed_slideshow_front_img, -5);
cacophony.canvas.append (datafeed_slideshow_front_img);
}
} else if (datafeed_slideshow_n == 25) {
cacophony.canvas.remove (datafeed_slideshow_back_img);
datafeed_slideshow_back_img = datafeed_slideshow_front_img;
datafeed_slideshow_back_burns = datafeed_slideshow_front_burns;
if (datafeed_slideshow_back_img) {
datafeed_slideshow_back_img.opacity = 1;
}
datafeed_slideshow_front_img = null;
datafeed_slideshow_front_burns = null;
datafeed_slideshow_n = 0;
} else if (datafeed_slideshow_n > 20) {
if (datafeed_slideshow_front_img) {
datafeed_slideshow_front_img.opacity += .2;
datafeed_slideshow_front_burns.apply (datafeed_slideshow_front_img, datafeed_slideshow_n - 25);
}
datafeed_slideshow_back_img.opacity -= .2;
}
if (datafeed_slideshow_back_img) {
datafeed_slideshow_back_burns.apply (datafeed_slideshow_back_img, datafeed_slideshow_n);
setTimeout (datafeed_slideshow_step, (cacophony.beatLength () * datafeed_slideshow_duration) / 25);
}
} |
Display a slideshow based on a specified RSS or ATOM feed. Usage: | function datafeed_slideshow (data) {
if (data) {
var feed = cacophony.datafeed[data.url];
var images = feed.childNodes[0].getElementsByTagName ('content');
datafeed_slideshow_cur = 0;
datafeed_slideshow_limit = (data.limit) ? data.limit : false;
datafeed_slideshow_duration = (data.duration) ? data.duration : 4;
datafeed_slideshow_images = [];
for (var i = 0; i < images.length; i++) {
if (datafeed_slideshow_limit && i == datafeed_slideshow_limit) {
break;
}
datafeed_slideshow_images[i] = _i[images[i].getAttribute ('url')];
}
}
datafeed_slideshow_n = 0;
datafeed_slideshow_back_img = new ImageNode (datafeed_slideshow_images[0]);
datafeed_slideshow_back_burns = datafeed_slideshow_burns (datafeed_slideshow_back_img.width / datafeed_slideshow_back_img.height);
datafeed_slideshow_back_img.opacity = 1;
datafeed_slideshow_back_burns.apply (datafeed_slideshow_back_img, datafeed_slideshow_n);
cacophony.canvas.append (datafeed_slideshow_back_img);
datafeed_slideshow_step ();
} |
Display a series of headlines based on a specified RSS or ATOM feed. Usage: | function datafeed_headlines (data) {
if (data) {
var feed = cacophony.datafeed[data.url];
datafeed_headlines_items = feed.childNodes[0].getElementsByTagName ('item');
datafeed_headlines_cur = 0;
datafeed_headlines_duration = (data.duration) ? data.duration : 4;
datafeed_headlines_limit = (data.limit) ? data.limit : false;
datafeed_headlines_last_y = false;
datafeed_headlines_colour = (data.colour) ? data.colour : 'rgba(102, 102, 102, 1.0)';
}
if (! cacophony.playing) {
setTimeout (datafeed_headlines, cacophony.beatLength () * datafeed_headlines_duration);
return;
}
if (datafeed_headlines_limit && datafeed_headlines_limit <= datafeed_headlines_cur) {
return;
}
if (datafeed_headlines_items[datafeed_headlines_cur]) {
var txt = $(datafeed_headlines_items[datafeed_headlines_cur]).find ('title')[0].textContent;
if (! datafeed_headlines_last_y || datafeed_headlines_last_y > (cacophony.height / 2)) {
datafeed_headlines_last_y = 5 + Math.round (Math.random () * ((cacophony.height / 2) - 5));
} else {
datafeed_headlines_last_y = (cacophony.height / 2) + Math.round (Math.random () * (cacophony.height / 2));
}
lyrics ({
txt: txt,
x: Math.random () * (cacophony.width / 4),
y: datafeed_headlines_last_y,
colour: datafeed_headlines_colour
});
datafeed_headlines_cur++;
setTimeout (datafeed_headlines, cacophony.beatLength () * datafeed_headlines_duration);
}
} |
Display a series of points on a map based on a JSON feed of the following form:
Usage:
Also be sure to include the Google Maps API into your | function datafeed_map_on (data) {
var feed, d, zoom, lat, lng, latlng, options, map, c, opts, circle;
feed = cacophony.datafeed[data.url];
d = document.createElement ('div');
d.setAttribute ('style', 'width: ' + (cacophony.width - 40) + 'px; height: ' + (cacophony.height - 100) + 'px');
zoom = (data.zoom) ? data.zoom : 2;
lat = (data.lat) ? data.lat : 1.0;
lng = (data.lng) ? data.lng : 0.0;
latlng = new google.maps.LatLng (lat, lng);
options = {
zoom: zoom,
center: latlng,
mapTypeId: google.maps.MapTypeId.TERRAIN,
mapTypeControl: false,
backgroundColor: 'transparent',
draggable: false,
scrollwheel: false,
scaleControl: false,
navigationControl: false,
streetViewControl: false
};
map = new google.maps.Map (d, options);
for (var i = 0; i < feed.length; i++) {
c = datafeed_map_colour ();
opts = {
center: new google.maps.LatLng (feed[i].lat, feed[i].lng),
fillColor: c,
fillOpacity: 1,
clickable: false,
map: map,
radius: feed[i].count * 10000, // 10km per count
strokeColor: c,
strokeOpacity: 1,
strokeWeight: 1,
zIndex: 100
};
circle = new google.maps.Circle (opts);
circle.setMap (map);
}
cacophony.html (d, 30, 20);
} |
Hide the map. Usage: | function datafeed_map_off () {
cacophony.html ();
} |
Get a random colour for the map circles | function datafeed_map_colour () {
return datafeed_map_colours[Math.floor (Math.random () * datafeed_map_colours.length)];
}
_e['datafeed_slideshow'] = datafeed_slideshow;
_e['datafeed_headlines'] = datafeed_headlines;
_e['datafeed_map_on'] = datafeed_map_on;
_e['datafeed_map_off'] = datafeed_map_off;
|