Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Teino1978-Corp/d9a8bab00e3ae4b314cb to your computer and use it in GitHub Desktop.
Save Teino1978-Corp/d9a8bab00e3ae4b314cb to your computer and use it in GitHub Desktop.
Obelisk Buildr with Image Support
<header><h1><span>obelisk</span> buildr</h1>
<aside id="auth">
<button class="login is-hidden"><span>log in</span><span class="icon icon-github"></span></button>
<button class="logged is-hidden" title="connected to github"><span class="icon icon-github"></span></button>
</aside>
</header>
<div id="help" class="pane">
<ul>
<li><p><b>B</b>: Brush tool.</p></li>
<li><p><b>E</b>: Erase tool.</p></li>
<li><p><b>spacebar</b>: Color palette.</p></li>
<li><p><b>←</b>, <b>→</b>: Rotate view.</p></li>
<li><p><b>+</b>, <b>-</b>, <b>scroll</b>: Move draw layer up / down.</p></li>
<li><p><b>CTRL + Z</b>: Undo.</p></li>
<li><p><b>CTRL + S</b>: Save to gist.</p></li>
<li><p><b>N</b>: New art.</p></li>
<li><p><b>F</b>: Full canvas.</p></li>
<li><p><b>H</b>: Toggle this thing.</p></li>
</ul>
</div>
<main>
<h2 class="select">Select an icon to be displayed using the <strong>ObeliskBuilder</strong></h2>
<ul class="thumbnails">
<li class="active"><a href="#"><img src="data:image/gif;base64,R0lGODlhFAAUANUAAAAAAP///+/3997e1tbWzv/nIf/eEP/eGPfWGO/OGPfOAP/WCNa1EM6tEKWMEOfGGOe9EN61EMalELWUEO/GGL2UCKWECKWce9alCLWMCK2ECJRzCN6tEJx7EGNSGHNjMZyUe86cCL2MCKV7CIxrCGtSCKWchIxjANacCJxzCHNjOXtrQmtKCGNKGGtSIZSEY3tjOaWUe9bOxufn5////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAADQALAAAAAAUABQAAAbRwIBwSCwaiQKCadVqrUwEwVE4i5UcjASlYSnFZkeCqpNAHA4IRAKyURGKA5cEUajb1Y+MazAUvCZ0dnZoayMvUgEAiouMjYtCMYpCjpOLMUIwDI51jhUwQh4PB4yCjBAhHqAPZoKtBgoRqJgNga11aA8cIp8BMQ5ltgWEEBgpIEIyJRDAggcGCbkhLDJCfhYPZYwL0BHFh0NxExDYCQkKDxAcGBoefEQEHyQcERAQEeohJx9vRlUsKSIwoBCRgsWXKQEEyLigoomKCzIQIZxIJAgAOw==" alt=""></a></li>
<li><a href="#"><img src="data:image/gif;base64,R0lGODlhFAAUAKIAAAAAAP///+3u7wByvP///wAAAAAAAAAAACH5BAEAAAQALAAAAAAUABQAAAMpOLrc/jDKOYS9VF2ct82VJ3kkx5Slg5LqurXu18Tmw3Yi/uo16P/AQQIAOw==" alt=""></a></li>
<li><a href="#"><img src="data:image/gif;base64,R0lGODlhFAAUAPcAAORkE/F+GN1aHfOMMvqFDeelefWJIut6J/Gvg/upVthOF/aMKedtIeyBN//69eN7OvaLJul1KuiGPveJHOt1JfXh1fGBJ/3RpvOIKeeEOuaFOOCCQeWAOeNpIex5JdtVHd1bFvWGH/OFH//17fulTtlLC/7t3+52FOhxIviQK/qQJPeOK+WKQ/WLK+uKPuqJO/zMm+eHOe16JetxGuJlIf6aLvuWL/uULfqSK/iRLPiNJfKHKvKFJeaDOvGBKOWDOOSAN+V9POR+N+N9OeJ7OOt3I+RrGPuWLP3q2OBhH/mTLPqUK+eDPOiGO+58Ju93FuaidfjAk+F9N/Xj2+98JuymhfGodu14IOJ8NeWAPP/38Pi5gfmSK/SJKuJ5OPuUJ+SecO98IPqYNfR8CuFiGO98Hv3x6PioXfvIlvvRq/F5D9tTEvi3ff/37/e4hfuSJfbn4fSJKPe3f/KEKeR8O+55HfOUQPCEJvzy7f/+/vKaUu11Fe6ke/mLHOdqFeNfDeRpH+ZrHeSZZe59JvXj2falW/7s2/u/hut0GfecRvqdQfKCHPS0h/eHGeeIV+lyJN5lLvmVLO6TVfqTKd9hH/rj1vKeXOdsGutyH/yXLu12GPu9ge+BJu5wCvmSKfjWw+h9O/iGEvzAhPzr3+eGO/isaPbm3frawNtcIv3dwOF3NvWSN/iPK/mXNPehT+WBOuOCPvB4EuhvHt9TAd5YD99eGd1cH/qpWfysWv/+//B+IP7r2P3Wr+qbdffo3/R+DvKjad1XEvnXvPSOL/717t95NfmRJ+tpB+57JfuSJv7p0/qPIfyWK+KGRNlQF/CMQPqTLPe8ifSLKfa2gv7v4vzv5vGFKfKHKOWbaOWdbu96GeaHPfOVRvXKsfXMtfKGJ/fKqNxUGP7+/+iFTf///vGYVt5aEvaNKueFO/eydv338vvdxPuMGPe1fOdoEPu4dON+Nv/u3u+nfOF8PuVqHvmPJOBdEPKIKuR/OeWbZ+mHOumHO/fq4vzq2+99Jv///yH5BAAAAAAALAAAAAAUABQAAAj/AP/xgwJLCAcOr3qgQ9dE374XL7Zlm/LP1wYjgS5h8jDIgrUdXVakuGEjkwEpFQoYARShwQFEe8rcwRBnQQolS47UMCCoGQMAVsz0EzaN2yIRInEeOQItBSksj9wx+kf1n4M0iSZ4irSUywIMLuBRmFEO3ClqVbVsUvGF6YJvFlwAkSFDU6dY90qlqnrhjbFz1zhRkQDESR09bAoN+zXhHTGqFwzw8IHMA2EfT6JRNYGmFQES8ai2e+KkyCMmP3YEkFP1n6EEn0f8I/ZsBgoGqDHwWHXmEBKqbRKMSUcVnB96HbJoaCENQqNQk2CI+2digLZ1/9SBIkMjiIYV53SIuSGRjB0MqlGOASP3jw+tJN5z6FCkLBevehB+j/IQodo/b8EIQEcMN/QhSlWuqOHGP3lI8scn/1RiSzgPxGDDMrg48M8uA5xgCVXyzNLNP3hAosADLDBzxBu3bGGHLlc0gAAC45jjSBW9oOLMAwWIUAMOIQQQBjJFyAKAPbVQskYJJSgAQj6mbCACK13M4Y8HFDDQAQ1JCCDABx+AUEwF/8ABBgtNoJNBD6/gM8QQRBDhhSrzYEPIPwEBADs=" alt=""></a></li>
<li><a href="#"><img src="data:image/gif;base64,R0lGODlhFAAUAOYAAAAAAP///8S0A0lDAUVAAUI9AePQBODOBN7MBNfFBM++BLKkA//qBf7pBf3oBfznBfvmBfjkBffjBfbiBfTgBfDcBe/bBerXBeXSBePRBeLQBd/NBcu6BMm5BMKyBLmqBJWJA5GFA42CA4h9A4Z7A/znBvvmBvTgBvPfBqmbBE1HAsW1BvTgCOvYCOjWCObUCODOB9jHB+zaCdnICMq6CMa3CKibB0tFA9vKCtLBCsCxCdfGC8+/DMa2C7aoCp6SCTYyA5mNCb2vDLytDLqsDLaoDMGyDYN5CbKkDaaaDaGVDYB2CjEuBJyQDZmNDXZtCl1WCCglBODNBOLPBV1VAvrlBu3ZBpiLBPbhB+7aB+PQB8m4Bsq5Bzs2AsCwB5GFB869C7ipCmtiBsu6DKudC7GiDZ+SDF5WB6SXDWRcCIp/DGZeCY2CDf8AAPr6+tXV1cvLy7CwsKysrIuLi4aGhnR0dG9vb11dXVhYWFNTUzMzMyUlJSAgIAwMDAUFBf///yH5BAEAAH8ALAAAAAAUABQAAAf/gAGCgm5yeHp+fnp4cm6Dj4JvegMgHxpSCyIFe3GQgnN9JBUUExMUFRcHV111kHVUChNVDw0NDxASFgYdKq2CcQQYEQ8AAAzHDcUWBx5AnW58KRPEgsYMANUXCSN8hQMVENiDxY8ACCtAcnchFA7iAHDF8QHxU1tid3wcE8lw9HLF5PwDoIHLlz1+MvC7BgfgMXgAUcCo8aOPnwPtHlrTWCXLDB1B+vARAK7BsZMnS2B5kSPMkT14RFyQQAslgwYmsMjA0YPMGUYFNliIAMDkTQdVWMgAAKZIkyiN+FzZYOVEsatXeQxBs6ZbADldvMTQ4qIFgDZtAOwYQySJGqiDOurcsEEjx46zaY0gUcIGiC9CdPqk8TFESLEySZykiWLHESRJTMQsMdPkCZQonDwNKpRHTzE9eRpBCgQAOw==" alt=""></a></li>
<li><a href="#"><img src="data:image/gif;base64,R0lGODlhFAAUAOYAAAAAAP////3+//z+//X8/83y/9n1/+n5/zPM/zTM/zXM/zXN/zfN/znN/znO/zrO/z7P/0TQ/0XQ/0XR/0fR/0jR/0vS/03S/03T/1DT/1HT/1TU/1bV/2HY/2jZ/2ra/27b/3jd/3re/3ze/4Lg/4Tg/4Xh/5Hj/5Hk/5rm/53n/6Dn/6Ho/6Po/6nq/6vq/7Ps/7bt/7nt/7ru/7zu/7/v/8Dv/8Pw/8ny/8zy/83z/87z/9Dz/9H0/9P0/9b1/9r2/9/3/+P4/+b5/+r6/+v6/+/7//P8//f9//H8//L8//b9//n+//3//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAE4ALAAAAAAUABQAAAeZgAGCg4SFhoeIiYdJPUOHTYg+FxEth0sjMQSERxgIDRsuhygIGitFgioIqqoshkEZqhQvSxWrqg0HhT4Oth0JtqomMzqENRbAyAgfPIQ2C8m2EiQ/hAI3GtCqNIgeDNAcTIJCSIQ4E8kMO4NDJyk0MCUQyQ8yhUQh2QgdzIc6IhUKVCWIAILGAEUBlAApkMOAEYQQI0qcSCgQADs=" alt=""></a></li>
</ul>
<div class="drop-zone"></div><span>&lt;-- or drop your 20x20 image here...</span>
<br><h2 class="currently">Currently Displaying: </h2><img class="drop-image" src="" />
<canvas id="myCanvas" width="20" height="20">
<!-- Insert fallback content here -->
</canvas>
<div id="buildr">
<canvas id="scene"></canvas>
</div>
<div id="palette" class="is-hidden">
<button class="red" data-tool="brush" data-value="#c82829">1</button>
<button class="orange" data-tool="brush" data-value="#f5871f">2</button>
<button class="yellow" data-tool="brush" data-value="#eab700">3</button>
<button class="green" data-tool="brush" data-value="#718c00">4</button>
<button class="aqua" data-tool="brush" data-value="#3e999f">5</button>
<button class="blue" data-tool="brush" data-value="#4271ae">6</button>
<button class="purple" data-tool="brush" data-value="#8959a8">7</button>
<button class="black" data-tool="brush" data-value="#4d4d4c">8</button>
<button class="white is-active" data-tool="brush" data-value="#eeeeee">9</button>
</div >
<div id="overlay" class="is-hidden"></div>
<div id="notification" class="is-hidden"></div>
<div id="help" class="pane is-hidden">
<ul>
<li><p><b>B</b>: Brush tool.</p></li>
<li><p><b>E</b>: Erase tool.</p></li>
<li><p><b>spacebar</b>: Color palette.</p></li>
<li><p><b>←</b>, <b>→</b>: Rotate view.</p></li>
<li><p><b>+</b>, <b>-</b>, <b>scroll</b>: Move draw layer up / down.</p></li>
<li><p><b>CTRL + Z</b>: Undo.</p></li>
<li><p><b>CTRL + S</b>: Save to gist.</p></li>
<li><p><b>N</b>: New art.</p></li>
<li><p><b>F</b>: Full canvas.</p></li>
<li><p><b>H</b>: Toggle this thing.</p></li>
</ul>
</div>
<div id="welcome" class="pane is-hidden">
<div class="content">
<h2>Welcome to obelisk buildr!</h2>
<p>This little experiment makes use of the great <a target="_blank" href="https://github.com/nosir/obelisk.js">obelisk.js</a> library.</p>
<ul>
<li><p>Everything is driven by shortcuts here, no UI, I'm lazy :)<br>
Press <b>H</b> to list all of them.</li>
<li><p>You can draw on 20 layers of height. Scroll your mouse up or down to adjust elevation.</p></li>
<li><p>Available tools are brush (<b>B</b>) and erase (<b>E</b>).</p></li>
<li><p>Press the <b>spacebar</b> to spawn a 9 colors palette. Colors are also
accessible form <b>1</b> to <b>9</b>. </p></li>
<li><p>Rotate the view with <b>←</b> and <b>→</b> arrow keys</p></li>
<li><p>Your work is automatically saved locally in the browser.<br>
Press <b>CTRL + S</b> to save it to a github gist.
If you log in, you will be able to fork and edit your own gists.
If not, anonymous gists will be created each time you save! So please consider logging in.</p></li>
<li><p>Press any key to continue...</p></li>
</ul>
</div>
</div>
</main>
<footer>
<a href="https://github.com/kostasx/obelisk-buildr/tree/image-dropper"><em>Github</em></a> | <a href="https://twitter.com/kostas_mns">Follow <strong>@kostas_mns</strong> on <em>Twitter</em></a>
<a href="https://github.com/ngryman/obelisk-builder"> // Original Source on <em>Github</em></a> |
<a href="http://twitter.com/ngryman">Follow <strong>@ngryman</strong> on <em>Twitter</em></a>
</footer>
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
// TODO: move this elsewhere
obelisk.Point3D.prototype.clone = function() {
return new obelisk.Point3D(this.x, this.y, this.z);
};
/**
* Module dependencies.
*/
var ui = require('./ui'),
tool = require('./tool'),
pointer = require('./pointer'),
history = require('./history'),
storage = require('./storage');
/**
* Private variables
*/
var canvasEl = document.getElementById('scene');
var persistLock = false;
var autoSaveTimeout;
var resizeTimeout;
var fullCanvased = false;
/**
* Module declaration.
*/
var app = {};
/**
* Shift Detect
*/
app.shiftHandler = false;
// Wow! What a bad, bad practice... Shame on me!
app.createPixelArray = function( imageDataArray, width, height ){
var pixelArray = []; // Array( width * height )
var initial = 0;
var tetarto = 0;
var x = 0;
var y = 0;
var z = 0;
$.each( imageDataArray.data, function( index, value ){
if ( index % 4 === 0 ){
pixelArray[initial] = { "x" : x, "y" : y, "z" : z, "c" : value.toString()[0], "rgba": [value] };
tetarto = 0;
initial++;
x++;
if ( x % 20 === 0 && index !== 0 ){
// console.log(index, y);
x = 0;
y = ( y + 1 );
}
} else {
pixelArray[initial-1].rgba.push(value);
tetarto++;
}
});
return pixelArray;
};
app.getImageData = function( imageData, image, imageCtx ){
var pixelArray = this.createPixelArray( imageData, imageData.width, imageData.height );
pixelArray = { "colors":["0x333399","9999984","0xFFFFFF","15382272","15658734"], "data": pixelArray };
return pixelArray;
};
/**
*
*/
app.init = function() {
ui.auth.init();
ui.scene.init();
ui.welcome.init(function() {
ui.palette.init();
tool.init(ui.scene)
.use('brush');
pointer.init(ui.scene)
.click(tool.click)
.drag(tool.drag);
bindShortcuts();
bindScroll();
bindResize();
touchDisclaimer();
/*
// fetches initial art
storage.fetch(function(err, data, info) {
if (err) return ui.notification.error(err);
if (data) ui.scene.load(data);
if (info) ui.notification.info(info);
// auto save from now on
ui.scene.changed(onAutoSave);
});
*/
});
loadImage( "data:image/gif;base64,R0lGODlhFAAUANUAAAAAAP///+/3997e1tbWzv/nIf/eEP/eGPfWGO/OGPfOAP/WCNa1EM6tEKWMEOfGGOe9EN61EMalELWUEO/GGL2UCKWECKWce9alCLWMCK2ECJRzCN6tEJx7EGNSGHNjMZyUe86cCL2MCKV7CIxrCGtSCKWchIxjANacCJxzCHNjOXtrQmtKCGNKGGtSIZSEY3tjOaWUe9bOxufn5////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAADQALAAAAAAUABQAAAbRwIBwSCwaiQKCadVqrUwEwVE4i5UcjASlYSnFZkeCqpNAHA4IRAKyURGKA5cEUajb1Y+MazAUvCZ0dnZoayMvUgEAiouMjYtCMYpCjpOLMUIwDI51jhUwQh4PB4yCjBAhHqAPZoKtBgoRqJgNga11aA8cIp8BMQ5ltgWEEBgpIEIyJRDAggcGCbkhLDJCfhYPZYwL0BHFh0NxExDYCQkKDxAcGBoefEQEHyQcERAQEeohJx9vRlUsKSIwoBCRgsWXKQEEyLigoomKCzIQIZxIJAgAOw==" );
// HANDLE THUMBNAIL CHANGE
$(".thumbnails li").click(function(e){
var imgSrc = $(this).find("img").attr("src");
$(".thumbnails").find("li").removeClass('active');
$(this).addClass("active");
$("#myCanvas").show();
$(".drop-image").hide();
loadImage( imgSrc );
});
// HANDLE DRAG & DROP
$('html').on('dragenter dragover', function(e) { e.stopPropagation(); });
$('.drop-image').on('load', function() {
if ( this.naturalWidth > 20 || this.naturalHeight > 20 ) {
console.log("IMAGE TOO LARGE");
} else {
$("#myCanvas").hide();
$(".thumbnails li").removeClass("active");
loadImage( this.src );
$(this).show();
$('.drop-placeholder').hide();
}
});
$('.drop-zone')
.on('dragover', function() {
$(this).addClass('drop-over');
return false;
})
.on('dragleave', function() {
$(this).removeClass('drop-over');
return false;
})
.on('drop', function(e) {
if(e.originalEvent.dataTransfer){
if(e.originalEvent.dataTransfer.files.length) {
// $('.drop-image').hide();
$(this).removeClass('drop-over');
var file = e.originalEvent.dataTransfer.files[0];
if (!file || file.type.indexOf('image/') !== 0) {
console.log("NOT AN IMAGE");
} else {
if ( true ){
var reader = new FileReader();
reader.onload = function(e) {
$('.drop-image').attr('src', e.target.result );
};
reader.readAsDataURL(file);
}
}
e.preventDefault();
return false;
}
}
});
$('.drop-image, .drop-samples img').on('dragstart', function(e) {
e.preventDefault();
});
// logCurious();
};
/**
* @private
*/
function loadImage(imgSrc){
var imageData;
var imageCanvas = document.getElementById("myCanvas");
var imageCtx = imageCanvas.getContext("2d");
var image = new Image();
image.src = imgSrc;
$(image).load(function() {
imageCtx.drawImage(image, 0, 0, 20, 20);
imageData = imageCtx.getImageData(0, 0, 20, 20);
var output = app.getImageData( imageData, image, imageCtx );
storage.fetch(function(err, output, info) {
if (err) return ui.notification.error(err);
// if (output) ui.scene.load(output);
if (output) ui.scene.load( output, "rgba" );
if (info) ui.notification.info(info);
ui.scene.changed(onAutoSave); // auto save from now on
}, output );
});
}
/**
* @private
*/
function logCurious() {
console.log('Hey! Curious or having bugs?');
console.log('Please post ideas or issues here: https://github.com/ngryman/obelisk-buildr/issues.');
console.log('You can play with the window.scene object.');
if (console.table) {
var methods = {
snapshot: { description: 'Returns a base64 image of the current scene.' },
load: { description: 'Loads a scene. Same format as the art.json file in gists.' },
save: { description: 'Returns data associated with the current scene. Same format as the art.json file in gists.' }
};
console.table(methods);
}
}
/**
* @private
*/
function bindShortcuts() {
document.addEventListener('keydown', onKeyDown);
document.addEventListener('keyup', onKeyUp);
}
/**
* @private
*/
function bindScroll() {
var isFirefox = /Firefox/i.test(navigator.userAgent);
document.addEventListener(isFirefox ? 'DOMMouseScroll' : 'mousewheel', onScroll);
}
/**
* @private
*/
function bindResize() {
window.addEventListener('resize', onResize);
}
/**
* @private
*/
function touchDisclaimer() {
var isChrome = /chrome/i.exec(navigator.userAgent),
isAndroid = /android/i.exec(navigator.userAgent),
hasTouch = 'ontouchstart' in window && !(isChrome && !isAndroid);
if (hasTouch)
ui.notification.error('Hey! For now, there is no real support for touch devices. Yeah i know...');
}
/**
* @param {boolean} silent
* @returns {object}
* @private
*/
function save(silent) {
var data = ui.scene.save(silent);
storage.local(data);
return data;
}
/**
* @private
*/
function persist( local ) {
if (persistLock) return;
persistLock = true;
// nothing to persist
if (!ui.scene.changed() && !storage.orphan()) {
persistLock = false;
return ui.notification.error('nothing to save');
}
// saves locally
var data = save();
if ( local ) {
console.log(JSON.stringify(data));
persistLock = false;
return;
}
// persist to a gist
storage.persist(data, function(err, info) {
persistLock = false;
if (err) return ui.notification.error(err);
var anchor = '<a target="_blank" href="' + info.url + '">' + info.id + '</a>';
ui.notification.info(info.action + ' gist ' + anchor);
});
}
/**
* @private
*/
function create() {
storage.flush();
ui.scene.clear();
ui.notification.info('new craft!');
}
/**
* @private
*/
function fullCanvas() {
var display = fullCanvased ? 'block' : 'none';
document.querySelector('header').style.display = display;
document.querySelector('footer').style.display = display;
var padding = fullCanvased ? '70px' : '0px';
document.querySelector('main').style.paddingTop = padding;
document.querySelector('main').style.paddingBottom = padding;
ui.scene.resize();
fullCanvased = !fullCanvased;
}
/**
* @param {event} e
* @private
*/
function onKeyDown(e) {
switch (e.keyCode) {
// +
case 107:
ui.scene.adjustFloor(+1);
break;
// -
case 109:
ui.scene.adjustFloor(-1);
break;
// left
case 37:
ui.scene.rotate(+1);
break;
// right
case 39:
ui.scene.rotate(-1);
break;
// b
case 66:
tool.use('brush');
break;
// e
case 69:
tool.use('erase');
break;
// space bar
case 32:
ui.palette.toggle();
break;
// ctrl + z
case 90:
if (e.ctrlKey) history.back();
break;
// ctrl + s
case 83:
e.preventDefault();
if (e.ctrlKey) {
if (e.shiftKey){
persist( true );
} else {
persist();
}
}
break;
// n
case 78:
create();
break;
// f
case 70:
fullCanvas();
break;
// h
case 72:
e.preventDefault();
ui.help.toggle();
break;
}
// 123456789
if (e.keyCode >= 49 && e.keyCode <= 57)
tool.use('brush').set(ui.palette.color(e.keyCode - 49));
// Shift Button Pressed
if ( e.keyIdentifier === "Shift" )
app.shiftHandler = true;
}
/**
* @param {event} e
* @private
*/
function onKeyUp(e) {
if ( e.keyIdentifier === "Shift" )
// Shift Button Unpressed
app.shiftHandler = false;
}
/**
* @param {event} e
* @private
*/
function onScroll(e) {
var delta = e.detail ? -e.detail : e.wheelDelta;
ui.scene.adjustFloor(delta > 0 ? -1 : +1);
}
/**
* @param {event} e
* @private
*/
function onResize(e) {
// hide on first event
if (null == resizeTimeout)
canvasEl.style.visibility = 'hidden';
// debounce scene resize
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function() {
ui.scene.resize();
canvasEl.style.visibility = 'visible';
resizeTimeout = null;
}, 100);
}
/**
* @private
*/
function onAutoSave() {
// debounce auto save
clearTimeout(autoSaveTimeout);
autoSaveTimeout = setTimeout(save.bind(null, true), 1000);
}
/**
* Global export.
*/
window.app = app;
/**
* Exports for hackers
*/
window.scene = ui.scene;
},{"./history":3,"./pointer":4,"./storage":5,"./tool":6,"./ui":11}],2:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Private variables
*/
var anonymousMessage = 'View and edit it on http://ngryman.sh/obelisk-buildr.\n\n' +
'As this is an anonymous gist, you have to manually copy and paste its id, and append it' +
'to the url (i.e. http://ngryman.sh/obelisk-buildr#1337).';
var authenticatedMessage = 'View and edit it on http://ngryman.sh/obelisk-buildr/#{0}.';
var token;
/**
* Module declaration.
*/
var github = {};
/**
*
* @returns {boolean}
*/
github.authenticated = function() {
return (null != token);
};
/**
*
*/
github.connect = function() {
location.href = 'https://github.com/login/oauth/authorize?client_id=717772a46c3c521155d3&scope=gist';
};
/**
*
*/
github.disconnect = function() {
localStorage.removeItem('token');
token = null;
};
/**
*
* @param content
* @param callback
*/
github.newGist = function(content, callback) {
var data = {
description: 'An awesome pixel art chef d\'oeuvre',
public: true,
files: {
'data.json': {
content: content
}
}
};
// anonymous art.json
if (!token)
data.files['art.md'] = {
content: anonymousMessage
};
request('post', '/gists', data, token ? editMessage.bind(null, callback) : callback);
};
/**
*
* @param id
* @param content
* @param callback
*/
github.editGist = function(id, content, callback) {
var data = {
files: {
'data.json': {
content: content
}
}
};
request('patch', '/gists/' + id, data, callback);
};
/**
*
* @param id
* @param callback
*/
github.forkGist = function(id, callback) {
request('post', '/gists/' + id + '/forks', null, token ? editMessage.bind(null, callback) : callback);
};
/**
*
* @param id
* @param callback
*/
github.getGist = function(id, callback) {
request('get', '/gists/' + id, null, callback);
};
/**
*
* @param {function} callback
* @param {object} err
* @param {object} res
* @private
*/
function editMessage(callback, err, res) {
if (err) return callback(err);
// art.json with the correct link.
var data = {
files: {
'art.md': {
content: authenticatedMessage.replace('{0}', res.id)
}
}
};
request('patch', '/gists/' + res.id, data, callback);
}
/**
* @param {string} method
* @param {string} uri
* @param {object} data
* @param {function} callback
* @private
*/
function request(method, uri, data, callback) {
var qs = '';
if (token)
qs = '?access_token=' + token;
reqwest({
url: 'https://api.github.com' + uri + qs,
method: method,
type: 'json',
data: data ? JSON.stringify(data) : null,
error: callback,
success: callback.bind(null, null)
});
}
// TODO: github init
/**
* @private
*/
function fetchToken() {
// priority from url
if (~location.search.indexOf('?token=')) {
token = location.search.match(/\?token=(.{40})/)[1];
localStorage.setItem('token', token);
// remove token from query string
location.replace(location.protocol + '//' + location.host + location.pathname);
}
// from local storage
else
token = localStorage.getItem('token');
}
fetchToken();
/**
* Exports.
*/
module.exports = github;
},{}],3:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Private variables
*/
var stack = [];
var sequence = null;
/**
* Module declaration.
*/
var history = {};
/**
*
* @param {function} fn
*/
history.push = function(fn) {
if (!sequence)
return stack.push(fn);
sequence.push(fn);
};
/**
*
*/
history.startSequence = function() {
sequence = [];
};
/**
*
*/
history.stopSequence = function() {
var seq = sequence;
stack.push(function() {
seq.forEach(function(action) {
action();
});
});
sequence = null;
};
/**
*
* @returns {boolean}
*/
history.isSequenced = function() {
return (null != sequence);
};
/**
*
*/
history.back = function() {
if (0 === stack.length) return;
stack.pop()();
};
/**
* Exports.
*/
module.exports = history;
},{}],4:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var history = require('./history');
/**
* Private variables
*/
var canvasEl = document.getElementById('scene');
var canvasOffset = new obelisk.Point();
var scene;
var x, y;// TODO: screenPos
var viewPoint = new obelisk.Point3D(); // TODO: viewPos
var loopStarted = false;
var loopStopIn = 0;
var down = false;
var dragging = false;
var clickHandler;
var dragHandler;
var moveHandler;
/**
* Module declaration.
*/
var pointer = {};
/**
*
* @param {scene} _scene
* @returns {pointer}
*/
pointer.init = function(_scene) {
var main = document.querySelector('#buildr');
main.addEventListener('mousedown', onDown);
main.addEventListener('mousemove', onMove);
main.addEventListener('mouseup', onUp);
main.addEventListener('mouseleave', onUp);
window.addEventListener('resize', onResize);
Loop.on('tick', apply);
onResize();
scene = _scene;
return pointer;
};
/**
*
* @param {function} handler
* @returns {pointer}
*/
pointer.click = function(handler) {
clickHandler = handler;
return pointer;
};
/**
*
* @param {function} handler
* @returns {pointer}
*/
pointer.drag = function(handler) {
dragHandler = handler;
return pointer;
};
/**
*
* @param {function} handler
* @returns {pointer}
*/
pointer.move = function(handler) {
moveHandler = handler;
return pointer;
};
/**
* @private
*/
function onDown() {
down = true;
}
/**
* @private
*/
function onUp() {
// may happen when called by mouseleave
if (!down) return;
down = false;
if (!dragging) {
if (clickHandler) clickHandler();
return;
}
dragging = false;
if (history.isSequenced())
history.stopSequence();
}
/**
* @param {event} e
* @private
*/
function onMove(e) {
x = e.pageX - canvasOffset.x;
y = e.pageY - canvasOffset.y;
if (down && !dragging)
dragging = true;
if (!loopStarted) {
Loop.start();
loopStarted = true;
}
loopStopIn = 1;
}
/**
* @private
*/
function onResize() {
canvasOffset.x = canvasEl.offsetLeft;
canvasOffset.y = canvasEl.offsetTop;
}
/**
* @private
*/
function apply() {
scene.screenToView(x, y, viewPoint);
scene.select(viewPoint);
if (dragging) {
if (dragHandler) dragHandler();
return;
}
if (moveHandler) moveHandler();
if (0 === loopStopIn) {
Loop.stop();
loopStarted = false;
}
loopStopIn--;
}
/**
* Exports.
*/
module.exports = pointer;
},{"./history":3}],5:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var github = require('./github');
/**
* Private variables
*/
var errors = {
sadSave: "could not save your awesome art on the cloud :(",
unknownGist: "it seems this gist does not exist anymore :(",
invalidGist: "this gist does not behaves well, loading failed :(",
forkFailed: "fork failed :(<br>does this gist still exists?"
};
var gist;
/**
* Module declaration.
*/
var storage = {};
/**
*
* @param data
*/
storage.local = function(data) {
localStorage.setItem(gist ? gist : 'orphan', JSON.stringify(data));
};
/**
*
* @returns {boolean}
*/
storage.orphan = function() {
return (null == gist);
};
/**
*
* @param {object} data
* @param {function} callback
*/
storage.persist = function(data, callback) {
var content = JSON.stringify(data, null, 2),
action = 'created';
// working on an existing gist?
if (gist) {
// edit it
github.editGist(gist, content, function(err, res) {
// tried to edit a gist that is not ours
if (err) {
if (401 == err.status || 404 == err.status) {
// fork it if we are authenticated
// anonymous gist can't be edited after being forked
if (github.authenticated()) {
github.forkGist(gist, function(err, res) {
if (err) return callback(errors.forkFailed);
// then add changes
action = 'forked gist ' + gist + ' to';
github.editGist(res.id, content, onData);
});
}
// if not, well, simply create it :p
else
github.newGist(content, onData);
}
else
callback(errors.sadSave);
return;
}
action = 'saved to';
onData(err, res);
});
return;
}
// create a new one
github.newGist(content, onData);
function onData(err, res) {
if (err) return callback(errors.sadSave);
// remove orphan data
if (storage.orphan())
localStorage.removeItem('orphan');
// set this gist as the current one
gist = res.id;
// and the last one we worked on
localStorage.setItem('last', gist);
// make sure the hash is up to date
if (gist != location.hash.slice(1))
location.hash = gist;
// save it locally too
storage.local(data);
var info = {
id: res.id,
url: res.html_url,
action: action
};
callback(null, info);
}
};
/**
*
* @param {function} callback
*/
storage.fetch = function(callback, data) {
// LOAD LOCAL DATA ( STATISTICS )
// var data = { "colors":["7441408","9001384","13117481","15382272","15658734"], "data":[{"x":0,"y":0,"z":0,"c":2},{"x":0,"y":1,"z":0,"c":2},{"x":0,"y":1,"z":1,"c":2},{"x":0,"y":2,"z":0,"c":2},{"x":0,"y":2,"z":1,"c":2},{"x":0,"y":2,"z":2,"c":2},{"x":0,"y":2,"z":3,"c":2},{"x":0,"y":2,"z":4,"c":2},{"x":0,"y":2,"z":5,"c":2},{"x":0,"y":3,"z":0,"c":2},{"x":0,"y":3,"z":1,"c":2},{"x":0,"y":3,"z":2,"c":2},{"x":0,"y":3,"z":3,"c":2},{"x":0,"y":4,"z":0,"c":2},{"x":0,"y":4,"z":1,"c":2},{"x":0,"y":4,"z":2,"c":2},{"x":0,"y":5,"z":0,"c":2},{"x":0,"y":5,"z":1,"c":2},{"x":0,"y":5,"z":2,"c":2},{"x":0,"y":6,"z":0,"c":2},{"x":0,"y":6,"z":1,"c":2},{"x":0,"y":6,"z":2,"c":2},{"x":0,"y":6,"z":3,"c":2},{"x":0,"y":7,"z":0,"c":2},{"x":0,"y":7,"z":1,"c":2},{"x":0,"y":7,"z":2,"c":2},{"x":0,"y":7,"z":3,"c":2},{"x":0,"y":7,"z":4,"c":2},{"x":0,"y":7,"z":5,"c":2},{"x":0,"y":7,"z":6,"c":2},{"x":0,"y":8,"z":0,"c":2},{"x":0,"y":8,"z":1,"c":2},{"x":0,"y":8,"z":2,"c":2},{"x":0,"y":8,"z":3,"c":2},{"x":0,"y":8,"z":4,"c":2},{"x":0,"y":9,"z":0,"c":2},{"x":0,"y":9,"z":1,"c":2},{"x":0,"y":9,"z":2,"c":2},{"x":0,"y":9,"z":3,"c":2},{"x":0,"y":10,"z":0,"c":2},{"x":0,"y":10,"z":1,"c":2},{"x":0,"y":10,"z":2,"c":2},{"x":0,"y":11,"z":0,"c":2},{"x":0,"y":11,"z":1,"c":2},{"x":0,"y":12,"z":0,"c":2},{"x":0,"y":12,"z":1,"c":2},{"x":0,"y":12,"z":2,"c":2},{"x":0,"y":13,"z":0,"c":2},{"x":0,"y":13,"z":1,"c":2},{"x":0,"y":13,"z":2,"c":2},{"x":0,"y":13,"z":3,"c":2},{"x":0,"y":13,"z":4,"c":2},{"x":0,"y":14,"z":0,"c":2},{"x":0,"y":14,"z":1,"c":2},{"x":0,"y":14,"z":2,"c":2},{"x":0,"y":14,"z":3,"c":2},{"x":0,"y":14,"z":4,"c":2},{"x":0,"y":14,"z":5,"c":2},{"x":0,"y":15,"z":0,"c":2},{"x":0,"y":15,"z":1,"c":2},{"x":0,"y":15,"z":2,"c":2},{"x":0,"y":15,"z":3,"c":2},{"x":0,"y":15,"z":4,"c":2},{"x":0,"y":16,"z":0,"c":2},{"x":0,"y":16,"z":1,"c":2},{"x":0,"y":16,"z":2,"c":2},{"x":0,"y":16,"z":3,"c":2},{"x":0,"y":17,"z":0,"c":2},{"x":0,"y":17,"z":1,"c":2},{"x":0,"y":17,"z":2,"c":2},{"x":0,"y":18,"z":0,"c":2},{"x":0,"y":18,"z":1,"c":2},{"x":0,"y":19,"z":0,"c":2},{"x":4,"y":0,"z":0,"c":4},{"x":5,"y":0,"z":0,"c":0},{"x":5,"y":0,"z":1,"c":0},{"x":5,"y":0,"z":2,"c":0},{"x":5,"y":1,"z":0,"c":0},{"x":5,"y":1,"z":1,"c":0},{"x":5,"y":1,"z":2,"c":0},{"x":5,"y":1,"z":3,"c":0},{"x":5,"y":1,"z":4,"c":0},{"x":5,"y":2,"z":0,"c":0},{"x":5,"y":2,"z":1,"c":0},{"x":5,"y":2,"z":2,"c":0},{"x":5,"y":3,"z":0,"c":0},{"x":5,"y":3,"z":1,"c":0},{"x":5,"y":4,"z":0,"c":0},{"x":5,"y":5,"z":0,"c":0},{"x":5,"y":6,"z":0,"c":0},{"x":5,"y":7,"z":0,"c":0},{"x":5,"y":7,"z":1,"c":0},{"x":5,"y":8,"z":0,"c":0},{"x":5,"y":8,"z":1,"c":0},{"x":5,"y":9,"z":0,"c":0},{"x":5,"y":9,"z":1,"c":0},{"x":5,"y":9,"z":2,"c":0},{"x":5,"y":10,"z":0,"c":0},{"x":5,"y":10,"z":1,"c":0},{"x":5,"y":10,"z":2,"c":0},{"x":5,"y":10,"z":3,"c":0},{"x":5,"y":11,"z":0,"c":0},{"x":5,"y":11,"z":1,"c":0},{"x":5,"y":11,"z":2,"c":0},{"x":5,"y":11,"z":3,"c":0},{"x":5,"y":11,"z":4,"c":0},{"x":5,"y":11,"z":5,"c":0},{"x":5,"y":11,"z":6,"c":0},{"x":5,"y":11,"z":7,"c":0},{"x":5,"y":12,"z":0,"c":0},{"x":5,"y":12,"z":1,"c":0},{"x":5,"y":12,"z":2,"c":0},{"x":5,"y":12,"z":3,"c":0},{"x":5,"y":13,"z":0,"c":0},{"x":5,"y":13,"z":1,"c":0},{"x":5,"y":13,"z":2,"c":0},{"x":5,"y":14,"z":0,"c":0},{"x":5,"y":14,"z":1,"c":0},{"x":5,"y":14,"z":2,"c":0},{"x":5,"y":14,"z":3,"c":0},{"x":5,"y":15,"z":0,"c":0},{"x":5,"y":15,"z":1,"c":0},{"x":5,"y":15,"z":2,"c":0},{"x":5,"y":16,"z":0,"c":0},{"x":5,"y":16,"z":1,"c":0},{"x":5,"y":17,"z":0,"c":0},{"x":5,"y":17,"z":1,"c":0},{"x":5,"y":18,"z":0,"c":0},{"x":5,"y":18,"z":1,"c":0},{"x":5,"y":19,"z":0,"c":0},{"x":10,"y":1,"z":0,"c":3},{"x":10,"y":1,"z":1,"c":3},{"x":10,"y":1,"z":2,"c":3},{"x":10,"y":2,"z":0,"c":3},{"x":10,"y":2,"z":1,"c":3},{"x":10,"y":3,"z":0,"c":3},{"x":10,"y":3,"z":1,"c":3},{"x":10,"y":4,"z":0,"c":3},{"x":10,"y":4,"z":1,"c":3},{"x":10,"y":4,"z":2,"c":3},{"x":10,"y":4,"z":3,"c":3},{"x":10,"y":5,"z":0,"c":3},{"x":10,"y":5,"z":1,"c":3},{"x":10,"y":5,"z":2,"c":3},{"x":10,"y":6,"z":0,"c":3},{"x":10,"y":6,"z":1,"c":3},{"x":10,"y":6,"z":2,"c":3},{"x":10,"y":7,"z":0,"c":3},{"x":10,"y":7,"z":1,"c":3},{"x":10,"y":7,"z":2,"c":3},{"x":10,"y":8,"z":0,"c":3},{"x":10,"y":8,"z":1,"c":3},{"x":10,"y":8,"z":2,"c":3},{"x":10,"y":9,"z":0,"c":3},{"x":10,"y":9,"z":1,"c":3},{"x":10,"y":10,"z":0,"c":3},{"x":10,"y":11,"z":0,"c":3},{"x":10,"y":12,"z":0,"c":3},{"x":10,"y":12,"z":1,"c":3},{"x":10,"y":13,"z":0,"c":3},{"x":10,"y":13,"z":1,"c":3},{"x":10,"y":13,"z":2,"c":3},{"x":10,"y":14,"z":0,"c":3},{"x":10,"y":14,"z":1,"c":3},{"x":10,"y":14,"z":2,"c":3},{"x":10,"y":14,"z":3,"c":3},{"x":10,"y":15,"z":0,"c":3},{"x":10,"y":15,"z":1,"c":3},{"x":10,"y":15,"z":2,"c":3},{"x":10,"y":16,"z":0,"c":3},{"x":10,"y":16,"z":1,"c":3},{"x":10,"y":17,"z":0,"c":3},{"x":10,"y":18,"z":0,"c":3},{"x":10,"y":19,"z":0,"c":3},{"x":15,"y":0,"z":0,"c":1},{"x":15,"y":0,"z":1,"c":1},{"x":15,"y":0,"z":2,"c":1},{"x":15,"y":1,"z":0,"c":1},{"x":15,"y":1,"z":1,"c":1},{"x":15,"y":2,"z":0,"c":1},{"x":15,"y":3,"z":0,"c":1},{"x":15,"y":3,"z":1,"c":1},{"x":15,"y":3,"z":2,"c":1},{"x":15,"y":3,"z":3,"c":1},{"x":15,"y":4,"z":0,"c":1},{"x":15,"y":5,"z":0,"c":1},{"x":15,"y":6,"z":0,"c":1},{"x":15,"y":6,"z":1,"c":1},{"x":15,"y":7,"z":0,"c":1},{"x":15,"y":8,"z":0,"c":1},{"x":15,"y":9,"z":0,"c":1},{"x":15,"y":9,"z":1,"c":1},{"x":15,"y":9,"z":2,"c":1},{"x":15,"y":9,"z":3,"c":1},{"x":15,"y":9,"z":4,"c":1},{"x":15,"y":10,"z":0,"c":1},{"x":15,"y":10,"z":1,"c":1},{"x":15,"y":10,"z":2,"c":1},{"x":15,"y":11,"z":0,"c":1},{"x":15,"y":11,"z":1,"c":1},{"x":15,"y":12,"z":0,"c":1},{"x":15,"y":12,"z":1,"c":1},{"x":15,"y":13,"z":0,"c":1},{"x":15,"y":14,"z":0,"c":1},{"x":15,"y":15,"z":0,"c":1},{"x":15,"y":16,"z":0,"c":1},{"x":15,"y":16,"z":1,"c":1},{"x":15,"y":16,"z":2,"c":1},{"x":15,"y":16,"z":3,"c":1},{"x":15,"y":16,"z":4,"c":1},{"x":15,"y":16,"z":5,"c":1},{"x":15,"y":16,"z":6,"c":1},{"x":15,"y":17,"z":0,"c":1},{"x":15,"y":17,"z":1,"c":1},{"x":15,"y":17,"z":2,"c":1},{"x":15,"y":17,"z":3,"c":1},{"x":15,"y":18,"z":0,"c":1},{"x":15,"y":18,"z":1,"c":1},{"x":15,"y":18,"z":2,"c":1},{"x":15,"y":19,"z":0,"c":1}]};
// LOAD DATA FROM IMAGE
return callback(null, JSON.parse(JSON.stringify(data)), 'LOADED DATA FROM IMAGE');
/* CODE TEMPORARILY DISABLED
// priority to url
if (location.hash) {
gist = location.hash.slice(1);
// if it was a gist we were working on, load local data as it is more fresh
data = localStorage.getItem(gist);
if (data)
return callback(null, JSON.parse(data), 'loaded your last local changes for ' + gist);
// if not loads the gist
github.getGist(gist, function(err, res) {
if (err) return callback(errors.unknownGist);
var data;
try {
data = JSON.parse(res.files['data.json'].content);
}
catch (e) {
return callback(errors.invalidGist);
}
callback(null, data);
});
return;
}
// well, load the last working gist?
gist = localStorage.getItem('last');
data = localStorage.getItem(gist);
if (data) {
location.hash = gist;
return callback(null, JSON.parse(data), 'loaded your last saved stuff');
}
// ok ok, load the last orphan art?
data = localStorage.getItem('orphan');
if (data) return callback(null, JSON.parse(data), 'loaded your last local stuff');
// i can't do nothing more dude, new one!
callback(null, null, 'new');
*/
};
/**
*
*/
storage.flush = function() {
localStorage.removeItem('last');
location.hash = '';
};
module.exports = storage;
},{"./github":2}],6:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var tools = {
brush: require('./tools/brush'),
erase: require('./tools/erase')
};
/**
* Private variables
*/
var scene;
var current;
/**
* Module declaration.
*/
var tool = {};
/**
*
* @param _scene
* @returns {tool}
*/
tool.init = function(_scene) {
scene = _scene;
return tool;
};
/**
*
* @param type
* @returns {tool}
*/
tool.use = function(type) {
current = tools[type];
return tool;
};
/**
*
* @param value
* @returns {tool}
*/
tool.set = function(value) {
if (current.set) current.set(value);
return tool;
};
/**
*
* @returns {tool}
*/
tool.click = function() {
current.click(scene);
return tool;
};
/**
*
* @returns {tool}
*/
tool.drag = function() {
current.drag(scene);
return tool;
};
/**
* Exports.
*/
module.exports = tool;
},{"./tools/brush":7,"./tools/erase":8}],7:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var history = require('../history');
/**
* Private variables
*/
var color = obelisk.ColorPattern.GRAY;
/**
* Module declaration.
*/
var brush = {};
/**
*
* @param {string} value
*/
brush.set = function(value) {
// strip #
value = value.slice(1);
// convert to number
value = parseInt(value, 16);
color = value;
};
/**
*
* @param {scene} scene
*/
brush.click = function(scene) {
if (scene.add(color))
history.push(scene.remove.bind(scene, scene.selected().clone()));
};
/**
*
* @param {scene} scene
*/
brush.drag = function(scene) {
if (scene.add(color)) {
if (!history.isSequenced())
history.startSequence();
history.push(scene.remove.bind(scene, scene.selected().clone()));
}
};
/**
* Exports.
*/
module.exports = brush;
},{"../history":3}],8:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var history = require('../history');
/**
* Module declaration.
*/
var erase = {};
/**
*
* @param {scene} scene
*/
erase.click = function(scene) {
var color = scene.color();
if (scene.remove())
history.push(scene.add.bind(scene,
color,
scene.selected().clone()
));
};
/**
*
* @param {scene} scene
*/
erase.drag = function(scene) {
var color = scene.color();
if (scene.remove()) {
if (!history.isSequenced())
history.startSequence();
history.push(scene.add.bind(scene,
color,
scene.selected().clone()
));
}
};
/**
* Exports.
*/
module.exports = erase;
},{"../history":3}],9:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var github = require('./../github');
/**
* Private variables
*/
var loginEl = document.querySelector('#auth .login');
var loggedEl = document.querySelector('#auth .logged');
/**
* Module declaration.
*/
var auth = {};
/**
*
*/
auth.init = function() {
// login button
loginEl.addEventListener('click', onLoginBtnClick);
// logged button
loggedEl.addEventListener('click', onLoggedBtnClick);
// initial ui state
if (github.authenticated())
loggedEl.classList.remove('is-hidden');
else
loginEl.classList.remove('is-hidden');
};
/**
* @private
*/
function toggle() {
loginEl.classList.toggle('is-hidden');
loggedEl.classList.toggle('is-hidden');
}
/**
* @param {event} e
* @private
*/
function onLoginBtnClick(e) {
if (this.classList.contains('is-disabled')) return;
this.querySelector('span:first-child').innerText = 'wait for it...';
this.classList.add('is-disabled');
github.connect();
}
/**
* @param {event} e
* @private
*/
function onLoggedBtnClick(e) {
var res = confirm('Disconnect from Github?');
if (!res) return;
github.disconnect();
toggle();
// avoids spacebar to trigger it again
this.blur();
}
/**
* Exports.
*/
module.exports = auth;
},{"./../github":2}],10:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Private variables
*/
var el = document.querySelector('#help');
var overlayEl = document.getElementById('overlay');
/**
* Module declaration.
*/
var help = {};
help.toggle = function() {
el.classList.toggle('is-hidden');
overlayEl.classList.toggle('is-hidden');
};
/**
* Exports.
*/
module.exports = help;
},{}],11:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Exports.
*/
module.exports = {
auth: require('./auth'),
notification: require('./notification'),
palette: require('./palette'),
scene: require('./scene'),
welcome: require('./welcome'),
help: require('./help')
};
},{"./auth":9,"./help":10,"./notification":12,"./palette":13,"./scene":14,"./welcome":15}],12:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Private variables
*/
var el = document.getElementById('notification');
var timeout = null;
var queue = [];
var currentMessage;
var count = 0;
/**
* Module declaration.
*/
var notification = {};
/**
*
* @param {string} type
* @param {string} message
*/
notification.push = function(type, message) {
// a message is being displayed, enqueue
if (timeout) {
// is it the same message?
// if so don't enqueue, add multiplier
if (message == currentMessage) {
el.innerHTML = message + ' (' + (++count) + ')';
return;
}
// else enqueue
return queue.push({
type: type,
message: message
});
}
display(type, message);
};
/** Shortcuts */
notification.info = notification.push.bind(null, 'info');
notification.error = notification.push.bind(null, 'error');
/**
* @param {string} type
* @param {string} message
* @private
*/
function display(type, message) {
el.innerHTML = message;
el.dataset.type = type;
el.classList.remove('is-hidden');
timeout = setTimeout(onHide, 5000);
currentMessage = message;
}
/**
* @private
*/
function onHide() {
el.classList.add('is-hidden');
// messages in the queue, pop
if (queue.length > 0) {
var notif = queue.pop();
setTimeout(display.bind(null,
notif.type,
notif.message
), 300);
return;
}
timeout = null;
currentMessage = null;
count = 0;
}
/**
* Exports.
*/
module.exports = notification;
},{}],13:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Module dependencies.
*/
var tool = require('./../tool');
/**
* Private variables
*/
var el = document.getElementById('palette');
var overlayEl = document.getElementById('overlay');
var active = document.querySelector('#palette .is-active');
var visible = false;
var x, y;
var width, height;
/**
* Module declaration.
*/
var palette = {};
/**
*
*/
palette.init = function() {
var style = getComputedStyle(el);
width = parseInt(style.width);
height = parseInt(style.height);
window.addEventListener('mousemove', function(e) {
x = e.clientX;
y = e.clientY;
});
el.addEventListener('click', function(e) {
var btn = e.target;
if ('BUTTON' != btn.tagName) return;
if (active)
active.classList.remove('is-active');
btn.classList.add('is-active');
// tool selection and value
tool.use(btn.dataset.tool).set(btn.dataset.value);
active = e.target;
});
};
/**
*
*/
palette.toggle = function() {
if (!visible) {
el.style.left = (x - width / 2) + 'px';
el.style.top = (y - height / 2) + 'px';
}
el.classList.toggle('is-hidden');
overlayEl.classList.toggle('is-hidden');
visible = !visible;
};
/**
*
* @param {number} index
* @returns {string}
*/
palette.color = function(index) {
var btn = el.querySelector('button:nth-child(' + (index + 1) + ')');
return btn.dataset.value;
};
/**
* Exports.
*/
module.exports = palette;
},{"./../tool":6}],14:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Private variables
*/
var canvasEl = document.getElementById('scene');
var SIZE = 20;
var BLOCK_SIZE = 20;
var view;
var floor;
var cubes;
var blocks;
var origin;
var changed = false;
var changedHandler;
/**
* Module declaration.
*/
var scene = {};
/**
*
* @returns {scene}
*/
scene.init = function() {
cubes = {};
cubes[obelisk.ColorPattern.GRAY] = createCube(BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, obelisk.ColorPattern.GRAY);
floor = {
normal: createBrick(BLOCK_SIZE, BLOCK_SIZE, '0xFF222222'),
elevated: createBrick(BLOCK_SIZE + 2, BLOCK_SIZE + 2, '0xFF222222'),
highlighted: createBrick(BLOCK_SIZE, BLOCK_SIZE, '0xFF444444'),
elevatedHighlighted: createBrick(BLOCK_SIZE + 2, BLOCK_SIZE + 2, '0xFF555555'),
selected: new obelisk.Point3D(-1, -1, 0),
offset: 0
};
blocks = matrix(SIZE);
scene.resize();
return scene;
};
/**
*
*/
scene.resize = function() {
// 1:1 ratio
var style = getComputedStyle(canvasEl);
canvasEl.width = parseInt(style.width);
canvasEl.height = parseInt(style.height);
origin = new obelisk.Point(canvasEl.width / 2, canvasEl.height / 2);
view = new obelisk.PixelView(canvasEl, new obelisk.Point(
origin.x, origin.y
));
var oldBlockSize = BLOCK_SIZE;
// small screens
if (canvasEl.width < 800 || canvasEl.height < 800) {
var size = Math.min(canvasEl.width, canvasEl.height);
// compute new block size
BLOCK_SIZE = Math.floor(size / 40);
// ensure it's even (obelisk needs it)
BLOCK_SIZE = BLOCK_SIZE - (BLOCK_SIZE % 2);
}
// ensure block size comes back to its original size
else
BLOCK_SIZE = 20;
// adapt existing geom to the correct size
if (oldBlockSize != BLOCK_SIZE) {
for (var color in cubes) {
if (!cubes.hasOwnProperty(color)) continue;
cubes[color] = createCube(BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, parseInt(color));
}
floor.normal = createBrick(BLOCK_SIZE, BLOCK_SIZE, '0xFF222222');
floor.elevated = createBrick(BLOCK_SIZE + 2, BLOCK_SIZE + 2, '0xFF222222');
floor.highlighted = createBrick(BLOCK_SIZE, BLOCK_SIZE, '0xFF444444');
floor.elevatedHighlighted = createBrick(BLOCK_SIZE + 2, BLOCK_SIZE + 2, '0xFF555555');
}
scene.draw();
};
/**
*
*/
scene.draw = function() {
view.clear();
drawBlocks(view, blocks, cubes, 0, floor.offset);
drawFloor(view, floor);
drawBlocks(view, blocks, cubes, floor.offset, SIZE);
};
/**
*
* @param {number} x
* @param {number} y
* @param {obelisk.Point3D} point
*/
scene.screenToView = function(x, y, point) {
x -= origin.x;
y -= origin.y;
point.x = Math.floor(((x + 2 * y) / 2) / BLOCK_SIZE) + floor.offset;
point.y = Math.floor(((-x + 2 * y) / 2) / BLOCK_SIZE) + floor.offset;
point.z = floor.offset;
};
/**
*
* @param {obelisk.Point3D} point
*/
scene.select = function(point) {
clampBounds(point);
floor.selected.x = point.x;
floor.selected.y = point.y;
floor.selected.z = point.z;
scene.draw();
};
/**
*
* @returns {obelisk.Point}
*/
scene.selected = function() {
return floor.selected;
};
/**
*
* @param {obelisk.Point3D} point
* @returns {number|null}
*/
scene.color = function(point) {
point = point || scene.selected();
var block = blocks[point.x][point.y][point.z];
if (!block) return null;
return block.color;
};
/**
*
* @param {number} color
* @param {obelisk.Point3D} point
* @returns {boolean}
*/
scene.add = function(color, point) {
point = point || floor.selected;
// already exists
if (null != blocks[point.x][point.y][point.z]) return false;
// if a cube with the given color does not exist, create it
if (null == cubes[color])
cubes[color] = createCube(BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, color);
var block = point.clone();
block.color = color;
blocks[block.x][block.y][block.z] = block;
scene.draw();
changed = true;
if (changedHandler) changedHandler();
return true;
};
/**
*
* @param {obelisk.Point3D} point
* @returns {boolean}
*/
scene.remove = function(point) {
point = point || floor.selected;
if (null == blocks[point.x][point.y][point.z]) return false;
blocks[point.x][point.y][point.z] = null;
scene.draw();
changed = true;
if (changedHandler) changedHandler();
return true;
};
/**
*
* @param {number} delta
*/
scene.adjustFloor = function(delta) {
floor.offset += delta;
if (floor.offset < 0) floor.offset = 0;
else if (floor.offset >= SIZE) floor.offset = SIZE - 1;
scene.draw();
};
/**
*
* @param {number} direction
*/
scene.rotate = function(direction) {
var b = blocks,
n = SIZE,
x, y, z, start, end;
// transpose
for (z = 0; z < n; z++)
for (x = 0; x < n; x++)
for (y = 0; y < n; y++)
if (x < y) swap(b, x, y, y, x, z);
if (1 === direction) {
// reverse rows
for (z = 0; z < n; z++)
for (x = 0; x < n; x++)
for (start = 0, end = n - 1; start < end; start++, end--)
swap(b, x, start, x, end, z);
}
else if (-1 == direction) {
// reverse cols
for (z = 0; z < n; z++)
for (y = 0; y < n; y++)
for (start = 0, end = n - 1; start < end; start++, end--)
swap(b, start, y, end, y, z);
}
scene.draw();
};
/**
*
* @param {boolean} silent
* @returns {object}
*/
scene.save = function(silent) {
var data = [];
// creates a color table
var colors = [], colorsHash = {};
for (var p in cubes) {
if (!cubes.hasOwnProperty(p)) continue;
colorsHash[p] = colors.length;
colors.push(p);
}
// basically "compact" the memory structure by only saving existing blocks,
// referencing colors in color table, with short properties name
for (var x = 0; x < SIZE; x++) {
for (var y = 0; y < SIZE; y++) {
for (var z = 0; z < SIZE; z++) {
if (null != blocks[x][y][z]) {
var b = blocks[x][y][z];
data.push({
x: b.x,
y: b.y,
z: b.z,
c: colorsHash[b.color]
});
}
}
}
}
if (!silent) changed = false;
return {
colors: colors,
data: data
};
};
/**
*
* @param {object} data
*/
scene.load = function( data, colorFormat ) {
var i;
// ensure colors are numbers
var colors = data.colors;
for (i = 0; i < colors.length; i++)
colors[i] = parseInt(colors[i]);
data = data.data;
blocks = matrix(SIZE);
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "0x" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
var currentColor;
for (i = 0; i < data.length; i++){
currentColor = ( colorFormat === "rgba" ) ? parseInt( rgbToHex( data[i].rgba[0], data[i].rgba[1], data[i].rgba[2] ) ) : colors[data[i].c];
scene.add( currentColor, new obelisk.Point3D(data[i].x, data[i].y, data[i].z) );
}
scene.draw();
changed = false;
};
/**
*
* @returns {string}
*/
scene.snapshot = function() {
// isolate art
view.clear();
view.context.fillStyle = '#222222';
view.context.fillRect(0, 0, canvasEl.width, canvasEl.height);
drawBlocks(view, blocks, cubes, 0, SIZE);
var image = canvasEl.toDataURL("image/png");
scene.draw();
return image;
};
/**
*
*/
scene.clear = function() {
blocks = matrix(SIZE);
scene.draw();
};
/**
*
* @param {function} callback
* @returns {boolean|undefined}
*/
scene.changed = function(callback) {
if (!callback) return changed;
changedHandler = callback;
return this;
};
/**
*
* @param {number} width
* @param {number} height
* @param {string} hexColor
* @returns {obelisk.Brick}
* @private
*/
function createBrick(width, height, hexColor) {
var dimension = new obelisk.BrickDimension(width, height);
var color = new obelisk.SideColor().getByInnerColor(hexColor);
return new obelisk.Brick(dimension, color, false);
}
/**
*
* @param {number} width
* @param {number} height
* @param {number} depth
* @param {string} hexColor
* @returns {obelisk.Cube}
* @private
*/
function createCube(width, height, depth, hexColor) {
var dimension = new obelisk.CubeDimension(width, height, depth);
var color = new obelisk.CubeColor(
obelisk.ColorGeom.applyBrightness(hexColor, -20 * 4),
obelisk.ColorGeom.applyBrightness(hexColor, 60),
obelisk.ColorGeom.applyBrightness(hexColor, -20 * 2),
obelisk.ColorGeom.applyBrightness(hexColor, -20),
hexColor
);
return new obelisk.Cube(dimension, color);
}
/**
*
* @param {obelisk.Point3D} point
* @private
*/
function clampBounds(point) {
if (point.x < 0) point.x = 0;
else if (point.x >= SIZE) point.x = SIZE - 1;
if (point.y < 0) point.y = 0;
else if (point.y >= SIZE) point.y = SIZE - 1;
if (point.z < 0) point.z = 0;
else if (point.z >= SIZE) point.z = SIZE - 1;
}
/**
*
* @param {number} size
* @returns {array}
* @private
*/
function matrix(size) {
var m = new Array(size);
for (var x = 0; x < size; x++) {
m[x] = new Array(size);
for (var y = 0; y < size; y++) {
m[x][y] = new Array(size);
}
}
return m;
}
/**
*
* @param {number} m
* @param {number} x1
* @param {number} y1
* @param {number} x2
* @param {number} y2
* @param {number} z
* @private
*/
function swap(m, x1, y1, x2, y2, z) {
var tmp = m[x2][y2][z], c;
c = m[x2][y2][z] = m[x1][y1][z];
if (c) {
c.x = x2;
c.y = y2;
}
c = m[x1][y1][z] = tmp;
if (c) {
c.x = x1;
c.y = y1;
}
}
/**
*
* @param {obelisk.PixelView} view
* @param {object} floor
* @private
*/
function drawFloor(view, floor) {
var normal = floor.normal,
highlighted = floor.highlighted,
point = new obelisk.Point3D();
if (floor.offset > 0) {
normal = floor.elevated;
highlighted = floor.elevatedHighlighted;
view.context.globalAlpha = 0.7;
}
for (var x = 0; x < 20; x++) {
for (var y = 0; y < 20; y++) {
if (x == floor.selected.x && y == floor.selected.y) continue;
point.x = x * BLOCK_SIZE;
point.y = y * BLOCK_SIZE;
point.z = floor.offset * BLOCK_SIZE;
view.renderObject(normal, point);
}
}
if (-1 != floor.selected.x) {
point.x = floor.selected.x * BLOCK_SIZE;
point.y = floor.selected.y * BLOCK_SIZE;
point.z = floor.offset * BLOCK_SIZE;
view.renderObject(highlighted, point);
}
view.context.globalAlpha = 1;
}
/**
*
* @param {obelisk.PixelView} view
* @param {array} blocks
* @param {object} cubes
* @param {number} startZ
* @param {number} endZ
* @private
*/
function drawBlocks(view, blocks, cubes, startZ, endZ) {
var point = new obelisk.Point3D();
for (var x = 0; x < SIZE; x++) {
for (var y = 0; y < SIZE; y++) {
for (var z = startZ; z < endZ; z++) {
var block = blocks[x][y][z];
if (!block) continue;
point.x = block.x * BLOCK_SIZE;
point.y = block.y * BLOCK_SIZE;
point.z = block.z * BLOCK_SIZE;
view.renderObject(cubes[block.color], point);
}
}
}
}
/**
* Exports.
*/
module.exports = scene;
},{}],15:[function(require,module,exports){
/*!
* obelisk-builder
* Copyright (c) 2013 Nicolas Gryman <[email protected]>
* MIT Licensed
*/
'use strict';
/**
* Private variables
*/
var el = document.querySelector('#welcome');
var overlayEl = document.getElementById('overlay');
var onHideCallback;
/**
* Module declaration.
*/
var welcome = {};
/**
*
*/
welcome.init = function(callback) {
if (localStorage.getItem('visited')) return callback();
window.addEventListener('load', function() {
setTimeout(show, 500);
});
onHideCallback = callback;
};
/**
* @private
*/
function show() {
toggle();
document.addEventListener('keypress', hide);
localStorage.setItem('visited', true);
}
/**
* @private
*/
function hide() {
document.removeEventListener('keypress', hide);
toggle();
onHideCallback();
}
/**
* @private
*/
function toggle() {
el.classList.toggle('is-hidden');
overlayEl.classList.toggle('is-hidden');
}
/**
* Exports.
*/
module.exports = welcome;
},{}]},{},[1]);
app.init();
@font-face {
font-family: Lato;
src: url('https://github.com/ngryman/obelisk-buildr/raw/master/fonts/lato.woff?92048847') format('woff'),
url('https://github.com/ngryman/obelisk-buildr/raw/master/fonts/lato.ttf?92048847') format('truetype');
font-weight: normal;
font-style: normal;
}
#auth button {
display: inline-block;
vertical-align: middle;
margin: 0;
padding: 8px;
color: #eee;
background-color: transparent;
cursor: pointer;
}
#auth button.is-disabled,
#auth button:active {
color: #999;
}
#auth button > span {
display: inline-block;
vertical-align: middle;
}
#auth button .icon {
margin-left: 10px;
font-size: 25px;
width: 25px;
}
#auth button.login {
border: 1px solid #444;
background: #000;
}
#auth button.login .icon {
text-shadow: 0 0 2px #eee;
}
#auth button.logged {
color: #00B2B2;
}
#auth button.logged .icon {
-webkit-animation: glow 4s linear infinite;
animation: glow 4s linear infinite;
}
#auth button.is-hidden {
display: none;
}
@-webkit-keyframes glow {
50% {
text-shadow: 0 0 20px #00B2B2;
}
}
@keyframes glow {
50% {
text-shadow: 0 0 20px #00B2B2;
}
}
/** position fixed on small screens when they are in landscape mode */
@media (orientation: landscape) and (max-height: 400px) {
#auth {
position: fixed;
top: 0;
right: 0;
}
}
* {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
a,
a:active
a:visited {
color: #eee;
}
a:active {
text-decoration: none;
}
button {
margin: 2px;
padding: 0;
border: none;
outline: none;
}
html, body, main {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
body {
min-width: 320px;
background-color: #111;
color: #eee;
font-family: Lato, Arial, sans-serif;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
main {
text-align: center;
}
@media (min-width: 700px) and (min-height: 700px), (min-height: 700px) {
main {
padding-top: 70px;
padding-bottom: 70px;
}
}
#buildr {
height: 95%; /* Stretching a little... */margin-top: -30px;
}
#overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #000;
opacity: .3;
transition: opacity 200ms;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
#overlay.is-hidden {
opacity: 0;
pointer-events: none;
}
footer {
display: none;
}
@media (min-width: 700px) and (min-height: 700px), (min-height: 700px) {
footer {
display: block;
position: absolute;
bottom: 15px;
left: 0;
padding: 10px;
width: 100%;
text-align: center;
color: #999;
}
footer a {
padding: 6px;
color: #999;
font-size: 14px;
text-decoration: none;
text-shadow: 0 0 2px black;
border-radius: 4px;
transition: all 200ms;
}
footer a:hover {
background: black;
}
footer a strong,
footer a em {
font-style: normal;
font-weight: normal;
color: #eee;
}
footer a strong {
transition: all 200ms 200ms;
}
footer a strong:hover {
text-shadow: 0 0 1px #fff;
}
}
header {
display: block;
position: absolute;
z-index: 1;
padding: 6px 15px;
width: 100%;
text-align: justify;
}
header::after {
content: '';
display: inline-block;
width: 100%;
height: 0;
font-size: 0;
line-height: 0;
}
header > * {
display: inline-block;
vertical-align: middle;
}
header h1 {
margin: 0;
height: 54px;
line-height: 54px;
color: #fff;
text-align: left;
font-weight: 300;
}
header h1 span {
color: #00B2B2;
}
header h1:before {
content: '';
display: inline-block;
vertical-align: text-top;
margin-right: 15px;
width: 40px;
height: 40px;
background-image: url(http://ngryman.sh/obelisk-buildr/logo.png);
background-position: left center;
background-repeat: no-repeat;
background-size: 40px;
-webkit-animation: doodle 4s linear infinite;
animation: doodle 4s linear infinite;
}
@-webkit-keyframes doodle {
25% { -webkit-transform: rotate(5deg); transform: rotate(5deg); }
75% { -webkit-transform: rotate(-5deg); transform: rotate(-5deg); }
}
@keyframes doodle {
25% { -webkit-transform: rotate(5deg); transform: rotate(5deg); }
75% { -webkit-transform: rotate(-5deg); transform: rotate(-5deg); }
}
/**
* hide on small screens when they are in landscape mode
*
* [1]: using top instead of transform, because we can't have
* position fixed elements in transformed elements. This
* is needed for github auth buttons on small screens.
*/
@media (orientation: landscape) and (max-height: 400px) {
header {
top: -70px; /* [1] */
}
}
#help {
top: 25%;
left: 0;
width: 300px;
}
#help.is-hidden {
opacity: 0;
-webkit-transform: translateX(-100%) scale(.8);
transform: translateX(-100%) scale(.8);
}
.icon {
display: inline-block;
font-style: normal;
font-weight: normal;
speak: none;
text-decoration: inherit;
width: 1em;
margin-right: .2em;
text-align: center;
}
.icon-git:before { content: '\e801'; }
.icon-github:before { content: '\e800'; }
/**
* [1]: fixes blurry text on Chrome because of transform...
*/
#notification {
position: absolute;
top: 0;
left: 50%;
z-index: 1;
width: 100%;
max-width: 400px;
padding: 5px 40px;
color: #fff;
font-size: 16px; /* [1] */
-webkit-transform: translateX(-50%); /* [1] */
transform: translateX(-50%);
transition: -webkit-transform 300ms;
transition: transform 300ms;
}
#notification.is-hidden {
-webkit-transform: translate(-50%, -200%);
transform: translate(-50%, -200%);
}
#notification a,
#notification a:active
#notification a:visited {
color: #fff;
}
#notification[data-type=info] {
background-color: #00B2B2;
}
#notification[data-type=error] {
background-color: #c82829;
}
#palette {
position: fixed;
z-index: 1;
padding: 5px;
width: 200px;
background: rgba(17, 17, 17, .9);
opacity: 1;
text-align: left;
-webkit-transform: scale(1);
transform: scale(1);
/*transform: translateX(-50%) translateY(-50%);*/
-webkit-backface-visibility: hidden;
/*transform: translateX(-50%) translateY(-50%);*/
backface-visibility: hidden;
border: 1px solid #444;
box-shadow: 0 0 0 1px #000, 0 0 15px rgba(0, 0, 0, .5);
transition: opacity 100ms, -webkit-transform 100ms;
transition: opacity 100ms, transform 100ms;
}
#palette.is-hidden {
opacity: 0;
-webkit-transform: scale(.7);
transform: scale(.7);
pointer-events: none;
}
#palette button {
width: 30px;
height: 30px;
font-size: 10px;
}
#palette button.is-active {
box-shadow: 0 0 0 1px rgba(255, 255, 255, .4) inset;
}
#palette .red {
background: linear-gradient(#c82829, rgba(200, 40, 41, 0.80));
}
#palette .red:active {
background: linear-gradient(#af2829, rgba(175, 40, 41, 0.80));
}
#palette .orange {
background: linear-gradient(#f5871f, rgba(245, 135, 31, 0.80));
}
#palette .orange:active {
background: linear-gradient(#c8651f, rgba(200, 104, 31, 0.80));
}
#palette .yellow {
background: linear-gradient(#eab700, rgba(234, 183, 0, 0.80));
}
#palette .yellow:active {
background: linear-gradient(#bd8b00, rgba(189, 147, 0, 0.80));
}
#palette .green {
background: linear-gradient(#718c00, rgba(113, 140, 0, 0.80));
}
#palette .green:active {
background: linear-gradient(#475f00, rgba(71, 95, 0, 0.80));
}
#palette .aqua {
background: linear-gradient(#3e999f, rgba(62, 153, 159, 0.81));
}
#palette .aqua:active {
background: linear-gradient(#396c72, rgba(53, 108, 114, 0.81));
}
#palette .blue {
background: linear-gradient(#4271ae, rgba(66, 113, 174, 0.81));
}
#palette .blue:active {
background: linear-gradient(#404681, rgba(62, 71, 129, 0.81));
}
#palette .purple {
background: linear-gradient(#8959a8, rgba(137, 89, 168, 0.80));
}
#palette .purple:active {
background: linear-gradient(#5c3b7b, rgba(93, 59, 123, 0.80));
}
#palette .black {
background: linear-gradient(#4d4d4c, rgba(77, 77, 76, 0.80));
}
#palette .black:active {
background: linear-gradient(#20201f, rgba(32, 32, 31, 0.80));
}
#palette .white {
background: linear-gradient(#ddd, rgba(221, 221, 221, 0.80));
}
#palette .white:active {
background: linear-gradient(#b0b0b0, rgba(176, 176, 176, 0.80));
}
.pane {
position: fixed;
z-index: 1;
padding: 15px 30px;
background: rgba(17, 17, 17, .9);
border: 1px solid #444;
box-shadow: 0 0 0 1px #000, 0 0 15px rgba(0, 0, 0, .5);
transition: all 300ms;
border-radius: 2px;
}
.pane h2 {
font-weight: 300;
}
.pane ul {
margin-top: 20px;
padding-left: 20px;
}
.pane p {
text-align: left;
}
.pane b {
margin: 0 2px;
padding: 0 2px;
font-weight: 300;
color: #000;
background: #fff;
}
#scene {
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
@media (min-width: 800px) {
#scene {
width: 800px;
}
}
#welcome {
top: 70px;
width: 100%;
-webkit-transform: scale(1) rotate(0deg);
transform: scale(1) rotate(0deg);
transition: all 500ms;
}
@media (min-width: 500px) and (min-height: 600px) {
/**
* [1]: fixes blurry text on Chrome because of transform -50%...
*/
#welcome {
left: 50%;
margin-left: -250px; /* [1] */
width: 500px;
}
}
@media (min-height: 700px) {
#welcome {
top: 25%;
}
}
#welcome.is-hidden {
opacity: 0;
-webkit-transform: scale(0) rotate(720deg);
transform: scale(0) rotate(720deg);
}
.thumbnails {
list-style: none;
margin: 10px 0 8px 0;
display: inline-block;
}
.thumbnails li {
display: inline;
margin: 10px;
}
.thumbnails li.active {
border-top: 10px solid rgb(70, 157, 70);
}
.currently {
margin: 0;
padding: 0 0 0 0;
display: inline-block;
font-size: 18px;
margin-right: 25px;
}
.select {
font-size: 18px;
margin: 0;
}
.drop-image {
display: none;
}
.drop-zone {
display: inline-block;
height: 20px;
width: 20px;
border: 2px dashed #666;
margin-left: 10px;
margin-right: 10px;
}
.drop-over {
border-color: #CACACA;
background-color: #2d2d2d;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment