Skip to content

Instantly share code, notes, and snippets.

@newhouseb
Last active September 19, 2018 23:04
Show Gist options
  • Save newhouseb/0f57f086584733bd6e4a531d1fe44480 to your computer and use it in GitHub Desktop.
Save newhouseb/0f57f086584733bd6e4a531d1fe44480 to your computer and use it in GitHub Desktop.
view.bubb.li scratch
<div class="metadata" style="display: none;"></div>
<div data-lang="md" data-visibility="output" data-autorun="false" class="block hide-source" data-source-visibility="hidden">
<pre class="source hljs coffeescript" contenteditable="true"><span class="hljs-comment"># view.bubb.li scratch</span>
First, let<span class="hljs-string">'s see if we can get access to the major shared link properties via CORS.</span></pre>
<div class="result"><h1 id="viewbubbliscratch">view.bubb.li scratch</h1>
<p>First, let's see if we can get access to the major shared link properties via CORS.</p></div>
</div><div data-lang="js" data-visibility="source" data-autorun="true" class="block">
<pre class="source hljs cs" contenteditable="true"><span class="hljs-keyword">var</span> GooglePageURL = <span class="hljs-string">'https://photos.google.com/share/AF1QipOaG3Ys97bMVpvkcHlI8LqHtXZzyJ6Bq4mM6IgU4EvKMp21vY4k-JKwEw41WEF8eA/photo/AF1QipPfS44hOHZI0TXkyW_DSomYQBm5s2KqKZDig5MR?key=LUIzR0EyTWd5SFkweTl6dk9tRjJLWHAzYm8yNHhn'</span>;
<span class="hljs-keyword">var</span> GoogleRawURL = <span class="hljs-string">'https://lh3.googleusercontent.com/UXA8tD35xweXj84Da4HhhrJcmAXBg9hc7oriL4ewhHLMjgT6T73XAsQw9ImkWKzjywRy8e_mtxwMA3Y_yUL_3CYa1oK95Qzn2a05SgKc_MhrTYpLVn0_XWnoUJoIcjs61_nt2xk8FVOLQl3gQUDfYzYW98WWN3p7MFaFYY1xs_9jARlNUw2FY_ZmJgytBycTkCmYEpPSy4noIqgLLot8e2lxsK0KQgxwfkTsUPp0uSKg2JPaPKXMn2ODPxeikS-y3VuF2IVYWGDg0Q4FL6q-4X7SVAnj7lX7238__AeJq_jvum0TLddZrrZQElxRGdtegA4c3BpdSEVW5Bz3aW8zNC98pcw2h8xblGyuL5gy34gYCbNcoFmqtlzMrX_gjodl3kx0ss1H3lnrxS0TyFtzX6PX3bCLWSFYor0BtRSBr2oAViuAXa-yU2-TdV_bHPC8v6BpoCzgo_aw2ToMS9rzLTtnRBvOSQMmwQ6HTyoAC5R9sw9k_Zbi7EWPVnc8LByXUrxi2tb2f3aJzjsuGlxYTDIhWFhfS6ZtKV6H6NWUSF8n4SxfzYfTSi347UQdIj2xxowSp9i8Mwas_jPWcV3cbFUBzb1L71ZUiMIZQmKX40WNBIUDMMVsovm0acaE97Ix7-CD_lWkQy_Gr5qJh-gKdtnGr4usQmWvplbtyxXkimea6mpc7KcKKj903A=s0'</span>;
window.DropboxSharedLink = <span class="hljs-string">'https://www.dropbox.com/s/7ojbvogtltrx7on/Equirectangular.jpg?dl=0'</span>.replace(<span class="hljs-string">'www.dropbox.com'</span>, <span class="hljs-string">'dl.dropboxusercontent.com'</span>).replace(<span class="hljs-string">'dl=0'</span>, <span class="hljs-string">'dl=1'</span>);
console.log(DropboxSharedLink)
<span class="hljs-comment">// Since AJAX requests are asynchronous, we have to do a little bit of gymnastics</span>
<span class="hljs-comment">// to make sure Pocketbook can get ahold of the results. Note that we're doing an</span>
<span class="hljs-comment">// AJAX request rather than an image load here because the image might not by default</span>
<span class="hljs-comment">// include the right CORS headers so that we could actually access the pixel data.</span>
<span class="hljs-keyword">var</span> promise = <span class="hljs-keyword">new</span> Promise(function(resolve, reject) {
<span class="hljs-keyword">var</span> xhttp = <span class="hljs-keyword">new</span> XMLHttpRequest();
xhttp.onreadystatechange = function() {
<span class="hljs-keyword">if</span> (xhttp.readyState == <span class="hljs-number">4</span>) {
resolve(xhttp.status);
}
};
xhttp.open(<span class="hljs-string">'GET'</span>,&nbsp;DropboxSharedLink);
xhttp.send();
});
promise
</pre>
<div class="result">200</div>
</div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs coffeescript" contenteditable="true">Okay, so Dropbox <span class="hljs-keyword">is</span> a <span class="hljs-literal">yes</span> but everything <span class="hljs-keyword">else</span> <span class="hljs-keyword">is</span> a <span class="hljs-literal">no</span> <span class="hljs-keyword">unless</span> we set up a proxy to <span class="hljs-keyword">do</span> either <span class="hljs-keyword">do</span> the reprojection <span class="hljs-keyword">or</span> add CORS headers so we can <span class="hljs-keyword">do</span> things <span class="hljs-keyword">from</span> our end. Let<span class="hljs-string">'s now make a canvas to handle the output of the reprojection.</span></pre><div class="result"><p>Okay, so Dropbox is a yes but everything else is a no unless we set up a proxy to do either do the reprojection or add CORS headers so we can do things from our end. Let's now make a canvas to handle the output of the reprojection.</p></div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="true" class="block"><pre class="source hljs javascript" contenteditable="true"><span class="hljs-keyword">var</span> canvas = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'canvas'</span>);
canvas.width = <span class="hljs-number">600</span>;
canvas.height = <span class="hljs-number">300</span>;
<span class="hljs-built_in">window</span>.ctx2 = canvas.getContext(<span class="hljs-string">"2d"</span>);
ctx2.beginPath();
ctx2.rect(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">600</span>, <span class="hljs-number">300</span>);
ctx2.fillStyle = <span class="hljs-string">"red"</span>;
ctx2.fill();
canvas
</pre><div class="result"><canvas width="600" height="300"></canvas></div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs cs" contenteditable="true">Ok, now <span class="hljs-keyword">let</span><span class="hljs-string">'s draw our equirectangular to double check we can get access to the pixel data.</span></pre><div class="result"><p>Ok, now let's draw our equirectangular to double check we can get access to the pixel data.</p></div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="true" class="block"><pre class="source hljs cpp" contenteditable="true"><span class="hljs-comment">// Note this is a bit different than the usual document.createElement('img')</span>
<span class="hljs-comment">// approach which wouldn't add the right CORS headers</span>
var downloadedImg = <span class="hljs-keyword">new</span> Image;
downloadedImg.crossOrigin = <span class="hljs-string">"Anonymous"</span>;<div>var promise = new Promise(function(resolve, reject) {
downloadedImg.addEventListener(<span class="hljs-string">"load"</span>, function() {
window.ew = downloadedImg.width;
window.eh = downloadedImg.height;
var canvas = document.createElement(<span class="hljs-string">'canvas'</span>);
canvas.width = downloadedImg.width;
canvas.height = downloadedImg.height;
var ctx = canvas.getContext(<span class="hljs-string">"2d"</span>);
ctx.drawImage(downloadedImg, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, downloadedImg.width, downloadedImg.height);
ctx2.drawImage(downloadedImg, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">600</span>, <span class="hljs-number">300</span>);
window.eqData = ctx.getImageData(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, downloadedImg.width, downloadedImg.height).data;</div><div> resolve(1);
}, <span class="hljs-literal">false</span>);</div><div>});
downloadedImg.src = DropboxSharedLink;
</div><div>promise</div></pre><div class="result" style="">1</div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs sql" contenteditable="true">Ok, now lets generate a cube side, computing the lat/lng for each point on the cube side and sample it out.</pre><div class="result"><p>Ok, now lets generate a cube side, computing the lat/lng for each point on the cube side and sample it out.</p></div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="true" class="block"><pre class="source hljs php" contenteditable="true"><span class="hljs-keyword">var</span> s = <span class="hljs-number">512</span>;
<span class="hljs-keyword">var</span> pixels = <span class="hljs-keyword">new</span> Uint8ClampedArray(s * s * <span class="hljs-number">4</span>);
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">norm</span><span class="hljs-params">(c)</span> </span>{
<span class="hljs-keyword">var</span> n = Math.sqrt(c[<span class="hljs-number">0</span>]*c[<span class="hljs-number">0</span>] + c[<span class="hljs-number">1</span>]*c[<span class="hljs-number">1</span>] + c[<span class="hljs-number">2</span>]*c[<span class="hljs-number">2</span>]);
<span class="hljs-keyword">return</span> [c[<span class="hljs-number">0</span>]/n, c[<span class="hljs-number">1</span>]/n, c[<span class="hljs-number">2</span>]/n];
}
window.makeSide = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(sideFunction)</span> </span>{
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> y = <span class="hljs-number">0</span>; y &lt; s; y++) {
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> x = <span class="hljs-number">0</span>; x &lt; s; x++) {
<span class="hljs-keyword">var</span> c = norm(sideFunction(x, y));
<span class="hljs-keyword">var</span> lng = - Math.atan2(-c[<span class="hljs-number">2</span>], -c[<span class="hljs-number">0</span>]) - Math.PI / <span class="hljs-number">2</span>;
<span class="hljs-keyword">var</span> p = norm([c[<span class="hljs-number">0</span>], <span class="hljs-number">0</span>, c[<span class="hljs-number">2</span>]]);
<span class="hljs-keyword">var</span> lat = (c[<span class="hljs-number">1</span>] &lt; <span class="hljs-number">0</span> ? <span class="hljs-number">-1</span> : <span class="hljs-number">1</span>)*Math.acos(p[<span class="hljs-number">0</span>]*c[<span class="hljs-number">0</span>] + p[<span class="hljs-number">2</span>]*c[<span class="hljs-number">2</span>]);
<span class="hljs-comment">// <span class="hljs-doctag">TODO:</span> Add a bilinear sampling here rather than round</span>
<span class="hljs-keyword">var</span> ex = Math.round(ew*((lng + <span class="hljs-number">2</span>*Math.PI) % (<span class="hljs-number">2</span>*Math.PI))/(<span class="hljs-number">2</span>*Math.PI));
<span class="hljs-keyword">var</span> ey = Math.round(eh*(lat/Math.PI + <span class="hljs-number">0.5</span>));
pixels[<span class="hljs-number">4</span>*(s*y + x) + <span class="hljs-number">0</span>] = eqData[<span class="hljs-number">4</span>*(ew*ey + ex) + <span class="hljs-number">0</span>];
pixels[<span class="hljs-number">4</span>*(s*y + x) + <span class="hljs-number">1</span>] = eqData[<span class="hljs-number">4</span>*(ew*ey + ex) + <span class="hljs-number">1</span>];
pixels[<span class="hljs-number">4</span>*(s*y + x) + <span class="hljs-number">2</span>] = eqData[<span class="hljs-number">4</span>*(ew*ey + ex) + <span class="hljs-number">2</span>];
pixels[<span class="hljs-number">4</span>*(s*y + x) + <span class="hljs-number">3</span>] = <span class="hljs-number">255</span>;
}
}
}
<span class="hljs-keyword">var</span> sideFunctions = {
PX: (x, y) =&gt; [-y*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>, x*<span class="hljs-number">2</span>/s - <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>],
NX: (x, y) =&gt; [-y*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>, -x*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>, <span class="hljs-number">1</span>],
PY: (x, y) =&gt; [<span class="hljs-number">1</span>, -y*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>, -x*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>],
NY: (x, y) =&gt; [<span class="hljs-number">-1</span>, y*<span class="hljs-number">2</span>/s - <span class="hljs-number">1</span>, - x*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>],
PZ: (x, y) =&gt; [-y*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, - x*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>],
NZ: (x, y) =&gt; [-y*<span class="hljs-number">2</span>/s + <span class="hljs-number">1</span>, <span class="hljs-number">1</span>, x*<span class="hljs-number">2</span>/s - <span class="hljs-number">1</span>],
}
<span class="hljs-keyword">var</span> canvas = document.createElement(<span class="hljs-string">'canvas'</span>);
canvas.width = s;
canvas.height = s;<div><br></div><div>window.sideImage = function(sideFunction) {</div><div> makeSide(sideFunction);</div><div> var data = new ImageData(pixels, s, s);
canvas.getContext(<span class="hljs-string">"2d"</span>).putImageData(data, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
return canvas.toDataURL(); <span class="hljs-comment">// With no params this will dump a png which is pretty fast</span></div><div>}</div><div><br></div><div>window.sides = {</div><div> PX: sideImage(sideFunctions.PX),</div> NX: sideImage(sideFunctions.NX),
PY: sideImage(sideFunctions.PY),
NY: sideImage(sideFunctions.NY),
PZ: sideImage(sideFunctions.PZ),
NZ: sideImage(sideFunctions.NZ),
<div>}</div><div><br></div><div>canvas
</div></pre><div class="result" style=""><canvas width="512" height="512"></canvas></div></div><div data-lang="md" data-source-visibility="hidden" data-result-visibility="visible" data-autorun="false" class="block hide-source"><pre class="source hljs sql" contenteditable="true">Alright, now we can assemble a bubble viewer of sorts.</pre><div class="result"><p>Alright, now we can assemble a bubble viewer of sorts.</p></div></div><div data-lang="deps" data-source-visibility="visible" data-result-visibility="hidden" data-autorun="true" class="block hide-result"><pre class="source hljs bash" contenteditable="true">https://bubb.li/lib/bubblekit-09192018.js
</pre><div class="result" style="display: none;">[object Event]</div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="true" class="block"><pre class="source" contenteditable="true">var bubbleDiv = document.createElement('div')
bubbleDiv.style.width = "400px";
bubbleDiv.style.height = "400px";<div>bubbleDiv.id = "bubble"<br><div>bubbleDiv</div></div></pre><div class="result"><div id="bubble" style="width: 400px; height: 400px; position: relative;"><canvas width="800" height="800" style="width: 400px; height: 400px;"></canvas><div class="clickBlocker" style="width: 100%; height: 100%; position: absolute; top: 0px; left: 0px;"></div></div></div></div><div data-lang="js" data-source-visibility="visible" data-result-visibility="visible" data-autorun="true" class="block"><pre class="source" contenteditable="true"><div>// The bubble el needs to be already part of the DOM for reasons I don't remember...</div>window.bubble = new bubbli.Bubble({
src_px: sides.PX,
src_nx: sides.NX,<br> src_py: sides.PY,<br> src_ny: sides.NY,<br> src_pz: sides.PZ,<br> src_nz: sides.NZ,<br> id: 'bubble'
});</pre><div class="result">[object Object]</div></div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment