Created
February 17, 2014 06:21
-
-
Save yoksel/9045639 to your computer and use it in GitHub Desktop.
A Pen by yoksel.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="l-wrapper" data-size="300" data-oneside="9"> | |
<div class="b-box b-box--paint"><span class="dot"></div> | |
<div class="b-box b-box--result"><span class="dot is-running"></span></div> | |
<div class="b-palette"></div> | |
<div class="b-steps"></div> | |
<div class="b-codes"> | |
<span class="b-codes__toggle" data-init = "Get codes" data-opened = "Close">Get codes</span> | |
<div class="b-codes__wrapper"> | |
<h3 class="b-codes--title">CSS</h3> | |
<textarea class="b-codes__textarea textarea--css"></textarea> | |
<h3 class="b-codes--title">HTML</h3> | |
<textarea class="b-codes__textarea textarea--html"></textarea> | |
</div> | |
</div> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log( "Hello!" ); | |
var line = "------------------------"; | |
function Pixelator() { | |
var doc = document; | |
var colors = ["#3FB8AF","#7FC7AF","#DAD8A7","#FF9E9D","#FF3D7F"]; | |
var currentColorNum = 0; | |
var currentColor = colors[currentColorNum]; | |
var currentColorClass = "color--" + currentColorNum; | |
var transparent = "rgba(255,255,255,0)"; | |
var wrapper = doc.querySelector(".l-wrapper"); | |
var paintBox = doc.querySelector(".b-box--paint"); | |
var resultBox = doc.querySelector(".b-box--result"); | |
var palette = doc.querySelector(".b-palette"); | |
var steps = doc.querySelector(".b-steps"); | |
var codes = doc.querySelector(".b-codes"); | |
var codesToggle = doc.querySelector(".b-codes__toggle"); | |
var codesCss = doc.querySelector(".textarea--css"); | |
var codesHtml = doc.querySelector(".textarea--html"); | |
var is_opened = false; | |
var oneSide = 7;// dottes in line | |
var dotSize = 30;// pixels | |
var size = oneSide * dotSize; | |
var padding = 20;// pixels. Don't change it | |
var border = 1;// pixels | |
var configElemParams = { | |
".l-wrapper": { | |
"width": size * 2 + padding * 3 + border*6, | |
"height": size + padding * 2 + border*4, | |
"padding": padding | |
}, | |
".b-box": { | |
"width": size + border*2, | |
"height": size + border*2 | |
}, | |
".cell__lbl": { | |
"width": dotSize, | |
"height": dotSize | |
}, | |
".dot": { | |
"width": dotSize, | |
"height": dotSize, | |
"margin": "-" + dotSize + " 0 0 -" + dotSize | |
}, | |
".b-box--paint": { | |
"background-size": dotSize + " " + dotSize | |
} | |
}; | |
var stepsMax = 5; | |
var stylesShadowsClass = "stylesBox"; | |
var stylesColorsClass = "colorsBox"; | |
var stylesConfigClass = "configBox"; | |
var cellClass = "cell"; | |
var cellInpClass = cellClass + "__inp"; | |
var cellLblClass = cellClass + "__lbl"; | |
var colorClass = "color"; | |
var colorInpClass = colorClass + "__inp"; | |
var colorLblClass = colorClass + "__lbl"; | |
var stepClass = "step"; | |
var stepInpClass = stepClass + "__inp"; | |
var stepLblClass = stepClass + "__lbl"; | |
var currentStepNum = 0; | |
var colorStyleTempl = "." + colorClass + "--{i} {background: {color};}\n"; | |
var classIsRunning = "is-running"; | |
var frames = {}; | |
var currentFrame = 0; | |
this.init = function(){ | |
this.cellTempl = createTemplate ( cellClass, "checkbox", "data-hpos=\"{hpos}\" data-vpos=\"{vpos}\" ", "" ); | |
this.colorTempl = createTemplate ( colorClass, "radio", "data-color=\"{color}\" ", "" ); | |
this.stepTempl = createTemplate ( stepClass, "radio", "", "{i+1}" ); | |
this.stylesConfig = addStylesBox(stylesConfigClass); | |
this.stylesColors = addStylesBox(stylesColorsClass); | |
this.stylesShadows = addStylesBox(stylesShadowsClass); | |
this.addConfig(); | |
this.createInputsSet(); | |
this.createFramesSet(); | |
this.createPalette(); | |
this.createSteps(); | |
} | |
// FUNCTIONS | |
// ----------------------------------------- | |
function findKeyFrames(name){ | |
var sheets = doc.styleSheets[1].cssRules; | |
var keyFrames; | |
for (var i = 0; i < doc.styleSheets.length; i++) { | |
var stylesList = doc.styleSheets[i].cssRules; | |
for (var k = 0; k < stylesList.length; k++) { | |
if ( stylesList[k].name == name ){ | |
keyFrames = stylesList[k]; | |
} | |
}; | |
}; | |
return keyFrames; | |
} | |
// ----------------------------------------- | |
this.addConfig = function(){ | |
var styles = ""; | |
out("make config"); | |
//out( configElemParams ); | |
for ( var elem in configElemParams ){ | |
var className = elem; | |
var elemStyles = ""; | |
var params = configElemParams[elem]; | |
for (var item in params){ | |
var value = addUnits( params[item] ); | |
elemStyles += item + ": " + value + ";\n"; | |
} | |
styles += className + " {\n" + elemStyles + "}\n"; | |
} | |
this.stylesConfig.innerHTML = styles; | |
} | |
// ----------------------------------------- | |
function addStylesBox(elemClass){ | |
var elem = doc.createElement( "style" ); | |
elem.classList.add( elemClass ); | |
var head = doc.querySelector( "head" ); | |
head.appendChild( elem ); | |
return elem; | |
} | |
// ----------------------------------------- | |
function createTemplate ( itemType, inputType, data_attr, lblContent ){ | |
var itemInpClass = itemType + "__inp"; | |
var itemLblClass = itemType + "__lbl"; | |
var replacements = { | |
"{inputType}": inputType, | |
"{itemType}": itemType, | |
"{itemClass}": itemType, | |
"{itemLblClass}": itemLblClass, | |
"{itemInpClass}": itemInpClass, | |
"{lblContent}": lblContent | |
}; | |
var itemInputTempl = "<input type='{inputType}' id='{itemType}-{i}' class='" + itemInpClass +"' name='{itemType}' data-{itemType}-num='{i}' " + data_attr + ">";// | |
var itemLabelTempl = "<label for='{itemType}-{i}' class='{itemLblClass} {itemType}--{i}'>{lblContent}</label>"; | |
var itemTempl = "<span class='{itemType}'>" + itemInputTempl + itemLabelTempl +"</span>"; | |
var result = fillTemplate( itemTempl, replacements ); | |
return result; | |
} | |
// ----------------------------------------- | |
this.addEvents = function ( itemsClass, func ){ | |
var items = doc.querySelectorAll("." + itemsClass); | |
var parent = this; | |
for (var i = 0; i < items.length; i++) { | |
items[i].onclick = function() { | |
func.call(parent, this); | |
} | |
} | |
} | |
// ----------------------------------------- | |
this.createInputsSet = function() { | |
for (var i = 0; i < oneSide * oneSide; i++) { | |
var hpos = i % oneSide + 1; | |
var vpos = Math.floor(i / oneSide) + 1; | |
var replacements = { | |
"{i}": i, | |
"{hpos}": hpos, | |
"{vpos}": vpos | |
}; | |
var checkBox = fillTemplate( this.cellTempl, replacements ); | |
paintBox.innerHTML += checkBox; | |
} | |
this.addEvents( cellInpClass, this.onClickCell); | |
} | |
// ----------------------------------------- | |
this.createFramesSet = function() { | |
for (var k = 0; k < stepsMax; k++) { | |
frames[k] = { active: 0 }; | |
for (var i = 0; i < oneSide * oneSide; i++) { | |
var hpos = i % oneSide + 1; | |
var vpos = Math.floor(i / oneSide) + 1; | |
frames[k]["cell-" + i] = { | |
"hpos": hpos, | |
"vpos": vpos, | |
"color": transparent | |
}; | |
} | |
}; | |
} | |
// ----------------------------------------- | |
this.onClickCell = function( elem ) { | |
if( elem !== undefined ){ | |
var cellLbl = elem.nextSibling; | |
this.updateFrames( elem ); | |
} | |
} | |
// ----------------------------------------- | |
this.toggleColorClass = function( elem ) { | |
var findClass = colorClass + "--"; | |
var classes = elem.classList; | |
for (var i = 0; i < classes.length; i++) { | |
if(classes[i].indexOf(findClass) >= 0 ){ | |
classes.remove(classes[i]); | |
return; | |
} | |
} | |
classes.add(findClass + currentColorNum); | |
} | |
// ----------------------------------------- | |
this.updateFrames = function( elem ) { | |
out( "currentColor: " + currentColor); | |
out( frames[currentFrame] ); | |
//if ( frames[currentFrame] == undefined ){ | |
//frames[currentFrame] = {}; | |
//} | |
var place = frames[currentFrame]; | |
var color = transparent; | |
if ( elem.checked ){ | |
color = currentColor; | |
place.active++; | |
} | |
else { | |
place.active--; | |
} | |
place[elem.id].color = color; | |
this.paintShadow(); | |
} | |
// ----------------------------------------- | |
this.paintShadow = function(){ | |
var styles = ""; | |
var animName = "shadows"; | |
var animFrames = {}; | |
var framesLength = objLength(frames); | |
var perc = (100 / framesLength).toFixed(3); | |
var dottes = frames[currentFrame]; | |
var shadows = this.createShadow( dottes ); | |
styles = ".b-box--paint .dot {\n " + shadows + " \n}\n"; | |
dottes = frames[0]; | |
shadows = this.createShadow( dottes ); | |
styles += ".b-box--result .dot {\n " + shadows + " \n}\n"; | |
this.stylesShadows.innerHTML = styles; | |
this.replaceAnimation({perc: perc}); | |
} | |
// ----------------------------------------- | |
this.createShadow = function( dottes ){ | |
if ( dottes == undefined ){ | |
return; | |
} | |
var shadows = ""; | |
var if_first = true; | |
var cellsMax = oneSide * oneSide; | |
for (var i = 0; i < cellsMax; i++) { | |
var dot = dottes["cell-" + i]; | |
var hpos = dot.hpos * dotSize + "px"; | |
var vpos = dot.vpos * dotSize + "px"; | |
var color = transparent; | |
if ( dot.color != transparent ) { | |
color = dot.color; | |
} | |
if ( if_first ){ | |
if_first = false; | |
} | |
else { | |
shadows += ", "; | |
} | |
shadows += hpos + " " + vpos + " 0 0 " + color; | |
}; | |
shadows = "box-shadow: " + shadows + ";"; | |
return shadows; | |
} | |
// ----------------------------------------- | |
this.replaceAnimation = function(animation){ | |
var keyframes = findKeyFrames("shadows"); | |
var rules = keyframes.cssRules; | |
if ( rules.length > 0 ){ | |
for ( var keyframe in rules ) { | |
var keyText = rules[keyframe].keyText; | |
keyframes.deleteRule(keyText); | |
} | |
} | |
for ( var step in frames ){ | |
if ( step == 0 ) continue; | |
var anim_dottes = frames[step]; | |
var anim_shadows = this.createShadow( anim_dottes ); | |
keyframes.insertRule(animation.perc*step + "% {" + anim_shadows + "}"); | |
} | |
var resultDot = doc.querySelector(".b-box--result .dot"); | |
resultDot.classList.remove(classIsRunning); | |
resultDot.offsetWidth = resultDot.offsetWidth; | |
resultDot.classList.add(classIsRunning); | |
} | |
// ----------------------------------------- | |
this.createPalette = function () { | |
var styles = ""; | |
palette.innerHTML += "<h4 class='b-title'>Colors</h4> "; | |
for (var i = 0; i < colors.length; i++) { | |
var replacements = { | |
"{i}": i, | |
"{color}": colors[i] | |
}; | |
var colorItem = fillTemplate( this.colorTempl, replacements ); | |
var colorStyle = fillTemplate( colorStyleTempl, replacements ); | |
this.stylesColors.innerHTML += colorStyle; | |
palette.innerHTML += colorItem; | |
} | |
var first = doc.querySelector("." + colorInpClass); | |
first.checked = true; | |
this.addEvents( colorInpClass, this.onClickColor ); | |
} | |
// ----------------------------------------- | |
this.onClickColor = function( elem ){ | |
currentColor = elem.getAttribute("data-color"); | |
currentColorNum = elem.getAttribute("data-color-num"); | |
currentColorClass = colorClass + "--" + currentColorNum; | |
} | |
// ----------------------------------------- | |
this.createSteps = function(){ | |
steps.innerHTML += "<h4 class='b-title'>Frames</h4> "; | |
for (var i = 0; i < stepsMax; i++) { | |
var replacements = { | |
"{i}": i, | |
"{i+1}": i+1, | |
}; | |
var step = fillTemplate( this.stepTempl, replacements ); | |
steps.innerHTML += step; | |
} | |
var first = doc.querySelector("." + stepInpClass); | |
first.checked = true; | |
this.addEvents( stepInpClass, this.onClickStep ); | |
} | |
// ----------------------------------------- | |
this.onClickStep = function( elem ){ | |
currentFrame = elem.getAttribute("data-step-num"); | |
this.paintShadow(); | |
this.updateCells(); | |
} | |
// ----------------------------------------- | |
this.updateCells = function() { | |
var checkboxes = paintBox.querySelectorAll("input"); | |
var frameCells = frames[currentFrame]; | |
var colored = 0; | |
for (var i = 0; i < checkboxes.length; i++) { | |
var cell = checkboxes[i]; | |
var id = cell.id; | |
var color = frameCells[id].color; | |
if ( color == transparent ){ | |
cell.checked = false; | |
} | |
else { | |
colored++; | |
cell.checked = true; | |
} | |
}; | |
} | |
codesToggle.onclick = function(){ | |
out("Click!"); | |
var textInit = this.getAttribute("data-init"); | |
var textClose = this.getAttribute("data-opened"); | |
var text = textInit; | |
if ( is_opened ){ | |
is_opened = false; | |
} | |
else { | |
is_opened = true; | |
text = textClose; | |
} | |
codes.classList.toggle("is-open"); | |
this.innerText = text; | |
var styleBox = doc.querySelector(".b-box--result");//resultBox | |
var styleDot = doc.querySelector(".b-box--result .dot"); | |
var styles = getComputedStyle(styleBox, '');//.cssText | |
out( "styleBox" ); | |
out( styles ); | |
} | |
}// End Pixelator | |
// Common | |
// ----------------------------------------- | |
function out ( data ) { | |
console.log( data ); | |
} | |
function addUnits( str ){ | |
str = String(str); | |
var arr = str.split(" "); | |
if ( arr.length > 1 | |
&& arr[0].indexOf("px") < 0 | |
&& arr[0].indexOf("em") < 0 | |
&& arr[0].indexOf("%") < 0 ){ | |
str = arr.join("px ") + "px"; | |
return str; | |
} | |
if ( str.indexOf("px") < 0 | |
&& str.indexOf("em") < 0 | |
&& arr[0].indexOf("%") < 0 ) { | |
str += "px"; | |
} | |
return str; | |
} | |
function fillTemplate( dataStr, replacements ) { | |
for ( var key in replacements ){ | |
var findStr = key; | |
var replaceWithStr = replacements[key]; | |
dataStr = dataStr.split(findStr).join(replaceWithStr); | |
} | |
return dataStr; | |
} | |
function objLength( obj ) { | |
var count = 0; | |
for ( var key in obj ){ | |
count++; | |
} | |
return count; | |
} | |
// Init | |
// ----------------------------------------- | |
var painter = new Pixelator(); | |
painter.init(); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import "compass"; | |
$sideCells: 10; | |
$dotSize: 30px; | |
$box-size: $dotSize * $sideCells; | |
$radius: 10%; | |
$padding: 20px; | |
$color-border: #CCC; | |
$color-active: orange; | |
$time: 2s; | |
* { | |
box-sizing: border-box; | |
} | |
LABEL { | |
cursor: pointer; | |
} | |
.l-wrapper { | |
position: absolute; | |
display: inline-block; | |
margin: auto; | |
left: 1em; | |
right: 1em; | |
top: 1em; | |
bottom: 1em; | |
border: 1px solid $color-border; | |
white-space: nowrap; | |
&:after { | |
content: ''; | |
display: table; | |
width: 100%; | |
clear: both; | |
} | |
} | |
.b-box { | |
display: inline-block; | |
border: 1px solid $color-border; | |
&:nth-of-type(1){ | |
margin-right: $padding; | |
} | |
} | |
.b-title { | |
float: left; | |
padding-right: $padding/2; | |
line-height: $dotSize; | |
color: #888; | |
} | |
/* Paint Box | |
----------------------------- */ | |
.b-box--paint { | |
overflow: hidden; | |
background-image: | |
linear-gradient( to right, | |
$color-border 1px, | |
transparent 1px | |
), | |
linear-gradient( to bottom, | |
$color-border 1px, | |
transparent 1px | |
); | |
background-position: 0 0; | |
} | |
/* Labels | |
----------------------------- */ | |
.cell { | |
display: block; | |
float: left; | |
} | |
.cell__inp { | |
position: absolute; | |
display: none; | |
} | |
.cell__lbl { | |
display: block; | |
border-radius: $radius; | |
} | |
:checked + .cell__lbl { | |
position: relative; | |
/* z-index: 5; | |
background: gold; | |
opacity: .5*/ | |
} | |
.is-colored { | |
background: $color-active; | |
} | |
/* Result Box | |
----------------------------- */ | |
.b-box--result { | |
overflow: hidden; | |
} | |
.dot { | |
display: block; | |
position: relative; | |
border-radius: $radius; | |
} | |
//.b-box--result .dot | |
.is-running{ | |
-webkit-animation: $time shadows linear infinite; | |
animation: $time shadows linear infinite; | |
} | |
@keyframes shadows { | |
} | |
@-webkit-keyframes shadows { | |
} | |
/* Palette | |
----------------------------- */ | |
.b-palette { | |
position: absolute; | |
border: 1px solid $color-border; | |
top: -($dotSize + $padding); | |
left: $padding/2; | |
height: $dotSize + $padding; | |
padding: $padding/2; | |
} | |
.color { | |
display: block; | |
float: left; | |
width: $dotSize; | |
height: $dotSize; | |
} | |
.color__inp { | |
display: none; | |
} | |
.color__lbl { | |
display: block; | |
height: $dotSize; | |
} | |
:checked + .color__lbl { | |
position: relative; | |
z-index: 1; | |
box-shadow: 0 0 0 3px rgba(0, 0, 0, .3); | |
} | |
/* Steps | |
----------------------------- */ | |
.b-steps { | |
position: absolute; | |
border: 1px solid $color-border; | |
left: $padding/2; | |
bottom: -($dotSize + $padding); | |
height: $dotSize + $padding; | |
padding: $padding/2; | |
} | |
.step { | |
display: block; | |
float: left; | |
width: $dotSize; | |
height: $dotSize; | |
margin-right: 1px; | |
line-height: $dotSize; | |
background: gainsboro; | |
text-align: center; | |
} | |
.step__inp { | |
position: absolute; | |
display: none; | |
} | |
.step__lbl { | |
display: block; | |
height: $dotSize; | |
} | |
:checked + .step__lbl { | |
position: relative; | |
z-index: 1; | |
box-shadow: 0 0 0 3px rgba(0, 0, 0, .3); | |
} | |
.step--filled { | |
background: paleturquoise; | |
} | |
/* Codes | |
----------------------------- */ | |
.b-codes { | |
display: none; | |
position: absolute; | |
z-index: 10; | |
top: 0; | |
right: 0; | |
left: 0; | |
background: rgba(240, 240, 240, .9); | |
} | |
.is-open { | |
top: -$padding*3; | |
right: -1em; | |
bottom: -$padding*3; | |
left: -1em; | |
} | |
.b-codes__toggle { | |
position: absolute; | |
top: -$padding*1.2; | |
right: $padding/2; | |
border-bottom: 1px dotted; | |
color: #555; | |
} | |
.b-codes__wrapper { | |
display: none; | |
padding: $padding; | |
.is-open & { | |
display: block; | |
} | |
} | |
.b-codes--title { | |
margin-bottom: $padding/3; | |
color: #333; | |
} | |
.b-codes__textarea { | |
display: block; | |
width: 100%; | |
height: $dotSize*2; | |
border: 1px solid $color-border; | |
} | |
.textarea--css { | |
margin-bottom: $padding; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment