diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js
index 7a2120dc..6d041d12 100644
--- a/build/js/ox.ui.js
+++ b/build/js/ox.ui.js
@@ -10687,6 +10687,103 @@ requires
};
+ Ox.Flipbook = function(options, self) {
+
+ var self = self || {},
+ frame = $('').css({
+ 'position': 'absolute',
+ 'width': '100%',
+ 'height': 'auto'
+ })
+ .hide(),
+ icon = $('').css({
+ 'position': 'absolute',
+ 'width': '100%',
+ 'height': 'auto'
+ }),
+ frames = {},
+ timestamp = $('
').css({
+ 'position': 'absolute',
+ 'text-align': 'center',
+ 'width': '100%',
+ })
+ .hide(),
+ that = new Ox.Element('div', self)
+ .defaults({
+ frames: {},
+ duration: 0,
+ icon: '',
+ })
+ .options(options || {})
+ .append(icon)
+ .append(frame)
+ .append(timestamp)
+ .mouseover(function() {
+ frame.show();
+ timestamp.show();
+ icon.hide();
+ })
+ .mousemove(function(event) {
+ var position = getPosition(event),
+ image = getFrame(position),
+ frameHeight = image.height;
+ frame.attr('src', image.src);
+ timestamp.html(Ox.formatDuration(position, 'short'));
+
+ var height = (that.height() - frameHeight)/2;
+ frame.css({'top': height + 'px'});
+ timestamp.css({'top': (frameHeight + height) + 'px'});
+ })
+ .mouseout(function() {
+ frame.hide();
+ timestamp.hide();
+ icon.show();
+ })
+ .mousedown(function(event) {
+ that.triggerEvent('click', {
+ 'position': getPosition(event)
+ });
+ });
+
+ function getPosition(event) {
+ var position = Math.floor(event.clientX - that.offset().left);
+ position = (position / that.width()) * self.options.duration;
+ return position;
+ }
+
+ function getFrame(position) {
+ var frame;
+ $.each(frames, function(i, img) {
+ if(!frame || i <= position)
+ frame = img;
+ });
+ return frame;
+ }
+
+ function cacheFrames() {
+ $.each(self.options.frames, function(i, src) {
+ frames[i] = new Image();
+ frames[i].onload = function() {
+ frameHeight = frames[i].height / frames[i].width * that.width();
+ }
+ frames[i].src = src;
+ });
+ }
+
+ self.onChange = function(key, value) {
+ if (key == 'frames') {
+ cacheFrames();
+ } else if (key == 'icon') {
+ icon.attr('src', value);
+ }
+ }
+
+ if(options.icon)
+ icon.attr('src', options.icon);
+ cacheFrames();
+ return that;
+ };
+
Ox.LargeTimeline = function(options, self) {
var self = self || {},