var bf_react_cam = (function() { var UPLOAD_URL = '/bfcgi/_edit_photo_editor_image'; var tracking_tags = { 'ad_tags': { 'impression': 'http://ad.doubleclick.net/ad/N2434.244372.BUZZFEED.COM/B7633595.21;sz=1x1;ord=[timestamp]?', 'reaction_button_click': 'http://ad.doubleclick.net/clk;271872711;97733907;u', 'turn_on_webcam': 'http://ad.doubleclick.net/clk;271872711;97733937;x', 'record_button': 'http://ad.doubleclick.net/clk;271872711;97733942;t', 'save_button': 'http://ad.doubleclick.net/clk;271872711;97733956;y', 'clear_button': 'http://ad.doubleclick.net/clk;271872711;97733923;s', 'contrib_fb_share': 'http://ad.doubleclick.net/clk;271872711;97733917;v', 'contrib_tw_share': 'http://ad.doubleclick.net/clk;271872711;97733901;o', 'contrib_email_share': 'http://ad.doubleclick.net/clk;271872711;97733930;q', 'contrib_link_share': 'http://ad.doubleclick.net/clk;271872711;97733903;q' } } function ReactCam() { this.selector = $('react_cam_tt').clone(true); this.id = 'react_cam' + new Date().getTime(); this.selector.id = this.id; this._listeners = { }; this._cnt_down_id = false; this._is_observing = false; this._is_open = false; this._access_granted = false; this._is_recording = false; this._is_saving = false; this._offset = false; bf_react_cam.track('impression'); } function track(action) { var ad_tag = objExists(tracking_tags['ad_tags'][action]) ? tracking_tags['ad_tags'][action] : null; if (ad_tag) { //trackPixel(ad_tag); if (action != 'impression') { gtrack.track_events('[ttp]:reaction-cam', action, ''); } return true; } else { return false; } } ReactCam.prototype = { $$: function(selector) { var eles = $$('#' + this.selector.id + ' ' + selector); return eles.length == 1 ? eles[0] : eles; }, //////// add_listener: function(type, fn) { this._listeners[type] = this._listeners[type] || []; this._listeners[type].push(fn); }, //////// remove_listener: function(type, fn) { if(!this._listeners[type]) return; for(var i = this._listeners[type].length;i--;) { if(this._listeners[type][i] == fn) { this._listeners[type].splice(i, 1); break; } } }, //////// close: function() { this.selector.remove(); this._is_open = false; this.stop_cnt_down(); bf_react_cam_swfinterface.invoke(this.id, 'stop'); }, //////// open: function(wrapper, offset) { if(this._is_open) return; this._offset = offset; this._is_open = true; this._access_granted = false; this._is_recording = false; this._is_saving = false; wrapper.insert({top: this.selector}); this.to_screen(false); this.to_frame(1); this.show_save_ctrl(false); this._observe(); this._embed_swf(); bf_react_cam.track('reaction_button_click'); }, //////// jumpto_record: function() { this.to_frame(2); this._change_record_btn_state(0); bf_react_cam_swfinterface.invoke(this.id, 'begin'); bf_react_cam.track('turn_on_webcam'); }, //////// position: function() { var arrow_dimensions = this.$$('.arrowBorder').getDimensions(); var my_width = this.$$('.frame.active').measure('width'); this.$$('.arrow_wrapper').setStyle({ left: ((my_width - arrow_dimensions.width) / 2) + 'px' }); this.selector.setStyle({ top: (this._offset.top + arrow_dimensions.height / 2) + 'px', left: (this._offset.left - my_width / 2) + 'px' }); }, //////// show_save_ctrl: function(val) { if(val) this.$$('.save_ctrl').show(); else this.$$('.save_ctrl').hide(); }, //////// to_frame: function(frame) { try { this.$$('.frame.active').removeClassName('active'); } catch(e) { } this.$$('.frame .active').each(function(el) { el.hide(); } ); this.$$('.frame').each(function(el) { el.hide(); } ); this.$$('.frame.frame'+frame).setStyle({display: 'block'}); this.$$('.frame.frame'+frame).addClassName('active'); this.$$('.arrow').each(function(el) { el.hide(); } ); this.$$('.arrow.arrowFill'+frame).setStyle({display: 'block'}); this.$$('.arrow.arrowBorder').setStyle({display: 'block'}); this.position(); this._notify_listeners('enterframe', frame); }, //////// to_screen: function(screen) { this.$$('.screen').each(function(el) { el.hide(); } ); if(!screen) return; this.$$('.screen.screen_'+screen).setStyle({display: 'block'}); }, //////// show_error: function(msg) { this.to_screen('err'); this.$$('.screen_err .lbl').innerHTML = 'Error: ' + msg; }, //////// begin_cnt_down: function() { var self = this; var lbl = this.$$('.screen_alt .lbl'); var cnt = 3; this.to_screen('alt'); lbl.innerHTML = 'READY?'; this._cnt_down_id = setTimeout(function() { if(self._cnt_down_id === false) return; if(cnt == 0) { self.stop_cnt_down(); self._notify_listeners('cntdowncomplete'); } else { lbl.innerHTML = cnt--; self.cnt_down_id = setTimeout(arguments.callee, 500); } }, 1000); this._notify_listeners('cnt_down'); }, //////// stop_cnt_down: function() { if(this._cnt_down_id === false) return; clearTimeout(this._cnt_down_id); this._cnt_down_id = false; this.$$('.screen_alt .lbl').innerHTML = ''; }, //////// _notify_listeners: function(type, data) { if(!this._listeners[type]) return; for(var i = 0, len = this._listeners[type].length;i < len;i++) { this._listeners[type][i](data); } }, //////// _embed_swf: function() { var id = bf_react_cam_swfinterface.prep_swf(this, UPLOAD_URL); if(!id) return; bf_react_cam_swfinterface.to_swf($(id)); }, //////// /* 0: Disable 1: Active 2: Hide */ _change_record_btn_state: function(s) { var self = this; var btn = this.$$('.record_btn'); if (s == 0) { if (btn.hasClassName('green')) { btn.removeClassName('green'); } if (!btn.hasClassName('red')) { btn.addClassName('red'); btn.addClassName('disable'); } btn.show(); } else if (s == 1) { if (!btn.hasClassName('green')) { btn.addClassName('green'); btn.removeClassName('disable'); } if (btn.hasClassName('red')) { btn.removeClassName('red'); } btn.show(); } else if (s == 2) { btn.hide(); } }, _observe: function() { if(this._is_observing) return; this._is_observing = true; var self = this; this.$$('.frame1').observe('click', function(evt) { evt.stop(); self.jumpto_record(); }); this.$$('.record_btn').observe('click', function(evt) { if(!self._access_granted || self._is_saving || self._is_recording) return; self._change_record_btn_state(2); self.to_screen('crop'); self._is_recording = true; self.show_save_ctrl(false); self.begin_cnt_down(); bf_react_cam.track('record_button'); }); this.add_listener('cntdowncomplete', function() { self.to_screen('crop'); self._notify_listeners('record'); bf_react_cam_swfinterface.invoke(self.id, 'record'); }); this.$$('.save_ctrl').observe('click', function(evt) { if(self._is_saving) return; var target = evt.findElement('a'); if(target.hasClassName('save_btn')) { var user = new BF_User(); var target = $$('#react_cam_button a')[0]; bf_badge_popup.set_active(false); if(!user.isLoggedIn()) { var self_click = this; var fn = arguments.callee; bf_login.loggedInCallbacks.push(function() { fn.call(self_click, evt); }); var ev = target.fire('click'); ev.signin_type = 'initial'; ev.mode = 'badges'; ev.location = 'react_cam'; signin.open(ev); return; } self.to_screen('alt'); self.$$('.screen_alt .lbl').innerHTML = 'Saving ...'; self._notify_listeners('save'); self._is_saving = true; self.show_save_ctrl(false); bf_react_cam_swfinterface.invoke(self.id, 'save'); bf_react_cam.track('save_button'); } else if(target.hasClassName('restart_btn')) { self.show_save_ctrl(false); bf_react_cam_swfinterface.invoke(self.id, 'video'); self.begin_cnt_down(); bf_react_cam.track('clear_button'); } }); bf_react_cam_swfinterface.add_listener(this.id, 'error', function(type) { switch(type) { case 'buildfail': { self.show_error('Invalid Build Options'); } break; case 'nowebcam': { self.show_error('No Webcam Detected'); } break; case 'deniedwebcam': { self.show_error('Webcam Access Required'); } break; case 'savefail': { self._is_saving = false; self.show_error('Could Not Save'); } break; } }); bf_react_cam_swfinterface.add_listener(this.id, 'webcam_access_granted', function() { self.to_screen('call_to_action'); self._access_granted = true; self._change_record_btn_state(1); }); bf_react_cam_swfinterface.add_listener(this.id, 'record_complete', function() { self._is_recording = false; self._notify_listeners('record_complete'); self.show_save_ctrl(true); bf_react_cam_swfinterface.invoke(self.id, 'preview'); }); bf_react_cam_swfinterface.add_listener(this.id, 'save_complete', function(data) { var image; var success = true; try { image = data.evalJSON(); } catch(e) { success = false; } self._is_saving = false; if(success) { self._notify_listeners('save_success', image); } else { self.show_error('Could Not Save'); } }); } }; return { init: function() { }, create: function(){ return new ReactCam(); }, track: function(a) { return track(a); } }; })(); BuzzLoader.register(bf_react_cam.init, 5); /** * SWF Interface */ var bf_react_cam_swfinterface = { _listeners: {}, _is_ready: {}, //////// to_swf: function(element, fn) { var params = unserialize(element.readAttribute('data-params')); var attrs = unserialize(element.readAttribute('data-attrs')); var flashvars = unserialize(element.readAttribute('data-flashvars')); var so = new SWFObject( element.readAttribute('data-swf'), element.readAttribute('data-name'), element.readAttribute('data-width'), element.readAttribute('data-height'), element.readAttribute('data-version') || '9.0.0', element.readAttribute('data-background-color') || '#FFFFFF' ); for(var p in params) so.addParam(p, params[p]); for(p in flashvars) so.addVariable(p, flashvars[p]); so.write(element.id); return so; function unserialize(s){ return s ? ('{"'+decodeURI(s.replace(/&/g, '","').replace(/=/g,'":"'))+'"}').evalJSON() : {}; } }, //////// prep_swf: function(o, url) { var wrapper_id = 'gogif_wrapper_' + o.id; this._is_ready[o.id] = false; if($(wrapper_id)) $(wrapper_id).innerHTML = ''; var wrapper = o.$$('.gogif_wrapper'); var flashvars = wrapper.readAttribute('data-flashvars'); flashvars += (flashvars ? '&' : '') + 'externalid=' + o.id; flashvars += '&jsinterface=bf_react_cam_swfinterface._swf_invoke'; flashvars += '&url=' + encodeURIComponent(url); wrapper.id = wrapper_id; wrapper.writeAttribute('data-name', 'gogif_' + o.id); wrapper.writeAttribute('data-flashvars', flashvars); return wrapper_id; }, //////// invoke: function(id, name) { var swf = this._get_swf(id); if(!swf) return; var args = Array.prototype.slice.call(arguments, 2); this._when_ready(id, function() { swf.jsinterface(name, args); }); }, //////// add_listener: function(id, name, fn) { this._listeners[id] = this._listeners[id] || []; this._listeners[id].push({name: name, fn: fn}); }, //////// remove_listener: function(id, name, fn) { if(!this._listeners[id]) return; for(var i = this._listeners[id].length;i--;) { if(this._listeners[id][i].name == name && this._listeners[id][i].fn == fn) { this._listeners[id].splice(i, 1); break; } } }, //////// _swf_invoke: function(id, name, args) { if(!this._listeners[id]) return; args = args || []; var listeners = this._listeners[id].slice(); if(name == 'swf_ready') this._is_ready[id] = true; for(var i = 0;i < listeners.length;i++) { if(listeners[i].name == name) { listeners[i].fn.apply(null, args); } } }, //////// _when_ready: function(id, fn) { if(this._is_ready[id]) setTimeout(fn, 0); else { var self = this; this.add_listener(id, 'swf_ready', function() { self.remove_listener(id, 'swf_ready', arguments.callee); self._is_ready[id] = true; fn(); }); } }, //////// _get_swf: function(id) { return document.getElementById('gogif_' + id); } };