Skip to content

Instantly share code, notes, and snippets.

@teetteet
Created November 11, 2012 04:25
Show Gist options
  • Save teetteet/4053690 to your computer and use it in GitHub Desktop.
Save teetteet/4053690 to your computer and use it in GitHub Desktop.
A CodePen by toto . Zen-Painting - Not sure if I am abusing codepen. I use bit.ly to shorten the url which is used for storing the drawing data... Only 2048(not 2083) characters url limit. I also use some simple way to compress the data.- press the redr
<div id="wrapper">
<canvas id="canvas"></canvas>
</div>
<div id="blocker"></div>
<div id="image-container" class="black-overlay">
<div class="image-wrapper">
<img id="image" class="interactive"/>
<span class="close-btn">+</span>
</div>
<div class="text interactive"><input id="transparency-checkbox" type="checkbox" class="interactive" checked/>Use transparent background</div>
<div class="text">right click and save the image :-)</div>
</div>
<div id="code-container" class="black-overlay">
<div class="code-wrapper">
<textarea id="code" class="interactive"></textarea>
<span class="close-btn">+</span>
</div><br/>
<div id="redraw-btn" class="interactive small-btn">Redraw</div>
</div>
<div id="share-container" class="black-overlay">
<div class="share-wrapper">
<div class="top">
<div class="text">LONG URL:</div>
<input id="long-url" readonly="readonly"/>
</div>
<div class="middle">
<div class="text">SHORT URL:</div>
<input id="short-url" readonly="readonly"/>
</div>
<div class="bottom">
<a class="facebook btn" target="_blank">SHARE ON FACEBOOK</a>
<a class="twitter btn" target="_blank">SHARE ON TWITTER</a>
</div>
<span class="close-btn">+</span>
</div>
</div>
<div id="logo">
<div class="top"></div>
<div class="middle"></div>
<div class="bottom"></div>
</div>
<div id="footer">
<div id="about-btn">
<span>ABOUT</span>
<div class="container">
<p>Zen Painting is an experiment stripped from my award winning HTML site - <a href="http://musiccanbefun.edankwan.com/" target="_blank">Music Can Be Fun</a>. The <a href="https://github.com/edankwan/zen-painting/blob/master/src/js/lib/edankwan/graphics/Ribbon.js" target="_blank">Ribbon</a> class is now available to download under GPL (Giant Penis License).</p>
<a href="http://www.linkedin.com/in/edankwan" target="_blank">LinkedIn</a> /
<a href="https://twitter.com/edankwan" target="_blank">Twitter</a> /
<a href="https://github.com/edankwan" target="_blank">Github</a>
</div>
</div>
<div class="facebook social-icon"></div>
<div class="twitter social-icon"></div>
<div class="link social-icon"></div>
<div class="info"></div>
</div>
define('controllers/historyController',[
'exports',
'app',
'controllers/dataController',
'controllers/uiController',
'controllers/paintController'
],
function(historyController, app, dataController, uiController, paintController){
var undef;
historyController.history = [];
// index of the history array
historyController.index = 0;
historyController.MAX_UNDO_HISTORY = 8;
var history = historyController.history;
var _mapId = -1;
function init(){
_initVariables();
_initEvents();
reset();
}
function _initVariables(){
}
function _initEvents(){
}
function reset(){
historyController.index = history.length;
save();
}
function save(){
history.splice(0, historyController.index);
_mapId = _mapId - historyController.index + 1;
_mapId = _mapId < 0 ? _mapId + historyController.MAX_UNDO_HISTORY : _mapId >= historyController.MAX_UNDO_HISTORY ? _mapId - historyController.MAX_UNDO_HISTORY: _mapId;
historyController.index = 0;
history.unshift(_mapId);
history.splice(historyController.MAX_UNDO_HISTORY, 1);
paintController.saveHistory(_mapId);
dataController.saveHistory(_mapId);
uiController.setUndoAvailability(history.length > 1);
uiController.setRedoAvailability(false);
}
function undo(){
if(history.length > 0 && historyController.index < history.length - 1) {
if(app.playMode) dataController.endRedraw();
historyController.index++;
var id = history[historyController.index];
paintController.loadHistory(id);
dataController.loadHistory(id);
uiController.setUndoAvailability(historyController.index < history.length - 1);
uiController.setRedoAvailability(true);
} else {
}
}
function redo(){
if(historyController.index > 0) {
if(app.playMode) dataController.endRedraw();
historyController.index--;
var id = history[historyController.index];
paintController.loadHistory(id);
dataController.loadHistory(id);
uiController.setUndoAvailability(true);
uiController.setRedoAvailability(historyController.index > 0);
} else {
}
}
historyController.init = init;
historyController.reset = reset;
historyController.save = save;
historyController.undo = undo;
historyController.redo = redo;
}
);
define('controllers/socialController',[
'exports',
'app',
'controllers/dataController',
'controllers/uiController',
'controllers/paintController'
],
function(socialController, app, dataController, uiController, paintController){
var undef;
socialController.SHARE_URL_BASE = window.__DEFAULT_SHARE_URL + '?data=';
socialController.HASHED_SHARE_URL_BASE = window.__DEFAULT_SHARE_URL + '#';
socialController.SHARE_URL_BASE_LENGTH = socialController.SHARE_URL_BASE.length;
socialController.MAXIMUM_DATA_LENGTH = 2048 - socialController.SHARE_URL_BASE_LENGTH; //even though IE maximum uri length is 2083, Google url shortener only accept 2048 characters
var API_LOGIN = 'o_1jjafij4a0';
var API_KEY = 'R_458495dba1b6856d5a9bd0fb1d8fe181';
var _container;
var _longUrl;
var _shortUrl;
var _facebookBtn;
var _twitterBtn;
var _closeBtn;
var _lastUrl = '';
var _isShown = false;
var _isGoogleShortenerReady = false;
function init(){
_initVariables();
_initEvents();
/*
// if using codepen, dont use dynamic script loader
if(!window.onGoogleApiReady) {
_loadGoogleApi();
} else if(window.__isGoogleApiReady){
window.onGoogleApiReady = onGoogleApiReady;
onGoogleApiReady();
} else {
window.onGoogleApiReady = onGoogleApiReady;
}
*/
}
function _initVariables(){
_socialContainer = document.getElementById('share-container');
_longUrl = document.getElementById('long-url');
_shortUrl = document.getElementById('short-url');
_facebookBtn = _socialContainer.querySelector('.facebook');
_twitterBtn = _socialContainer.querySelector('.twitter');
_closeBtn = _socialContainer.querySelector('.close-btn');
}
function _initEvents(){
_socialContainer.addEventListener('click', _onContainerClicked);
}
function _onContainerClicked(e){
if(e.target == _socialContainer || e.target == _closeBtn) _hide('show');
}
function _loadGoogleApi(){
window.onGoogleApiReady = onGoogleApiReady;
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = 'https://apis.google.com/js/client.js?onload=onGoogleApiReady';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag);
}
function onGoogleApiReady(){
gapi.client.setApiKey(API_KEY);
gapi.client.load('urlshortener', 'v1', _onShortenerReady);
}
function _onShortenerReady(){
_isGoogleShortenerReady = true;
if(_isShown) {
_requestShortenUrl();
}
}
function _requestShortenUrl(){
window.onReceivingShortenedUrl = onReceivingShortenedUrl;
var url = socialController.SHARE_URL_BASE + dataController.compressData(dataController.data);
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.src = 'http://api.bitly.com/v3/shorten?callback=onReceivingShortenedUrl&format=json&apiKey=' + API_KEY + '&login=' + API_LOGIN + '&longUrl=' + url;
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(scriptTag, firstScriptTag);
}
function onReceivingShortenedUrl(res){
if(res.data.url){
if(_lastUrl != res.data.long_url) return;
_socialContainer.classList.add('ready');
_shortUrl.classList.remove('error');
_shortUrl.value = res.data.url;
_facebookBtn.setAttribute('href', 'https://www.facebook.com/sharer.php?u=' + encodeURIComponent(res.data.url) + '&t=Check out my artwork ');
_twitterBtn.setAttribute('href', 'https://twitter.com/intent/tweet?text=' + encodeURIComponent('@codepen Check out my artwork: ') + encodeURIComponent(res.data.url));
} else {
_shortUrl.classList.add('error');
_shortUrl.value = 'Something is wrong and the url can\'t be shortened';
}
}
/*
function _requestShortenUrl(){
if(!_isGoogleShortenerReady) return;
var url = socialController.SHARE_URL_BASE + dataController.compressData(dataController.data);
var request = gapi.client.urlshortener.url.insert({'resource': {'longUrl': url}});
request.execute(function(res) {
if(_lastUrl != res.longUrl) return;
if (res.error) {
_shortUrl.classList.add('error');
_shortUrl.value = 'Something is wrong and the url can\'t be shortened';
} else {
_socialContainer.classList.add('ready');
_shortUrl.classList.remove('error');
_shortUrl.value = res.id;
_facebookBtn.setAttribute('href', 'https://www.facebook.com/sharer.php?u=' + encodeURIComponent(res.id) + '&t=Check out my artwork');
_twitterBtn.setAttribute('href', 'https://twitter.com/intent/tweet?text=' + encodeURIComponent('Check out my artwork: ') + encodeURIComponent(res.id));
}
});
}*/
function onFooterIconsClick(){
var compressedData = dataController.compressData(dataController.data);
_lastUrl = socialController.SHARE_URL_BASE + compressedData;
_longUrl.value = socialController.HASHED_SHARE_URL_BASE + compressedData;
_isShown = true;
_facebookBtn.removeAttribute('href');
_twitterBtn.removeAttribute('href');
_socialContainer.classList.remove('ready');
_socialContainer.classList.add('show');
if(compressedData.length < socialController.MAXIMUM_DATA_LENGTH) {
_shortUrl.value = 'Requesting Shortened URL from Google API...';
_requestShortenUrl(_lastUrl);
} else {
_shortUrl.value = 'URL is too long as what she says that can\'t be shared via social network.';
}
}
function _hide(){
_isShown = false;
_socialContainer.classList.remove('show');
}
socialController.init = init;
socialController.onFooterIconsClick = onFooterIconsClick;
}
);
define('controllers/paintController',[
'exports',
'app',
'controllers/dataController',
'controllers/uiController',
'controllers/historyController',
'controllers/socialController'
],
function(paintController, app, dataController, uiController, historyController, socialController){
var undef;
paintController.canvas = null;
var _canvas;
var _context;
var _cache;
var _cacheContext;
var _undoCaches = [];
var _undoCacheContexts = [];
var _ribbons = [];
var _amount = 0;
var _px = -1;
var _py = -1;
var _x = 0;
var _y = 0;
var _ptx = 0;
var _pty = 0;
var _tx = 0;
var _ty = 0;
var MAX_RIBBIONS = 10;
function init(){
_initVariables();
_initEvents();
}
function _initVariables(){
var i, undoCache;
_canvas = paintController.canvas = document.getElementById('canvas');
_context = _canvas.getContext('2d');
_cache = document.createElement('canvas');
_cacheContext = _cache.getContext('2d');
for(i = 0; i < MAX_RIBBIONS; i++) {
_ribbons[i] = new Ribbon(0, 0);
}
for(i = 0; i < historyController.MAX_UNDO_HISTORY; i++) {
undoCache = _undoCaches[i] = document.createElement('canvas');
_undoCacheContexts[i] = undoCache.getContext('2d');
}
}
function _initEvents(){
}
function onResize(){
_cacheContext.drawImage(_canvas, 0, 0);
_canvas.width = app.stageWidth;
_canvas.height = app.stageHeight;
_context.drawImage(_cache, app.halfW - app.prevHalfW, app.halfH - app.prevHalfH);
Ribbon.maxDistance = Math.sqrt( app.halfW * app.halfW + app.halfH * app.halfH) * 2;
_cache.width = app.stageWidth;
_cache.height = app.stageHeight;
}
function clearRect(){
if(app.playMode) dataController.endRedraw();
_context.clearRect(0, 0, window.innerWidth, window.innerHeight);
dataController.data = '';
app.playMode = false;
historyController.save();
uiController.updateURLLength(0);
}
function onSettingChanged(){
var guiData = uiController.guiData;
_amount = guiData.numOfBrush;
var r = guiData.r >> 0;
var g = guiData.g >> 0;
var b = guiData.b >> 0;
var opacity = guiData.opacity;
_context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + opacity + ')';
_context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + (opacity * opacity * opacity)+ ')';
var ribbon, d, length;
for(var i = 0; i < _amount; i++) {
d = (_amount - i) / _amount;
ribbon = _ribbons[i];
ribbon.radiusBase = d * d * d / _amount * guiData.radiusBase;
ribbon.radiusScale = d * guiData.radiusScale;
ribbon.radiusPower = guiData.radiusPower;
length = Math.cos(d * Math.PI) * guiData.radiusBase;
ribbon.offsetX = Math.sin(d * Math.PI * 2) * length;
ribbon.offsetY = Math.cos(d * Math.PI * 2) * length;
}
dataController.saveLocalStorageSetting();
}
function resetRibbons(x, y){
for(var i = 0; i < _amount; i++) {
_ribbons[i].reset(x, y);
}
}
function setDownXY(x, y) {
_ptx = _tx = _x = x;
_pty = _ty = _y = y;
}
function setMoveXY(x, y) {
_tx = x;
_ty = y;
}
function drawLine(){
_x += (_tx - _x) * .2;
_y += (_ty - _y) * .2;
var x = _x + app.halfW >> 0;
var y = _y + app.halfH >> 0;
var ribbon;
if(_px == x && _py == y) return;
_px = x;
_py = y;
if(!app.playMode) {
dataController.appendData((_tx - _ptx) + '/' + (_ty - _pty) + '/');
_ptx = _tx;
_pty = _ty;
}
for(var i = 0; i < _amount; i++) {
ribbon = _ribbons[i];
ribbon.update(x +ribbon.offsetX, y + ribbon.offsetY);
_context.beginPath();
_context.moveTo(ribbon.p2_p0x, ribbon.p2_p0y);
_context.quadraticCurveTo(ribbon.p2_c0x, ribbon.p2_c0y, ribbon.p1_p0x, ribbon.p1_p0y);
_context.lineTo(ribbon.p1_p1x, ribbon.p1_p1y);
_context.quadraticCurveTo(ribbon.p2_c1x, ribbon.p2_c1y, ribbon.p2_p1x, ribbon.p2_p1y);
_context.fill();
_context.stroke();
}
}
function drawCap(){
var ribbon;
for(var i = 0; i < _amount; i++) {
ribbon = _ribbons[i];
_context.beginPath();
_context.arc(ribbon.p1_x, ribbon.p1_y, ribbon.p1_radius, ribbon.previousAngle - Math.PI, ribbon.previousAngle, false);
_context.fill();
}
}
function loadHistory(id){
var undoCache = _undoCaches[id];
_context.clearRect(0, 0, app.stageWidth, app.stageHeight);
_context.drawImage(undoCache, app.stageWidth - undoCache.width >> 1, app.stageHeight - undoCache.height >> 1);
}
function saveHistory(id){
var undoCache = _undoCaches[id];
var undoContext = _undoCacheContexts[id];
undoCache.width = app.stageWidth;
undoCache.height = app.stageHeight;
undoContext.clearRect(0, 0, app.stageWidth, app.stageHeight);
undoContext.drawImage(_canvas, 0, 0);
}
paintController.init = init;
paintController.onResize = onResize;
paintController.clearRect = clearRect;
paintController.resetRibbons = resetRibbons;
paintController.onSettingChanged = onSettingChanged;
paintController.setDownXY = setDownXY;
paintController.setMoveXY = setMoveXY;
paintController.drawLine = drawLine;
paintController.drawCap = drawCap;
paintController.loadHistory = loadHistory;
paintController.saveHistory = saveHistory;
}
);
define('controllers/uiController',[
'exports',
'app',
'controllers/dataController',
'controllers/paintController',
'controllers/historyController',
'controllers/socialController'
],
function(uiController, app, dataController, paintController, historyController, socialController){
var undef;
// initial setting values can be found in the dataController
uiController.guiData = {
numOfBrush: 0,
radiusBase: 0,
radiusScale: 0,
radiusPower: 0,
color: [0,0,0],
r: 0,
g: 0,
b: 0,
opacity: 0,
loadLocal: null,
saveLocal: null,
clearLocal: null,
savePNG: _savePNG,
viewCode: _viewCode,
cleanUp: null,
redraw: _redraw,
undo: null,
redo: null
};
var guiData = uiController.guiData;
var _gui;
var _guiBrush;
var _guiFile;
var _transparencyCheckbox;
var _imageContainer;
var _image;
var _codeContainer;
var _code;
var _redrawBtn;
var _footer;
var _socialIcons;
var _shareInfo;
var _colorController;
var _undoController;
var _redoController;
function init(){
dataController.loadLocalStorageSetting();
guiData.loadLocal = dataController.loadLocalStorageData;
guiData.saveLocal = dataController.saveLocalStorageData;
guiData.clearLocal = dataController.clearLocalStorage;
guiData.cleanUp = paintController.clearRect;
guiData.undo = historyController.undo;
guiData.redo = historyController.redo;
_initVariables();
_initEvents();
}
function _initVariables(){
_footer = document.getElementById('footer');
_socialIcons = _footer.querySelectorAll('.social-icon');
_shareInfo = _footer.querySelector('.info');
_imageContainer = document.getElementById('image-container');
_image = document.getElementById('image');
_transparencyCheckbox = document.getElementById('transparency-checkbox');
_codeContainer = document.getElementById('code-container');
_code = document.getElementById('code');
_redrawBtn = document.getElementById('redraw-btn');
_gui = new dat.GUI();
}
function _initEvents(){
_imageContainer.addEventListener('click', _onContainerClick, false);
_transparencyCheckbox.addEventListener('click', _onTransparencyCheckboxClick);
_codeContainer.addEventListener('click', _onContainerClick, false);
_redrawBtn.addEventListener('click', _onRedrawClick);
for(var i = 0; i < _socialIcons.length; i++) {
_socialIcons[i].addEventListener('click', socialController.onFooterIconsClick, false);
}
_guiBrush = _gui.addFolder('Brush');
_guiFile = _gui.addFolder('File');
var colorController;
_guiBrush.add(guiData, 'numOfBrush',1, 10).step(1).name('number of brush').onChange(paintController.onSettingChanged);
_guiBrush.add(guiData, 'radiusBase', 0, 50).name('base radius').onChange(paintController.onSettingChanged);
_guiBrush.add(guiData, 'radiusScale',0, 80).name('radius scale').onChange(paintController.onSettingChanged);
_guiBrush.add(guiData, 'radiusPower',1, 500).name('radius power').onChange(paintController.onSettingChanged);
_colorController = _guiBrush.addColor(guiData, 'color').onChange(updateRGB);
_guiBrush.add(guiData, 'opacity', 0, 1).onChange(paintController.onSettingChanged);
_guiFile.add(guiData, 'loadLocal').name('load local storage');
_guiFile.add(guiData, 'saveLocal').name('save local storage');
_guiFile.add(guiData, 'clearLocal').name('clear local storage');
_guiFile.add(guiData, 'savePNG').name('save as PNG');
_guiFile.add(guiData, 'viewCode').name('view codes');
_gui.add(guiData, 'cleanUp').name('clean up canvas');
_gui.add(guiData, 'redraw').name('redraw');
_undoController = _gui.add(guiData, 'undo').name('undo (ctrl + z)');
_redoController = _gui.add(guiData, 'redo').name('redo (ctrl + y)');
_guiBrush.open();
_guiFile.open();
}
function _redraw(){
dataController.redrawData(dataController.compressData(dataController.data));
}
function _onRedrawClick(){
_codeContainer.classList.remove('show');
dataController.redrawData(_code.value);
}
function _onContainerClick(e){
if(!e.target.classList.contains('interactive')) this.classList.remove('show');
}
function _onTransparencyCheckboxClick(){
_showImage(this.checked);
}
function _showImage(isTransparent){
var canvas = paintController.canvas;
if(isTransparent) {
_image.src = paintController.canvas.toDataURL('image/png');
} else {
var cache = document.createElement("canvas");
var context = cache.getContext('2d');
cache.width = canvas.width;
cache.height = canvas.height;
context.fillStyle = "#fff";
context.fillRect(0, 0, canvas.width, canvas.height);
context.drawImage(canvas, 0, 0);
_image.src = cache.toDataURL('image/png');
delete cache;
delete context;
}
}
function updateBrushSetting(){
var controllers = _guiBrush.__controllers;
for (var i in controllers) controllers[i].updateDisplay();
}
function updateRGB() {
guiData.r = _colorController.__color.r >> 0;
guiData.g = _colorController.__color.g >> 0;
guiData.b = _colorController.__color.b >> 0;
paintController.onSettingChanged();
}
function _savePNG(){
_imageContainer.classList.add('show');
_showImage(true);
}
function _viewCode(){
_codeContainer.classList.add('show');
_code.value = dataController.compressData(dataController.data);
}
function show(){
document.getElementById('logo').classList.add('show');
_footer.classList.add('show');
document.querySelector('.dg.ac').classList.add('show');
}
function updateURLLength(num){
_shareInfo.innerHTML = '<< SHARE YOUR ARTWORK (' + (num+10000).toString().substr(1) + '/' + socialController.MAXIMUM_DATA_LENGTH + ')';
if(num > socialController.MAXIMUM_DATA_LENGTH) {
_footer.classList.add('no-share');
} else {
_footer.classList.remove('no-share');
}
}
function setUndoAvailability(bool){
var classList = _undoController.domElement.parentNode.classList;
if(bool) {
_undoController.domElement.parentNode.classList.remove('disable');
} else {
_undoController.domElement.parentNode.classList.add('disable');
}
}
function setRedoAvailability(bool){
var classList = _redoController.domElement.parentNode.classList;
if(bool) {
classList.remove('disable');
} else {
classList.add('disable');
}
}
uiController.init = init;
uiController.updateRGB = updateRGB;
uiController.updateBrushSetting = updateBrushSetting;
uiController.updateURLLength = updateURLLength;
uiController.show = show;
uiController.setUndoAvailability = setUndoAvailability;
uiController.setRedoAvailability = setRedoAvailability;
}
);
define('controllers/dataController',[
'exports',
'app',
'controllers/uiController',
'controllers/paintController',
'controllers/historyController',
'controllers/socialController'
],
function(dataController, app, uiController, paintController, historyController, socialController){
var undef;
/*
special characters in the data:
'S' => Setting
'D' => Mouse Down
'F' => Dot (.)
'M' => Minus (-)
A shitty compression is used to reduce the length of the data in order to share the art work through url:
'M0..9': 'a..j'
'/0..9': 'k..t'
*/
var LOCAL_STORAGE_SETTING_ID = 'zen-painting-setting';
var LOCAL_STORAGE_DATA_ID = 'zen-painting-data';
dataController.LOCAL_STORAGE_DATA_ID = LOCAL_STORAGE_DATA_ID;
dataController.setting = localStorage[LOCAL_STORAGE_SETTING_ID] ? JSON.parse(localStorage[LOCAL_STORAGE_SETTING_ID]) : {
numOfBrush: 5,
radiusBase: 15,
radiusScale: 20,
radiusPower: 150,
r: 0,
g: 0,
b: 0,
opacity: 1
};
dataController.settingChanged = false;
dataController.data = '';
var _dataArr = [];
var _x;
var _y;
var _savedSetting = {};
var _undoData = [];
var _undoSettings = [];
var setting = dataController.setting;
var COMPRESSION_SKIP = 30;
var _compressionCount = COMPRESSION_SKIP;
var _compressionCountDataLength = 0;
function init(){
_initVariables();
_initEvents();
}
function _initVariables(){
if(localStorage[LOCAL_STORAGE_SETTING_ID]) dataController.setting = JSON.parse(localStorage[LOCAL_STORAGE_SETTING_ID]);
for(i = 0; i < historyController.MAX_UNDO_HISTORY; i++) {
_undoData[i] = "";
_undoSettings[i] = {};
}
}
function _initEvents(){
}
function loadLocalStorageData(){
if(localStorage[LOCAL_STORAGE_DATA_ID]) redrawData(localStorage[LOCAL_STORAGE_DATA_ID]);
}
function redrawData(data){
paintController.clearRect();
dataController.data = decompressData(data);
uiController.updateURLLength(_getCompressedLength(dataController.data));
_saveSetting(_savedSetting);
_dataArr = dataController.data.replace(/M/g,'/-').replace(/F/g,'.').split('/');
app.playMode = true;
}
function _saveSetting(settingObject){
var guiData = uiController.guiData;
for(var i in guiData) settingObject[i] = guiData[i];
}
function _loadSetting(settingObject){
var guiData = uiController.guiData;
for(var i in settingObject) guiData[i] = settingObject[i];
uiController.updateBrushSetting();
paintController.onSettingChanged();
}
function saveLocalStorageData(){
localStorage[LOCAL_STORAGE_DATA_ID] = compressData(dataController.data);
}
function loadLocalStorageSetting(){
var guiData = uiController.guiData;
guiData.numOfBrush = setting.numOfBrush;
guiData.radiusBase = setting.radiusBase;
guiData.radiusScale = setting.radiusScale;
guiData.radiusPower = setting.radiusPower;
guiData.color[0] = setting.r;
guiData.color[1] = setting.g;
guiData.color[2] = setting.b;
guiData.opacity = setting.opacity;
}
function saveLocalStorageSetting(){
var guiData = uiController.guiData;
setting.numOfBrush = guiData.numOfBrush;
setting.radiusBase = guiData.radiusBase;
setting.radiusScale = guiData.radiusScale;
setting.radiusPower = guiData.radiusPower;
setting.r = guiData.r >> 0;
setting.g = guiData.g >> 0;
setting.b = guiData.b >> 0;
setting.opacity = guiData.opacity;
localStorage[LOCAL_STORAGE_SETTING_ID] = JSON.stringify(setting);
dataController.settingChanged = true;
}
function clearLocalStorage(){
localStorage[LOCAL_STORAGE_DATA_ID] = '';
localStorage[LOCAL_STORAGE_SETTING_ID] = '';
dataController.settingChanged = true;
}
function runData(){
var guiData;
if(_dataArr.length > 1) {
if(_dataArr[0] == 'S') {
guiData = uiController.guiData;
_dataArr.shift();
guiData.numOfBrush = parseInt(_dataArr.shift(), 10);
guiData.radiusBase = parseFloat(_dataArr.shift());
guiData.radiusScale = parseFloat(_dataArr.shift());
guiData.radiusPower = parseFloat(_dataArr.shift());
guiData.r = guiData.color[0] = _dataArr.shift();
guiData.g = guiData.color[1] = _dataArr.shift();
guiData.b = guiData.color[2] = _dataArr.shift();
guiData.opacity = parseFloat(_dataArr.shift());
uiController.updateBrushSetting();
paintController.onSettingChanged();
} else if(_dataArr[0] == 'D') {
_dataArr.shift();
_x = parseInt(_dataArr.shift(), 10);
_y = parseInt(_dataArr.shift(), 10);
paintController.setDownXY(_x, _y);
paintController.resetRibbons(_x + app.halfW, _y + app.halfH);
paintController.drawLine();
} else {
_x = parseInt(_dataArr.shift(), 10) + _x;
_y = parseInt(_dataArr.shift(), 10) + _y;
paintController.setMoveXY(_x, _y);
paintController.drawLine();
if(_dataArr.length === 0 || isNaN(parseInt(_dataArr[0], 10))) {
paintController.drawCap();
}
}
} else{
_dataArr.shift();
endRedraw();
historyController.save();
}
}
function endRedraw(){
app.playMode = false;
_loadSetting(_savedSetting);
}
/*
* Append the data and convert the seperator / coming with - into 'M' and . into F.
*/
function appendData(str) {
dataController.data = (dataController.data + str).replace(/\/\-/g, 'M').replace(/\./g, 'F');
}
/**
* a slightly faster way to get the length of the compressed data instead of getting the length after compressed the data
* @param {String} data - raw data
* @return {int} length of the compressed data
*/
function _getCompressedLength(data){
var i, character, code;
var output = data.length;
for(i = 0, len = output; i < len; i++) {
character = data[i];
if((character == 'M' || character == '/') && (i+1 < len && (code = data.charCodeAt(i+1)) > 47 && code < 58)) output--;
}
return output;
}
/**
* shitty compression to reduce the length of the data
* @param {String} data - raw data
* @return {String} compressed data
*/
function compressData(data){
var i, len, character, code;
var arr = [];
for(i = 0, len = data.length; i < len; i++) {
character = data[i];
if((character == 'M' || character == '/') && (i+1 < len && (code = data.charCodeAt(i+1)) > 47 && code < 58)) {
arr.push(String.fromCharCode(character == 'M' ? code + 49 : code + 59));
i++;
} else {
arr.push(character);
}
}
return arr.join('');
}
/**
* data decompression
* @param {String} data - compressed data
* @return {String} raw data
*/
function decompressData(data){
var i, len, code;
var arr = [];
for(i = 0, len = data.length; i < len; i++) {
if((code = data.charCodeAt(i)) > 106) {
arr.push('/' , String.fromCharCode(code - 59));
} else if(code > 96) {
arr.push('M' , String.fromCharCode(code - 49));
} else {
arr.push(data[i]);
}
}
return arr.join('');
}
function compressTick(){
if(_compressionCount === 0) {
if(_compressionCountDataLength < socialController.MAXIMUM_DATA_LENGTH && _compressionCountDataLength != dataController.data.length) {
_compressionCountDataLength = _getCompressedLength(dataController.data);
_compressionCount = COMPRESSION_SKIP;
uiController.updateURLLength(_compressionCountDataLength);
}
} else {
_compressionCount--;
}
}
function loadHistory(id){
_compressionCountDataLength = 0;
_compressionCount = 0;
compressTick();
dataController.data = _undoData[id];
//_loadSetting(_undoSettings[id]);
uiController.updateURLLength(_getCompressedLength(dataController.data));
}
function saveHistory(id){
_undoData[id] = dataController.data;
//_saveSetting(_undoSettings[id]);
}
dataController.init = init;
dataController.loadLocalStorageData = loadLocalStorageData;
dataController.saveLocalStorageData = saveLocalStorageData;
dataController.clearLocalStorage = clearLocalStorage;
dataController.loadLocalStorageSetting = loadLocalStorageSetting;
dataController.saveLocalStorageSetting = saveLocalStorageSetting;
dataController.redrawData = redrawData;
dataController.endRedraw = endRedraw;
dataController.runData = runData;
dataController.appendData = appendData;
dataController.compressData = compressData;
dataController.decompressData = decompressData;
dataController.compressTick = compressTick;
dataController.loadHistory = loadHistory;
dataController.saveHistory = saveHistory;
}
);
define('app',[
'exports',
'controllers/dataController',
'controllers/uiController',
'controllers/paintController',
'controllers/historyController',
'controllers/socialController'
],
function(app, dataController, uiController, paintController, historyController, socialController){
var undef;
app.stageWidth = window.innerWidth;
app.stageHeight = window.innerHeight;
app.halfW = 0;
app.halfH = 0;
app.prevHalfW = 0;
app.prevHalfH = 0;
app.playMode = false;
app.isDown = false;
var DEFAULT_DATA = 'Sso1F360295277772096q7F05882541036117p6F03676624962207l17t8p4kF23161765355552374/De06o21kkpjl8d7m9f1n2h5n1g5o5h8n2f5l3c8nb6kikfkdkb/Sso1F360295277772096q7F05882541036117p6F03676624962207l17t8p4kF23161765355552374/Dc37nkkkc6ch5b1h7if8b0h2kh8ef6dd0bb8kb7kked5cgcb7bhbfdjbfchbfcckebcbebc/Ssm0F404412337034238n3F52941270518058p6F03676624962207l60l42l00kF23161765355552374/Db79o70kkkepc6te8m9i8n6b12n0i5n6h5n0h7m3j8m1i2l0f5kb1kbkkkkkkkk/Spl4F338235696294326m2F05882414814512p6F03676624962207l60l42l00kF20955882940737863/Dc4l28kkkdn1c3p3d8q0e2r4e6r2d1r8d4q6c5o0b9m8b0l0gl3bl3cl5dl9b0m2b1n0b9n1c7m3c6m0c9l1b9m4e1m0d0l8c6kkl3c7l0b3/Spn6F948530448143075p5F5882368533257p6F03676624962207p2n9l0kF4080882467406847/Dg57o11kbkebb1mb1m1c1n6d3s2f3t8g8p8e1q9c5p8c3n2b3l6b0oglgkilglhoelembmdncodrf/Spm3F713235959256o4F11764829629024p6F03676624962207p2n9l0kF4080882467406847/Db12b1kkmgqb0tb9l6c7n3d9o1e2p0e9o7e0p3e0r0f1p9d8p8c9n3b7l8hshofkdcb0/Spl4F889706299997954m3F823530079996726p6F03676624962207o7n5qkF28676471392588654/Dc51f17kklsnm1kkkl7l0s1oq6pq4om0po4kp3lo3ko4mm7kl6lqklkkkkkkkkkkkkllmkkklkkkkklk/Spl4F889706299997954m3F823530079996726p6F03676624962207o7n5qkF28676471392588654/De23o04kkpel9b9m2d0m1d7td6tc5rb6pb2nhmindkblkkkkbkblkmcleoepisi/SprF169117848147163qF176470761480633p6F03676624962207o7n5qkF28676471392588654/Db53o08kkkfmb5td2l3e3m6h8m9g4m8f8m2f1m4g1l9f0rf4me5kc7cgbhkccdkd/Spl1F029412074072559l5F882353386664485p6F03676624962207l52l21o9kF11029412074072559/Dn25b19kkkb2kb6l4d3l2e0m1g1l6b23kb65c4h3c6kc4kb3kfkfk/Spo6F32353071110475q9F70588430813858p6F03676624962207l37n5n5kF5073529554073377/Dn24e01kkhpb9ne2kkkb24id7b0d2c0b3hkkrrn5m2p8m7p6l3p0rn1rl2qotlpkpkkkkkkkckckckhkjpd1oc9rc0qhpenfncmeodrfokqktotrsrl6l1pkl6nl2e/Spm8F676471392588653m6F470588977774142p6F03676624962207q5n6n6kF5073529554073377/Ssl2F132353281479816m5F588236011848338p6F03676624962207p7ttkF5073529554073377/Dm92d95kkkcdgib1b6b6d9c4i2d9f0c3/Ssl2F132353281479816m5F588236011848338p6F036766249622/Dq15b74kmkpkpospl0ntnn/';
var _canvas;
function init(){
_initVariables();
_initEvents();
dataController.init();
uiController.init();
uiController.show();
uiController.updateURLLength(0);
paintController.init();
historyController.init();
socialController.init();
_drawDefaultData();
uiController.updateRGB();
_onResize();
_loop();
// shitty hack for codepen.... so many unexpected thing happens here....
document.querySelector('.cr.object.color .selector').style.width = '127px';
if(document.location.href.toString().indexOf('secure')>-1) document.getElementById('footer').style.height = '48px';
}
function _drawDefaultData(){
var href = window.location.href.toString();
var data = DEFAULT_DATA;
if(href.indexOf('#') > 0) {
data = href.split('#')[1];
} else if (window.__QUERY_STRING['data']){
data = window.__QUERY_STRING['data'];
}
dataController.redrawData(data);
}
function _initVariables(){
_canvas = document.getElementById('canvas');
}
function _initEvents(){
window.addEventListener('resize', _onResize);
window.addEventListener('orientationchange', _onResize);
if('ontouchstart' in window) {
_canvas.addEventListener('touchstart', function(e){e.preventDefault(); _onDown(_parseTouchEvent(e));});
window.addEventListener('touchmove', function(e){e.preventDefault(); _onMove(_parseTouchEvent(e));});
window.addEventListener('touchend', function(e){_onUp(_parseTouchEvent(e));});
} else {
_canvas.addEventListener('mousedown', function(e){e.preventDefault(); _onDown(e);});
window.addEventListener('mousemove', function(e){e.preventDefault(); _onMove(e);});
window.addEventListener('mouseup', _onUp);
}
window.addEventListener('keyup', _onKey);
}
function _onKey(e){
if(e.ctrlKey) {
if(e.keyCode == 90) {
historyController.undo();
}else if(e.keyCode == 89) {
historyController.redo();
}
}
}
function _parseTouchEvent(e){
var fakeEvent = e.touches.length > 0 ? e.touches[0] : e.changedTouches[0];
return fakeEvent;
}
function _onDown(e){
var x = e.pageX - app.halfW;
var y = e.pageY - app.halfH;
app.isDown = true;
if(app.playMode) paintController.clearRect();
paintController.setDownXY(x, y);
paintController.resetRibbons(e.pageX, e.pageY);
if(dataController.settingChanged) {
var guiData = uiController.guiData;
dataController.appendData('S/' + guiData.numOfBrush + '/' + guiData.radiusBase + '/' + guiData.radiusScale + '/' + guiData.radiusPower + '/' + guiData.r + '/' + guiData.g + '/' + guiData.b + '/' + guiData.opacity + '/');
}
dataController.appendData('D/'+ x + '/' + y + '/');
}
function _onMove(e){
if(!app.isDown) return;
paintController.setMoveXY(e.pageX - app.halfW, e.pageY - app.halfH);
}
function _onUp(e){
if(!app.isDown) return;
app.isDown = false;
paintController.drawCap();
historyController.save();
}
function _onResize(){
app.prevHalfW = app.halfW;
app.prevHalfH = app.halfH;
app.stageWidth = window.innerWidth;
app.stageHeight = window.innerHeight;
app.halfW = app.stageWidth >> 1;
app.halfH = app.stageHeight >> 1;
paintController.onResize();
paintController.onSettingChanged();
}
function _loop(){
window.requestAnimationFrame(_loop);
if(app.playMode) {
dataController.runData();
return;
}
dataController.compressTick();
if(!app.isDown) return;
paintController.drawLine();
}
setTimeout(init);
}
);
require(['app']);
@import url(http://fonts.googleapis.com/css?family=PT+Sans+Narrow);
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
html, body{
width: 100%;
height: 100%;
overflow: hidden;
background-image: url('data:image/png;base64,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');
font-family: 'PT Sans Narrow', 'Lucida Grande', sans-serif;
}
#wrapper {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
background: -moz-radial-gradient(center, ellipse cover, rgba(73,60,46,0) 0%, rgba(73,60,46,.4) 100%);
background: -webkit-gradient(radial, center center, 0%, center center, 100%, color-stop(0%,rgba(73,60,46,0)), color-stop(100%,rgba(73,60,46,.4)));
background: -webkit-radial-gradient(center, ellipse cover, rgba(73,60,46,0) 0%,rgba(73,60,46,.4) 100%);
background: -o-radial-gradient(center, ellipse cover, rgba(73,60,46,0) 0%,rgba(73,60,46,.4) 100%);
background: -ms-radial-gradient(center, ellipse cover, rgba(73,60,46,0) 0%,rgba(73,60,46,.4) 100%);
background: radial-gradient(ellipse at center, rgba(73,60,46,0) 0%,rgba(73,60,46,.4) 100%);
}
.black-overlay{
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.7);
z-index: 200;
}
#image-container {
display: none;
position: absolute;
text-align: center;
}
#image-container.show {
display: block;
}
#image-container .image-wrapper{
position: relative;
display: inline-block;
margin-top: 30px;
height: 300px;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAACpJREFUeNpi/P//PwM2cPbsWaziTAwkglENxAAWXOFtbGw8Gkr00wAQYAD5xAiGkcIskQAAAABJRU5ErkJggg==);
}
#image-container #image{
height: 300px;
box-shadow: inset 0 0 120px rgba(0,0,0,.5);
-webkit-transition: box-shadow .5s ease-in-out;
-moz-transition: box-shadow .5s ease-in-out;
-ms-transition: box-shadow .5s ease-in-out;
-o-transition: box-shadow .5s ease-in-out;
transition: box-shadow .5s ease-in-out;
}
#image-container #image:hover{
box-shadow: inset 0 0 0 rgba(0,0,0,.5);
}
#image-container .text{
font-size: 11px;
margin-top: 10px;
color: #fff;
text-shadow: 1px 1px 0 #000;
}
#code-container {
display: none;
position: absolute;
text-align: center;
}
#code-container.show {
display: block;
}
#code-container .code-wrapper{
position: relative;
display: inline-block;
margin-top: 30px;
width: 400px;
height: 240px;
}
#code-container #code {
width: 400px;
height: 240px;
}
.close-btn {
position: absolute;
top: -32px;
right: -70px;
width: 80px;
height: 80px;
font-size: 36px;
line-height: 80px;
color: #fff;
text-align: center;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: -webkit-transform .1s ease-in-out;
-moz-transition: -moz-transform .1s ease-in-out;
-ms-transition: -ms-transform .1s ease-in-out;
-o-transition: -o-transform .1s ease-in-out;
transition: transform .1s ease-in-out;
cursor: pointer;
}
.close-btn:hover {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
-o-transform: rotate(-45deg);
transform: rotate(-45deg);
}
#code-container #redraw-btn {
margin-top: 12px;
}
#share-container {
display: none;
position: absolute;
}
#share-container.show {
display: block;
}
#share-container .share-wrapper{
position: absolute;
left: 50%;
top: 50%;
margin-left: -220px;
margin-top: -109px;
width: 441px;
height: 218px;
}
#share-container .top{
position: absolute;
top: 0;
width: 441px;
height: 72px;
background-color: #000;
}
#share-container .middle{
position: absolute;
top: 73px;
width: 441px;
height: 72px;
background-color: #000;
}
#share-container .text{
position: absolute;
left: 14px;
width: 80px;
height: 72px;
line-height: 74px;
color: #fff;
}
#share-container input{
position: absolute;
left: 100px;
width: 310px;
height: 19px;
top: 23px;
border: 0;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
font-family: 'PT Sans Narrow', 'Lucida Grande', sans-serif;
font-size: 14px;
padding: 5px;
cursor: text;
}
#share-container input#short-url{
background-color: #333;
}
#share-container .middle *{
color: #666;
cursor: default;
}
#share-container.ready .middle *{
color: #fff;
cursor: auto;
}
#share-container .bottom{
position: absolute;
top: 146px;
width: 441px;
height: 72px;
}
#share-container a,
#share-container a:hover,
#share-container a:active,
#share-container a:visited{
position: absolute;
display: block;
width: 220px;
height: 72px;
background-color: #000;
line-height: 74px;
text-align: center;
color: #666;
cursor: default;
}
#share-container .twitter{
left: 221px;
}
#share-container.ready a,
#share-container.ready a:hover,
#share-container.ready a:active,
#share-container.ready a:visited{
color: #fff;
cursor: pointer;
text-decoration: none;
}
#share-container.ready a:hover{
background-color: #00aeff;
}
.small-btn{
display: inline-block;
zoom: 1;
background-color: #000;
height: 32px;
color: #fff;
font-size: 14px;
line-height: 33px;
padding: 8px 8px 6px 8px;
text-transform: uppercase;
cursor: pointer;
box-shadow: 3px 3px rgba(0,0,0,.3);
}
.small-btn:hover{
background-color: #2fa1d6;
color: #fff;
}
#footer{
position: absolute;
height: 60px;
bottom: -60px;
width: 100%;
background-color: #1a1a1a;
-webkit-transition: bottom .15s ease-in-out;
-moz-transition: bottom .15s ease-in-out;
-ms-transition: bottom .15s ease-in-out;
-o-transition: bottom .15s ease-in-out;
transition: bottom .15s ease-in-out;
}
#footer.show{
bottom: 0;
}
html.is-down #footer{
pointer-events: none;
}
#footer > *{
border-right: 1px solid #ccc;
}
#footer, #footer > *{
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-user-drag: none;
user-drag: none;
-webkit-touch-callout: none;
-moz-touch-callout: none;
-ms-touch-callout: none;
-o-touch-callout: none;
touch-callout: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
#footer #about-btn{
position: absolute;
width: 70px;
height: 60px;
line-height: 50px;
background-color: #000;
color: #fff;
text-align: center;
-webkit-perspective: 800px;
-moz-perspective: 800px;
-ms-perspective: 800px;
perspective: 800px;
}
#footer #about-btn:hover{
background-color: #00aeff;
}
#footer #about-btn .container{
position: absolute;
width: 290px;
height: 80px;
bottom: 60px;
padding: 8px 8px;
text-align: left;
line-height: 18px;
font-size: 13px;
color: #fff;
background-color: #000;
border-bottom: 1px solid #ccc;
-webkit-transform: rotateX(90deg);
-moz-transform: rotateX(90deg);
-ms-transform: rotateX(90deg);
-o-transform: rotateX(90deg);
transform: rotateX(90deg);
-webkit-transform-origin: 100% 100%;
-moz-transform-origin: 100% 100%;
-ms-transform-origin: 100% 100%;
-o-transform-origin: 100% 100%;
transform-origin: 100% 100%;
-webkit-transition: -webkit-transform .2s ease-in-out;
-moz-transition: -moz-transform .2s ease-in-out;
-ms-transition: -ms-transform .2s ease-in-out;
-o-transition: -o-transform .2s ease-in-out;
transition: transform .2s ease-in-out;
opacity: 0;
}
#footer #about-btn:hover .container{
-webkit-transform: rotateX(0);
-moz-transform: rotateX(0);
-ms-transform: rotateX(0);
-o-transform: rotateX(0);
transform: rotateX(0);
opacity: 1;
}
#footer #about-btn .container p{
margin-bottom: 10px;
}
#footer #about-btn .container a,
#footer #about-btn .container a:visited,
#footer #about-btn .container a:active{
color: #00aeff;
}
#footer #about-btn .container a:hover{
color: #fff;
}
#footer .social-icon{
position: absolute;
width: 48px;
height: 60px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAAAwCAYAAADzRIMRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNS4xIFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6REZFNTRCODgyOEYwMTFFMjg1NzJGMzNDMDkxRDU5N0MiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6REZFNTRCODkyOEYwMTFFMjg1NzJGMzNDMDkxRDU5N0MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpERkU1NEI4NjI4RjAxMUUyODU3MkYzM0MwOTFENTk3QyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpERkU1NEI4NzI4RjAxMUUyODU3MkYzM0MwOTFENTk3QyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkQF/jYAAAJ7SURBVHja7JzhbdswEEatogP4t385E1TZwN7AniD2BKknSD2B3QmUDdJMYGWCaINqBG3QisAn5CCoUdKQDmm8BxCJBBvQiY93RwJJNpvN/kwAPPOFVwCIBYgFiAWAWIBYgFgAiAWIBYgFgFiAWIBYAIgFiDVAldA7atqxbUfWGz8Sn3sX07Xii1qsX2+YoJ0m5Vo/XXB1O+7bcYx0AnZ6vktiq5jcAl+GkMuXWGU71iMTsB2Qx33+SpM3lWSxcalS5e3YhJLra4CHrgfKRDWS0VxQTwo0ZubteNYiSF2qk4njXnKdfMUWosfaKwsdzSoYWw1OqCKBiZknLFVX0l0MD6Y6uPe+Mpkrqoy10CromvJagex0f4ybCCdiqDm32XihkQrfzO9rxfKsRV/qfh6bWMdXslKV6Arf/0OsvRErBUo968bEVem6Mf2V16rhqxQuPth45xMI1VMtVQKdPD81T7l63iBS+RTLPej3D3w3xr7lTqPfY3X3Y14MjWnUuyy1NJmqMJ87hOhvM89/V7iejJ9n9Ski3w1mvcx8ijxLNUaiXItgp0y1UuPetShVqHfv+7jhveVwnsARQ0r0pTrpuit/pbLYRtfBsq7v44ZCsrzn8+D3SKHbLD2oxbhVm3JrSmQd+kF8i+VWwO839ltFYtv1FDiYLLQ2jfmNpPufxf+ppbA0dfvRXA8xnbwcyoFfpqb8dQeeByPZ2fpZX2I15nzktaBXCnSKA2eV6+ybJN+7wlrZql/DFwmXvdR2hUON/Nl33hn/xuhixerkqj5jUSMWJLErBEAsQCxALADEAsQCxALE4hUAYgFiAWIBIBYgFiAWAGJBAvwVYAAY2459KQWENgAAAABJRU5ErkJggg==');
background-color: #ccc;
cursor: pointer;
-webkit-transition: background-color .2s;
-moz-transition: background-color .2s;
-ms-transition: background-color .2s;
-o-transition: background-color .2s;
transition: background-color .2s;
}
#footer .social-icon:hover{
background-color: #00aeff;
}
#footer.no-share .social-icon{
background-color: #666;
cursor: default;
}
#footer .twitter{
left: 71px;
}
#footer .facebook{
left: 120px;
background-position: -49px 0;
}
#footer .link{
left: 169px;
background-position: -98px 0;
}
#footer.no-share .link{
background-color: #ccc;
cursor: pointer;
}
#footer .info{
position: absolute;
left: 218px;
width: 220px;
height: 60px;
font-size: 14px;
text-align: center;
line-height: 50px;
background-color: #1a1a1a;
color: #cac3b8;
}
#footer.no-share .info{
color: #666;
}
#logo{
position: absolute;
left: 30px;
top: 40px;
width: 104px;
height: 30px;
pointer-events: none;
}
#logo > div{
position: absolute;
width: 104px;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGgAAAAeCAQAAABqbpP2AAAEOklEQVR4Xu1WS8ocNxAunIftgEMag7MLpH0C0147IWgTkoUx9FJbgU+gbZa6gq7QV9AVdAVdQVeYFB81KukXHciEMCGMil8tqZ6PT5qfMFa6PKFKf3esFCg1/USe7jgcZVrajsO6IZyNHEXW3Hi9w0aku41Ipq096nvbyKy7dOvtfh1S4FSm5UY7lUpfmPvCTuvqbtRdht7uQ0KBjjtkg6qqY4P0rrRSpEqp45UnHdjk3qgtQ/ro5A7gFbqeckPDSge0uQwDFbmPB22n/heKkJ1urYGBHm6BqqiU1j/TeKJ+0pPMpHYC83QUCnKuGjsVnDgpwI6zg2eHm3nm31AVG0mftjO4Ha0ie7sjpfH83F8KMLmxXqW1QTGje1sHTS82CnoPbQTvW2k2SBot6+xf7vx+9tLND22WSipwtpZ0ngxF8Io0X2vl4Zp5Ck3RLehLbF3sSjOUNZ/6j3prz+GmVAWbh8gUmKiQmx/lBGhMQ4CgxdmvXcHXCYzS8ISUQT+e+F8EbhMtVMSskiLZSJiODjn1mJ+OQpXmodf8GOoPuIhewqz+E2S1rP7E/9ai9nhUEnNnuDUkG+3CAAov0KKpn5nmkcSl3oQocrt8Deyha/pojGU98W8aj7pbCmNl6FduioucGH0G0OiqNVSDeqanYlnfKq2/b/IJFml6NIayzv4hGTskLBPc1OGA5IN2uYYaXJigpWdKsYWm8NBHO8y/U/pojIU48R9QRul7g9tEHvUrHWeB3NFgkSGjFEQuKnAGnRXrJN9MBvb5O/0n4a4/pNLFjODP/XuN+UEP+p/Qc/quo9f0o9AP2Cs9o399fNG5e8MhKL2ldwP9TL909Dt9Gui3gftT03qPvdLHTufXgfPhib+3QzTf07d003hJ31wJ61cdveC90pf0z8dX3NuvG71gj8+VmPMYD/rPknX2AvpsM77JLjj31vG88GmAVOWTYgPP2RqbeF54t/G6XCWhF/lLfF6sl/0FZLrZYy52a1zHO/DhMas+PO/X2HC+E7zw7iK0jikVBLCyG8dzFkOHPSSxajdIEQxyIpBnLnMCB5BELkHO8KmHLLvBPhIhCA4L9lex5m3suInXHla96FfoJ5F1VzmUkvUgVdhiQAuUkGNWJZsQ8G4PFsSpLS0hhIN+VNS38BwkIawQFrvRhGBfZHi1E2lCykVCO3M1oYP3W0uI5SQhJ4WAHe3O0CEiTQjJBRhwODXMCS0hL9LZRiTNMxIEiCQh7uPYoeZB9G0F5Fblwjbra0JIJljTOiRyQE/4y4QQkGdyQLAXNSMAMAhfIcd7pFylchuQ7oTPCUlBBsih/hEyToo4chP+ug7BK8+aEM8LTlZbNaGzR+GP68VDOBnVu6CmESYKLmTAysN4JEAPAJUyoG+McXXVrj1AQwA4LrrrubAd8cD49ig460H6KFScO0Qd5b4GzeVPz9chWECr2VUAAAAASUVORK5CYII=');
background-repeat: no-repeat;
}
#logo > .top{
top: 18px;
height: 0;
-webkit-transition: all .5s ease-in-out .5s;
-moz-transition: all .5s ease-in-out .5s;
-ms-transition: all .5s ease-in-out .5s;
-o-transition: all .5s ease-in-out .5s;
transition: all .5s ease-in-out .5s;
}
#logo > .middle{
top: 18px;
height: 4px;
width: 0;
background-position: 0 -18px;
-webkit-transition: all .4s ease-in-out;
-moz-transition: all .4s ease-in-out;
-ms-transition: all .4s ease-in-out;
-o-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
}
#logo > .bottom{
top: 22px;
height: 8px;
background-position: 0 -32px;
-webkit-transition: all .3s ease-in-out .5s;
-moz-transition: all .3s ease-in-out .5s;
-ms-transition: all .3s ease-in-out .5s;
-o-transition: all .3s ease-in-out .5s;
transition: all .3s ease-in-out .5s;
}
#logo.show > .top{
top: 0;
height: 18px;
}
#logo.show > .middle{
width: 104px;
}
#logo.show > .bottom{
background-position: 0 -22px;
}
.dg.ac {
-webkit-transform: translate3d(300px,0,0);
-moz-transform: translate3d(300px,0,0);
-ms-transform: translate3d(300px,0,0);
-o-transform: translate3d(300px,0,0);
transform: translate3d(300px,0,0);
-webkit-transition: -webkit-transform .5s ease-in-out;
-moz-transition: -moz-transform .5s ease-in-out;
-ms-transition: -ms-transform .5s ease-in-out;
-o-transition: -o-transform .5s ease-in-out;
transition: transform .5s ease-in-out;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-user-drag: none;
user-drag: none;
}
.dg.ac.show {
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
}
.dg.main, .dg .title, .dg .property-name, .dg input{
font-family: 'PT Sans Narrow', 'Lucida Grande', sans-serif;
font-size: 14px;
}
.dg .cr.function .disable *.property-name{
color: #666;
cursor: default;
}
.dg.main.a .close-button {
height: 24px;
line-height: 24px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment