UNPKG

elation-engine

Version:
514 lines (460 loc) 17.1 kB
elation.require([ "ui.panel", "share.picker", "share.targets.imgur", "share.targets.dropbox", "share.targets.googledrive", "share.targets.youtube", "share.targets.file", "share.targets.facebook"], function() { elation.requireCSS(["engine.sharing"]); elation.component.add('engine.sharing', function() { this.init = function() { elation.engine.sharing.extendclass.init.call(this); this.client = this.args.client; } this.showShareDialog = function() { if (!this.dialog) { this.dialog = elation.engine.sharing.dialog({append: document.body, client: this.client, anchor: this.args.anchor}); } else { this.dialog.show(); } } this.share = function(data) { this.showShareDialog(); this.dialog.share(data); } }, elation.ui.base); elation.component.add('engine.sharing.dialog', function() { this.init = function() { this.client = this.args.client; this.anchor = this.args.anchor; var bottom = 100; this.args.title = 'Sharing Options'; this.args.right = true; this.args.bottom = bottom; this.args.minimize = false; this.args.maximize = false; this.args.resizable = false; elation.engine.sharing.dialog.extendclass.init.call(this); this.addclass('engine_sharing'); this.initPicker(); this.sharetypes = { link: elation.engine.sharing.share_link({client: this.client, picker: this.sharepicker}), screenshot: elation.engine.sharing.share_screenshot({client: this.client, picker: this.sharepicker}), screenshot360: elation.engine.sharing.share_screenshot360({client: this.client, picker: this.sharepicker}), video: elation.engine.sharing.share_video({client: this.client, picker: this.sharepicker}), }; this.selected = 'link'; this.tabs = elation.ui.tabbedcontent({ append: this, items: [ { name: 'link', label: 'Link', content: this.sharetypes.link }, { name: 'screenshot', label: 'Screenshot', content: this.sharetypes.screenshot }, { name: 'screenshot360', label: '360 Screenshot', content: this.sharetypes.screenshot360 }, { name: 'video', label: 'Video', content: this.sharetypes.video, disabled: true }, ], selected: this.selected, events: { tab_change: elation.bind(this, function(ev) { this.selected = ev.data.name; }) } }); this.setcontent(this.tabs); } this.initPicker = function() { this.sharepicker = elation.share.picker({append: document.body}); var share = elation.config.get('share'), targets = share.targets || {}; for (var k in targets) { var target = targets[k]; if (!target.disabled && elation.share.targets[k]) { this.sharepicker.addShareTarget(elation.share.targets[k](target)); } } console.log('did the picker', this.sharepicker); } this.share = function(data) { var type = this.selected; console.log('sharetype', type, this.sharetypes[type], this.tabs) if (this.sharetypes[type]) { this.sharetypes[type].share(data); } } }, elation.ui.window); elation.component.add('engine.sharing.share_link', function() { this.init = function() { elation.engine.sharing.share_link.extendclass.init.call(this); this.client = this.args.client; this.janusweb = this.client.janusweb; /* this.link = elation.ui.input({ append: this, label: 'URL', value: this.janusweb.currentroom.url }); this.button = elation.ui.button({ append: this, label: 'Share' }); */ var fb = elation.html.create({tag: 'div', classname: 'fb-share-button'}); fb.dataset.href = 'https://web.janusvr.com/sites/' + this.janusweb.currentroom.url; // FIXME - this is definitely not the way to do it fb.dataset.layout = 'button_count'; this.container.appendChild(fb); var twitter = elation.html.create({tag: 'a', classname: 'twitter-share-button'}); twitter.href = "https://twitter.com/intent/tweet"; twitter.innerHTML = 'Tweet'; //twitter.dataset.size = 'large'; this.container.appendChild(twitter); this.addclass('engine_sharing_link'); setTimeout(elation.bind(this, function() { this.loadFacebook(); this.loadTwitter(); }), 10); } this.share = function(data) { } this.loadFacebook = function() { var clientid = elation.config.get('share.targets.facebook.clientid'); window.fbAsyncInit = elation.bind(this, function() { FB.init({ appId : clientid, xfbml : true, version : 'v2.8', status : true }); }); (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); } this.loadTwitter = function() { window.twttr = (function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0], t = window.twttr || {}; if (d.getElementById(id)) return t; js = d.createElement(s); js.id = id; js.src = "https://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); t._e = []; t.ready = function(f) { t._e.push(f); }; return t; }(document, "script", "twitter-wjs")); } }, elation.ui.panel_horizontal); elation.component.add('engine.sharing.share_screenshot', function() { this.init = function() { elation.engine.sharing.share_screenshot.extendclass.init.call(this); this.client = this.args.client; this.picker = this.args.picker; var resolutions = ['(window)', '512x256', '1280x720', '1920x1080', '3840x2160', '7680x4320']; var formats = ['png', 'jpg']; var panel = elation.ui.panel_horizontal({ append: this }); this.resolution = elation.ui.select({ append: panel, label: 'Resolution', classname: 'engine_sharing_screenshot_resolution', items: resolutions, selected: resolutions[0] }); this.format = elation.ui.select({ append: panel, label: 'Format', items: formats, selected: 'png' }); this.button = elation.ui.button({ append: panel, label: 'Capture', events: { //click: elation.bind(this, this.share) } }); elation.events.add(this.button, 'click', elation.bind(this, this.share)); this.addclass('engine_sharing_screenshot'); } this.share = function() { var client = this.client; var width = window.innerWidth, height = window.innerHeight; if (this.resolution.value != '(window)') { var size = this.resolution.value.split('x'); width = size[0]; height = size[1]; } client.view.setrendersize(width, height); // Force a render after resizing client.view.render(0); client.screenshot({width: width, height: height, format: this.format.value}).then(elation.bind(this, function(data) { var imgdata = data.split(',')[1]; //data.image.data; var bytestr = atob(imgdata); var img = new Uint8Array(bytestr.length); for (var i = 0; i < bytestr.length; i++) { img[i] = bytestr.charCodeAt(i); } var mimes = { png: 'image/png', jpg: 'image/jpeg' }; client.player.disable(); this.picker.share({ name: this.getScreenshotFilename(this.format.value), type: mimes[this.format.value], image: img, }).then(elation.bind(this, function(upload) { //this.player.enable(); })); var now = new Date().getTime(); //console.log('finished png in ' + data.time.toFixed(2) + 'ms'); console.log('finished screenshot'); client.view.setrendersize(window.innerWidth, window.innerHeight); })); } this.getScreenshotFilename = function(extension) { if (!extension) extension = 'png'; var now = new Date(); function pad(n) { if (n < 10) return '0' + n; return n; } var prefix = elation.config.get('engine.screenshot.prefix', 'screenshot'); var date = now.getFullYear() + '-' + pad(now.getMonth() + 1) + '-' + pad(now.getDate()); var time = pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds()); var filename = prefix + '-' + date + ' ' + time + '.' + extension return filename; } }, elation.ui.panel_vertical); elation.component.add('engine.sharing.share_screenshot360', function() { this.init = function() { elation.engine.sharing.share_screenshot360.extendclass.init.call(this); this.client = this.args.client; this.picker = this.args.picker; this.xmlns = { 'GPano': 'http://ns.google.com/photos/1.0/panorama/' }; var mappings = ['equirectangular', 'cubemap'], resolutions = ['512', '1024', '2048', '4096', '8192'], formats = ['PNG', 'JPEG']; var panel = elation.ui.panel_horizontal({ append: this }); this.mapping = elation.ui.select({ append: panel, label: 'Type', items: mappings }); this.resolution = elation.ui.select({ append: panel, label: 'Resolution', selected: '4096', items: resolutions }); this.format = elation.ui.select({ append: panel, label: 'Format', items: formats }); this.button = elation.ui.button({ append: panel, label: 'Capture', events: { //click: elation.bind(this, this.share) } }); elation.events.add(this.button, 'click', elation.bind(this, this.share)); this.addclass('engine_sharing_screenshot360'); } this.share = function() { var client = this.client; var width = this.resolution.value, height = this.resolution.value / 2; var player = client.player, playervisible = player.visible; player.hide(); client.view.render(0); client.screenshot({type: 'equirectangular', format: 'jpg'}).then(elation.bind(this, function(data) { var imgdata = data.split(',')[1]; //data.image.data; var bytestr = atob(imgdata); var img = new Uint8Array(bytestr.length); var lastbyte = null; var inject = false; // merge the panorama exif data inito image binary data // XMP handling courtesy of https://github.com/panrafal/depthy/blob/master/app/scripts/classes/GDepthEncoder.js // FIXME - could be made more efficient! var offset = 0; for (var i = 0; i < bytestr.length; i++) { var byte = img[i+offset] = bytestr.charCodeAt(i); if (lastbyte == 0xff && (byte == 0xc0 || byte == 0xc2 || byte == 0xda)) { console.log('found exif thing', i); if (!inject) { inject = i-1; } } lastbyte = byte; } if (inject) { var xmp = this.getXMPBytes(data); offset = xmp.length; var newimg = new Uint8Array(bytestr.length + xmp.length); newimg.set(img.subarray(0, inject, 0)); newimg.set(xmp, inject); newimg.set(img.subarray(inject), inject + offset); img = newimg; } player.visible = playervisible; player.disable(); this.picker.share({ name: this.getScreenshotFilename('jpg'), type: 'image/jpg', image: img, //imageb64: data, width: width, height: height, }).then(elation.bind(this, function(upload) { //this.player.enable(); })); })); } this.getXMPBytes = function(data) { var xmp = { 'GPano:ProjectionType': 'equirectangular', }; var xmpStr = this.getXMPString(xmp); var xmpData= this.buildXMPsegments(xmpStr); var len = 0; for (var i = 0; i < xmpData.length; i++) { len += xmpData[i].length; } var bytes = new Uint8Array(len); var offset = 0; for (var i = 0; i < xmpData.length; i++) { var d = xmpData[i]; for (var j = 0; j < d.length; j++) { bytes[offset++] = d[j]; } } return bytes; } this.getXMPString = function(props, xmlns) { var xmp = [], k; xmlns = xmlns || this.xmlns; xmp.push('<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.1.0-jc003">'); xmp.push('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">'); xmp.push('<rdf:Description rdf:about=""'); for (k in xmlns) { xmp.push(' xmlns:', k, '="', xmlns[k], '"'); } for (k in props) { // TODO html entities escaping xmp.push(' ', k, '="' + props[k] + '"'); } xmp.push(' /></rdf:RDF></x:xmpmeta>'); return xmp.join(''); } this.buildXMPsegments = function(standardXMP) { var extendedUid, parts = []; console.log('StandardXMP: ', standardXMP.length); var xmpHeader = 'http://ns.adobe.com/xap/1.0/'; parts.push(new Uint8Array([0xFF, 0xE1])); parts.push(this.makeUint16Buffer([2 + xmpHeader.length + 1 + standardXMP.length])); parts.push(this.stringToUint8Array(xmpHeader), new Uint8Array([0x00])); parts.push(this.stringToUint8Array(standardXMP)); console.log('Written standardXMP'); return parts; }, this.makeUint16Buffer = function(arr, littleEndian) { var ab = new ArrayBuffer(arr.length * 2), dv = new DataView(ab); for (var i = 0; i < arr.length; ++i) { dv.setUint16(i * 2, arr[i], littleEndian); } return new Uint8Array(ab); } this.stringToUint8Array = function(str) { var arr = new Uint8Array(str.length); for (var i = 0; i < str.length; i++) { arr[i] = str.charCodeAt(i); } return arr; } this.getScreenshotFilename = function(extension) { if (!extension) extension = 'jpg'; var now = new Date(); function pad(n) { if (n < 10) return '0' + n; return n; } var prefix = elation.config.get('engine.screenshot.prefix', 'screenshot'); var date = now.getFullYear() + '-' + pad(now.getMonth() + 1) + '-' + pad(now.getDate()); var time = pad(now.getHours()) + ':' + pad(now.getMinutes()) + ':' + pad(now.getSeconds()); var filename = prefix + '-equirectangular-' + date + ' ' + time + '.' + extension return filename; } }, elation.ui.panel); elation.component.add('engine.sharing.share_video', function() { this.init = function() { elation.engine.sharing.share_video.extendclass.init.call(this); this.client = this.args.client; this.addclass('engine_sharing_video'); } this.share = function(data) { } }, elation.ui.panel); elation.component.add('engine.sharing.sharebutton', function() { this.init = function() { var type = this.args.type, picker = this.args.picker; var targets = picker.getTargetsForType(type); var button = elation.ui.button({ append: this, label: 'Share on' }); this.targets = elation.ui.select({ append: this, items: targets }); } }, elation.ui.panel_horizontal); elation.component.add('engine.sharing.config', function() { this.init = function() { this.args.orientation = 'vertical' elation.engine.sharing.config.extendclass.init.call(this); this.client = this.args.client; this.engine = this.client.engine; this.view = this.client.view; var sharepanel = elation.ui.panel({ orientation: 'vertical', classname: 'engine_config_section', append: this }); var sharepicker = this.client.sharepicker; if (!sharepicker) { this.client.createSharePicker(); sharepicker = this.client.sharepicker; } /* var foo = sharepicker.showTargetSelector('image/png', sharepanel).then(function(f) { console.log('mfing ya', f); }); */ // Capture Settings /* var capturelabel = elation.ui.labeldivider({ append: capturepanel, label: 'Capture Settings' }); var codec = elation.ui.select({ append: capturepanel, label: 'Codec', items: ['h264','gif'] }); var fps = elation.ui.select({ append: capturepanel, label: 'FPS', items: [5,10,25,30,45,60] }); */ } }, elation.ui.panel); });