mozilla
Your Search Results

    Box-shadow generator

    This tool lets you construct CSS box-shadow effects, to add box shadow effects to your CSS objects.

    box-shadow generator

    HTML Content

    <div id="container">
        <div class="group section">
            <div id="layer_manager">
                <div class="group section">
                    <div class="button" data-type="add"> </div>
                    <div class="button" data-type="move-up"> </div>
                    <div class="button" data-type="move-down"> </div>
                </div>
                <div id="stack_container"></div>
            </div>
    
            <div id="preview_zone">
                <div id="layer_menu" class="col span_12">
                    <div class="button" id="element" data-type="subject" data-title="element"> element </div>
                    <div class="button" id="before" data-type="subject" data-title=":before">
                        :before
                        <span class="delete" data-type="disable"></span>
                    </div>
                    <div class="button" id="after" data-type="subject" data-title=":after">
                        :after
                        <span class="delete" data-type="disable"></span>
                    </div>
                    <div class="ui-checkbox" data-topic='before' data-label=":before"></div>
                    <div class="ui-checkbox" data-topic='after' data-label=":after"></div>
                </div>
    
                <div id="preview">
                    <div id="obj-element">
                        <div class="content"> </div>
                        <div id="obj-before"> </div>
                        <div id="obj-after"> </div>
                    </div>
                </div>
            </div>
        </div>
    
        <div id="controls" class="group section">
            <div class="wrap-left">
                <div class="colorpicker category">
                    <div class="title"> </div>
                    <div id="colorpicker" class="group">
                        <div id="gradient" class="gradient">
                            <div id="gradient_picker"> </div>
                        </div>
                        <div id="hue" data-topic="hue" class="hue">
                            <div id="hue_selector"> </div>
                        </div>
                        <div class="info">
                            <div class="input" data-topic="hue" data-title='H:' data-action="HSV"></div>
                            <div class="input" data-topic="saturation" data-title='S:' data-action="HSV"></div>
                            <div class="input" data-topic="value" data-title='V:' data-action="HSV"></div>
                        </div>
                        <div class="alpha">
                            <div id="alpha" data-topic="alpha">
                                <div id="alpha_selector"> </div>
                            </div>
                        </div>
                        <div class="info">
                            <div class="input" data-topic="r" data-title='R:' data-action="RGB"></div>
                            <div class="input" data-topic="g" data-title='G:' data-action="RGB"></div>
                            <div class="input" data-topic="b" data-title='B:' data-action="RGB"></div>
                        </div>
                        <div class="preview block">
                            <div id="output_color"> </div>
                        </div>
                        <div class="block info">
                            <div class="input" data-topic="a" data-title='alpha:' data-action="alpha"></div>
                            <div class="input" data-topic="hexa" data-title='' data-action="hexa"></div>
                        </div>
                    </div>
                </div>
            </div>
    
            <div class="wrap-right">
    
                <div id="shadow_properties" class="category">
                    <div class="title"> Shadow properties </div>
                    <div class="group">
                        <div class="group property">
                            <div class="ui-slider-name"> inset </div>
                            <div class="ui-checkbox" data-topic='inset'></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> Position x </div>
                            <div class="ui-slider-btn-set" data-topic="posX" data-type="sub"></div>
                            <div class="ui-slider" data-topic="posX"
                                data-min="-500" data-max="500" data-step="1"> </div>
                            <div class="ui-slider-btn-set" data-topic="posX" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="posX" data-unit="px"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> Position y </div>
                            <div class="ui-slider-btn-set" data-topic="posY" data-type="sub"></div>
                            <div class="ui-slider" data-topic="posY"
                                data-min="-500" data-max="500" data-step="1"> </div>
                            <div class="ui-slider-btn-set" data-topic="posY" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="posY" data-unit="px"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> Blur </div>
                            <div class="ui-slider-btn-set" data-topic="blur" data-type="sub"></div>
                            <div class="ui-slider" data-topic="blur"
                                data-min="0" data-max="200" data-step="1"> </div>
                            <div class="ui-slider-btn-set" data-topic="blur" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="blur" data-unit="px"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> Spread </div>
                            <div class="ui-slider-btn-set" data-topic="spread" data-type="sub"></div>
                            <div class="ui-slider" data-topic="spread"
                                data-min="-100"    data-max="100" data-step="1" data-value="50">
                            </div>
                            <div class="ui-slider-btn-set" data-topic="spread" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="spread" data-unit="px"></div>
                        </div>
                    </div>
                </div>
    
                <div id="element_properties" class="category">
                    <div class="title"> Class element properties </div>
                    <div class="group">
                        <div class="group property">
                            <div class="ui-slider-name"> border </div>
                            <div class="ui-checkbox" data-topic='border-state' data-state="true"></div>
                        </div>
                        <div id="z-index" class="slidergroup">
                            <div class="ui-slider-name"> z-index </div>
                            <div class="ui-slider-btn-set" data-topic="z-index" data-type="sub"></div>
                            <div class="ui-slider" data-topic="z-index"
                                data-min="-10" data-max="10" data-step="1"></div>
                            <div class="ui-slider-btn-set" data-topic="z-index" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="z-index"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> top </div>
                            <div class="ui-slider-btn-set" data-topic="top" data-type="sub"></div>
                            <div class="ui-slider" data-topic="top"
                                data-min="-500" data-max="500" data-step="1"> </div>
                            <div class="ui-slider-btn-set" data-topic="top" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="top" data-unit="px"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> left </div>
                            <div class="ui-slider-btn-set" data-topic="left" data-type="sub"></div>
                            <div class="ui-slider" data-topic="left"
                                data-min="-300" data-max="700" data-step="1"> </div>
                            <div class="ui-slider-btn-set" data-topic="left" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="left" data-unit="px"></div>
                        </div>
                        <div id="transform_rotate" class="slidergroup">
                            <div class="ui-slider-name"> Rotate </div>
                            <div class="ui-slider-btn-set" data-topic="rotate" data-type="sub"></div>
                            <div class="ui-slider" data-topic="rotate"
                                data-min="-360" data-max="360" data-step="1" data-value="0">
                            </div>
                            <div class="ui-slider-btn-set" data-topic="rotate" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="rotate" data-unit="deg"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> Width </div>
                            <div class="ui-slider-btn-set" data-topic="width" data-type="sub"></div>
                            <div class="ui-slider" data-topic="width"
                                data-min="0" data-max="1000" data-step="1" data-value="200">
                            </div>
                            <div class="ui-slider-btn-set" data-topic="width" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="width"  data-unit="px"></div>
                        </div>
                        <div class="slidergroup">
                            <div class="ui-slider-name"> Height </div>
                            <div class="ui-slider-btn-set" data-topic="height" data-type="sub"></div>
                            <div class="ui-slider" data-topic="height"
                                data-min="0" data-max="400" data-step="1" data-value="200">
                            </div>
                            <div class="ui-slider-btn-set" data-topic="height" data-type="add"></div>
                            <div class="ui-slider-input" data-topic="height" data-unit="px"></div>
                        </div>
                    </div>
                </div>
    
                <div id="output" class="category">
                    <div id="menu" class="menu"></div>
                    <div class="title">    CSS Code </div>
                    <div class="group" style="border-top-left-radius: 0;">
                        <div class="output" data-topic="element" data-name="element"
                            data-prop="width height background-color position=[relative] box-shadow">
                        </div>
                        <div class="output" data-topic="before" data-name="element:before"
                            data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
                        </div>
                        <div class="output" data-topic="after" data-name="element:after"
                            data-prop="content=[&quot;&quot;] position=[absolute] width height top left z-index background-color box-shadow transform -webkit-transform -ms-transform">
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    CSS Content

    /*  GRID OF TWELVE
     * ========================================================================== */
    
    .span_12 {
    	width: 100%;
    }
    
    .span_11 {
    	width: 91.46%;
    }
    
    .span_10 {
    	width: 83%;
    }
    
    .span_9 {
    	width: 74.54%;
    }
    
    .span_8 {
    	width: 66.08%;
    }
    
    .span_7 {
    	width: 57.62%;
    }
    
    .span_6 {
    	width: 49.16%;
    }
    
    .span_5 {
    	width: 40.7%;
    }
    
    .span_4 {
    	width: 32.24%;
    }
    
    .span_3 {
    	width: 23.78%;
    }
    
    .span_2 {
    	width: 15.32%;
    }
    
    .span_1 {
    	width: 6.86%;
    }
    
    
    /*  SECTIONS
     * ========================================================================== */
    
    .section {
    	clear: both;
    	padding: 0px;
    	margin: 0px;
    }
    
    /*  GROUPING
     * ========================================================================== */
    
    
    .group:before, .group:after {
        content: "";
        display: table;
    }
    
    .group:after {
        clear:both;
    }
    
    .group {
        zoom: 1; /* For IE 6/7 (trigger hasLayout) */
    }
    
    /*  GRID COLUMN SETUP
     * ========================================================================== */
    
    .col {
    	display: block;
    	float:left;
    	margin: 1% 0 1% 1.6%;
    }
    
    .col:first-child {
    	margin-left: 0;
    } /* all browsers except IE6 and lower */
    
    /*
     * UI Slider
     */
    
    .slidergroup {
    	height: 20px;
    	margin: 10px 0;
    	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
    	-moz-user-select: none;
    	user-select: none;
    }
    
    .slidergroup * {
    	float: left;
    	height: 100%;
    	line-height: 100%;
    }
    
    /* Slider */
    
    .ui-slider {
    	height: 10px;
    	width: 200px;
    	margin: 4px 10px;
    	display: block;
    	border: 1px solid #999;
    	border-radius: 3px;
    	background: #EEE;
    }
    
    .ui-slider:hover {
    	cursor: pointer;
    }
    
    .ui-slider-name {
    	width: 90px;
    	padding: 0 10px 0 0;
    	text-align: right;
    	text-transform: lowercase;
    }
    
    .ui-slider-pointer {
    	width: 13px;
    	height: 13px;
    	background-color: #EEE;
    	border: 1px solid #2C9FC9;
    	border-radius: 3px;
    	position: relative;
    	top: -3px;
    	left: 0%;
    }
    
    .ui-slider-btn-set {
    	width: 25px;
    	background-color: #2C9FC9;
    	border-radius: 3px;
    	color: #FFF;
    	font-weight: bold;
    	text-align: center;
    }
    
    .ui-slider-btn-set:hover {
    	background-color: #379B4A;
    	cursor: pointer;
    }
    
    .ui-slider-input > input {
    	margin: 0 10px;
    	padding: 0;
    	width: 50px;
    	text-align: center;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    /*
     * UI Button
     */
    
    /* Checkbox */
    
    .ui-checkbox {
    	text-align: center;
    	font-size: 16px;
    	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
    	line-height: 1.5em;
    	color: #FFF;
    
    	-moz-user-select: none;
    	-webkit-user-select: none;
    	-ms-user-select: none;
    	user-select: none;
    }
    
    .ui-checkbox > input {
     	display: none;
    }
    
    .ui-checkbox > label {
    	font-size: 12px;
    	padding: 0.333em 1.666em 0.5em;
    	height: 1em;
    	line-height: 1em;
    
    	background-color: #888;
    	background-image: url("https://mdn.mozillademos.org/files/5683/disabled.png");
    	background-position: center center;
    	background-repeat: no-repeat;
    
    	color: #FFF;
    	border-radius: 3px;
    	font-weight: bold;
    	float: left;
    }
    
    .ui-checkbox .text {
    	padding-left: 34px;
    	background-position: center left 10px;
    }
    
    .ui-checkbox .left {
    	padding-right: 34px;
    	padding-left: 1.666em;
    	background-position: center right 10px;
    }
    
    .ui-checkbox > label:hover {
    	cursor: pointer;
    }
    
    .ui-checkbox > input:checked + label {
    	background-image: url("https://mdn.mozillademos.org/files/5681/checked.png");
    	background-color: #379B4A;
    }
    
    /*
     * BOX SHADOW GENERATOR TOOL
     */
    
    body {
    	max-width: 1000px;
    	height: 800px;
    	margin: 20px auto 0;
    
    	font-family: "Segoe UI", Arial, Helvetica, sans-serif;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    
    	-moz-user-select: none;
    	-webkit-user-select: none;
    	-ms-user-select: none;
    }
    
    #container {
    	width: 100%;
    	padding: 2px;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    
    /* container with shadows stacks */
    #stack_container {
    	height: 400px;
    	overflow: hidden;
    	position: relative;
    	border: 1px solid #CCC;
    	border-radius: 3px;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    #stack_container .container {
    	height: 100%;
    	width: 100%;
    	position: absolute;
    	left: 100%;
    	transition-property: left;
    	transition-duration: 0.5s;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    
    #stack_container .title {
    	text-align: center;
    	font-weight: bold;
    	line-height: 2em;
    	border-bottom: 1px solid #43A6E1;
    	color: #666;
    }
    
    
    /*
     * Stack of Layers for shadow
     */
    
    #layer_manager {
    	width: 17%;
    	background-color: #FEFEFE;
    	margin: 0 1% 0 0;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    	float: left;
    }
    
    
    #layer_manager .button {
    	width: 30%;
    	height: 25px;
    	margin:0 0 10px;
    	color: #333;
    	background-color: #EEE;
    	text-align: center;
    	font-size: 0.75em;
    	line-height: 1.5em;
    	border: 1px solid #CCC;
    	border-radius: 3px;
    
    	display: block;
    	background-position: center center;
    	background-repeat: no-repeat;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    	float: left;
    }
    
    #layer_manager .button:hover {
    	background-color: #3380C4;
    	border: 1px solid #3380C4;
    	cursor: pointer;
    }
    
    #layer_manager [data-type='add'] {
    	background-image: url("https://mdn.mozillademos.org/files/5685/add-black.png");
    }
    
    #layer_manager [data-type='add']:hover {
    	background-image: url("https://mdn.mozillademos.org/files/5687/add-white.png");
    }
    
    #layer_manager [data-type='move-up'] {
    	background-image: url("https://mdn.mozillademos.org/files/5697/up-black.png");
    	margin-left: 5%;
    	margin-right: 5%;
    }
    
    #layer_manager [data-type='move-up']:hover {
    	background-image: url("https://mdn.mozillademos.org/files/5709/up-white.png");
    }
    
    #layer_manager [data-type='move-down'] {
    	background-image: url("https://mdn.mozillademos.org/files/5693/down-black.png");
    }
    
    #layer_manager [data-type='move-down']:hover {
    	background-image: url("https://mdn.mozillademos.org/files/5695/down-white.png");
    }
    
    /* shadows classes */
    
    #layer_manager .node {
    	width: 100%;
    	margin: 5px 0;
    	padding: 5px;
    	text-align: center;
    	background-color: #EEE;
    	border: 1px solid #DDD;
    	font-size: 0.75em;
    	line-height: 1.5em;
    	color: #333;
    	border-radius: 3px;
    
    	position: relative;
    	display: block;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    #layer_manager .node:hover {
    	color: #FFF;
    	background-color: #3380C4;
    	cursor: pointer;
    }
    
    /* active element styling */
    
    #layer_manager [data-active='layer'] {
    	color: #FFF;
    	border: none;
    	background-color: #379B4A;
    }
    
    #layer_manager [data-active='subject'] {
    	color: #FFF;
    	background-color: #467FC9;
    }
    
    /* delete button */
    
    #layer_manager .delete {
    	width: 1.5em;
    	height: 100%;
    	float: right;
    	border-radius: 3px;
    	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
    	background-position: center center;
    	background-repeat: no-repeat;
    	position: absolute;
    	top: 0;
    	right: 10px;
    	display: none;
    }
    
    #layer_manager .delete:hover {
    	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
    }
    
    #layer_manager .node:hover .delete {
    	display: block;
    }
    
    
    #layer_manager .stack {
    	padding: 0 5px;
    	max-height: 90%;
    	overflow: auto;
    	overflow-x: hidden;
    }
    
    
    /*
     * Layer Menu
     */
    
    #layer_menu {
    	margin: 0 0 10px 0;
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    #layer_menu .button {
    	width: 100px;
    	margin: 0 5px 0 0;
    	padding: 2.5px;
    	color: #333;
    	background-color: #EEE;
    	border: 1px solid #CCC;
    	border-radius: 3px;
    	text-align: center;
    	font-size: 0.75em;
    	line-height: 1.5em;
    
    	position: relative;
    	display: block;
    	float: left;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    #layer_menu .button:hover {
    	color: #FFF;
    	background-color: #3380C4;
    	border: 1px solid #3380C4;
    	cursor: pointer;
    }
    
    #layer_menu .delete {
    	width: 1.5em;
    	height: 100%;
    	float: right;
    	border-radius: 3px;
    	background-image: url("https://mdn.mozillademos.org/files/5689/delete-white.png");
    	background-position: center center;
    	background-repeat: no-repeat;
    	position: absolute;
    	top: 0;
    	right: 5px;
    	display: none;
    }
    
    #layer_menu .delete:hover {
    	background-image: url("https://mdn.mozillademos.org/files/5691/delete-yellow.png");
    }
    
    #layer_menu .button:hover .delete {
    	display: block;
    }
    
    
    /*
     * active element styling
     */
    
    #layer_menu [data-active='subject'] {
    	color: #FFF;
    	background-color: #379B4A;
    	border: 1px solid #379B4A;
    }
    
    
    /* Checkbox */
    
    #layer_menu .ui-checkbox > label {
    	height: 15px;
    	line-height: 17px;
    	font-weight: normal;
    	width: 46px;
    	margin: 0 5px 0 0;
    }
    
    #layer_menu .ui-checkbox > input:checked + label {
    	display: none;
    }
    
    
    /******************************************************************************/
    /******************************************************************************/
    /*
     * Preview Area
     */
    
    #preview_zone {
    	width: 82%;
    	float: left;
    
    }
    
    
    #preview {
    	width: 100%;
    	height: 400px;
    	border: 1px solid #CCC;
    	border-radius: 3px;
    	text-align: center;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    	cursor: move;
    	float: left;
    }
    
    #preview .content {
    	width: 100%;
    	height: 100%;
    	display: block;
    }
    
    #obj-element {
    	width: 300px;
    	height: 100px;
    	border: 1px solid #CCC;
    	background: #FFF;
    	position: relative;
    }
    
    
    #obj-before {
    	height: 100%;
    	width: 100%;
    	background: #999;
    	border: 1px solid #CCC;
    	text-align: left;
    	display : block;
    	position: absolute;
    	z-index: -1;
    }
    
    #obj-after {
    	height: 100%;
    	width: 100%;
    	background: #DDD;
    	border: 1px solid #CCC;
    	text-align: right;
    	display : block;
    	position: absolute;
    	z-index: -1;
    }
    
    
    /******************************************************************************/
    /******************************************************************************/
    
    /**
     * Controls
     */
    
    .wrap-left {
    	float: left;
    	overflow: hidden;
    }
    
    .wrap-right {
    	float: right;
    	overflow: hidden;
    }
    
    .wrap-left > * {
    	float: left;
    }
    
    .wrap-right > * {
    	float: right;
    }
    
    @media (min-width: 960px) {
    
    	.wrap-left {
    		width: 45%;
    	}
    
    	.wrap-right {
    		width: 55%;
    	}
    }
    
    
    @media (max-width: 959px) {
    
    	.wrap-left {
    		width: 30%;
    	}
    
    	.wrap-right {
    		width: 70%;
    	}
    }
    
    
    #controls {
    	color: #444;
    	margin: 10px 0 0 0;
    }
    
    
    #controls .category {
    	width: 500px;
    	margin: 0 auto 20px;
    	padding: 0;
    
    }
    
    #controls .category .title {
    	width: 100%;
    	height: 1.5em;
    	line-height: 1.5em;
    	color: #AAA;
    	text-align: right;
    }
    
    #controls .category > .group {
    	border: 1px solid #CCC;
    	border-radius: 3px;
    }
    
    
    /**
     * 	Color Picker
     */
    
    @media (min-width: 960px) {
    	#controls .colorpicker {
    		width: 420px;
    	}
    }
    
    @media (max-width: 959px) {
    	#controls .colorpicker {
    		width: 210px;
    	}
    }
    
    #colorpicker {
    	width: 100%;
    	margin: 0 auto;
    }
    
    #colorpicker .gradient {
    	width: 200px;
    	height: 200px;
    	margin: 5px;
    	background: url("https://mdn.mozillademos.org/files/5707/picker_mask_200.png");
    	background: -moz-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
    				-moz-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
    	background: -webkit-linear-gradient(bottom, #000 0%, rgba(0, 0, 0, 0) 100%),
    				-webkit-linear-gradient(left, #FFF 0%, rgba(255, 255, 255, 0) 100%);
    	background-color: #F00;
    	float: left;
    }
    
    #colorpicker .hue {
    	width: 200px;
    	height: 30px;
    	margin: 5px;
    	background: url("https://mdn.mozillademos.org/files/5701/hue.png");
    	background: -moz-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
    				#00F 66.66%, #F0F 83.33%, #F00 100%);
    	background: -webkit-linear-gradient(left, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%,
    				#00F 66.66%, #F0F 83.33%, #F00 100%);
    	float: left;
    }
    
    #colorpicker .alpha {
    	width: 200px;
    	height: 30px;
    	margin: 5px;
    	border: 1px solid #CCC;
    	float: left;
    	background: url("https://mdn.mozillademos.org/files/5705/alpha.png");
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    #colorpicker #alpha {
    	width: 100%;
    	height: 100%;
    	background: url("https://mdn.mozillademos.org/files/5703/alpha_mask.png");
    	background: -moz-linear-gradient(left, rgba(255, 0, 0, 0) 0%, rgba(255, 0, 0, 1) 100%);
    }
    
    #colorpicker #gradient_picker {
    	width: 0.5em;
    	height: 0.5em;
    	border-radius: 0.4em;
    	border: 2px solid #CCC;
    	position: relative;
    	top: 20%;
    	left: 20%;
    }
    
    #colorpicker #hue_selector,
    #colorpicker #alpha_selector {
    	width: 3px;
    	height: 100%;
    	border: 1px solid #777;
    	background-color: #FFF;
    	position: relative;
    	top: -1px;
    	left: 0%;
    }
    
    /* input HSV and RGB */
    #colorpicker .info {
    	width: 200px;
    	margin: 5px;
    	float: left;
    }
    
    #colorpicker .info * {
    	float: left;
    }
    
    #colorpicker .info input {
    	margin: 0;
    	text-align: center;
    	width: 30px;
    	-moz-user-select: text;
    	-webkit-user-select: text;
    	-ms-user-select: text;
    }
    
    #colorpicker .info span {
    	height: 20px;
    	width: 30px;
    	text-align: center;
    	line-height: 20px;
    	display: block;
    }
    
    /* Preview color */
    #colorpicker .block {
    	width: 95px;
    	height: 54px;
    	float: left;
    	position: relative;
    }
    
    #colorpicker .preview {
    	margin: 5px;
    	border: 1px solid #CCC;
    	background-image: url("https://mdn.mozillademos.org/files/5705/alpha.png");
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    #colorpicker .preview:before {
    	height: 100%;
    	width: 50%;
    	left: 50%;
    	content: "";
    	background: #FFF;
    	position: absolute;
    	z-index: 1;
    }
    
    #colorpicker .preview > * {
    	width: 50%;
    	height: 100%;
    }
    
    #colorpicker #output_color {
    	width: 100%;
    	height: 100%;
    	position: absolute;
    	z-index: 2;
    }
    
    #colorpicker .block .input {
    	float: right;
    }
    
    #colorpicker [data-topic="a"] > span {
    	width: 50px;
    }
    
    #colorpicker [data-topic="hexa"] {
    	float: right;
    	margin: 10px 0 0 0;
    }
    
    #colorpicker [data-topic="hexa"] > span {
    	display: none;
    }
    
    #colorpicker [data-topic="hexa"] > input {
    	width: 85px;
    	padding: 2px 0;
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    }
    
    
    /*
     * UI Components
     */
    
    /* Property */
    
    .property {
    	height: 20px;
    	margin: 10px 0;
    }
    
    .property * {
    	float: left;
    	height: 100%;
    	line-height: 100%;
    }
    
    /* Slider */
    
    #controls .ui-slider-name {
    	margin: 0 10px 0 0;
    }
    
    /*
     * Output code styling
     */
    
    #output {
    	position: relative;
    }
    
    #output .menu {
    	max-width: 70%;
    	height: 20px;
    	position: absolute;
    	top: 2px;
    }
    
    #output .button {
    	width: 90px;
    	height: 22px;
    	margin: 0 5px 0 0;
    	text-align: center;
    	line-height: 20px;
    	font-size: 14px;
    	color: #FFF;
    	background-color: #999;
    	border-top-left-radius: 3px;
    	border-top-right-radius: 3px;
    	bottom: -5px;
    	float:left;
    }
    
    #output .button:hover {
    	color: #FFF;
    	background-color: #666;
    	cursor: pointer;
    }
    
    #output .menu [data-active="true"] {
    	color: #777;
    	background-color: #FFF;
    	border: 1px solid #CCC;
    	border-bottom: none;
    }
    
    #output .menu [data-topic="before"] {
    	left: 100px;
    }
    
    #output .menu [data-topic="after"] {
    	left: 200px;
    }
    
    #output .output {
    	width: 480px;
    	margin: 10px;
    	padding: 10px;
    	overflow: hidden;
    	color: #555;
    	font-size: 14px;
    	border: 1px dashed #CCC;
    	border-radius: 3px;
    	display: none;
    
    	-moz-box-sizing: border-box;
    	-webkit-box-sizing: border-box;
    	box-sizing: border-box;
    
    	-moz-user-select: text;
    	-webkit-user-select: text;
    	-ms-user-select: text;
    }
    
    #output .css-property {
    	width: 100%;
    	float: left;
    	white-space: pre;
    }
    
    #output .name {
    	width: 35%;
    	float: left;
    }
    
    #output .value {
    	width: 65%;
    	float: left;
    }
    
    

    JavaScript Content

    
    
    'use strict';
    
    /**
     * UI-SlidersManager
     */
    
    var SliderManager = (function SliderManager() {
    
    	var subscribers = {};
    	var sliders = [];
    
    	var Slider = function(node) {
    		var min = node.getAttribute('data-min') | 0;
    		var max = node.getAttribute('data-max') | 0;
    		var step = node.getAttribute('data-step') | 0;
    		var value = node.getAttribute('data-value') | 0;
    		var snap = node.getAttribute('data-snap');
    		var topic = node.getAttribute('data-topic');
    
    		this.min = min;
    		this.max = max > 0 ? max : 100;
    		this.step = step === 0 ? 1 : step;
    		this.value = value <= max && value >= min ? value : (min + max) / 2 | 0;
    		this.snap = snap === "true" ? true : false;
    		this.topic = topic;
    		this.node = node;
    
    		var pointer = document.createElement('div');
    		pointer.className = 'ui-slider-pointer';
    		node.appendChild(pointer);
    		this.pointer = pointer;
    
    		setMouseTracking(node, updateSlider.bind(this));
    
    		sliders[topic] = this;
    		setValue(topic, this.value);
    	}
    
    	var setButtonComponent = function setButtonComponent(node) {
    		var type = node.getAttribute('data-type');
    		var topic = node.getAttribute('data-topic');
    		if (type === "sub") {
    			node.textContent = '-';
    			node.addEventListener("click", function() {
    				decrement(topic);
    			});
    		}
    		if (type === "add") {
    			node.textContent = '+';
    			node.addEventListener("click", function() {
    				increment(topic);
    			});
    		}
    	}
    
    	var setInputComponent = function setInputComponent(node) {
    		var topic		= node.getAttribute('data-topic');
    		var unit_type	= node.getAttribute('data-unit');
    
    		var input = document.createElement('input');
    		var unit = document.createElement('span');
    		unit.textContent = unit_type;
    
    		input.setAttribute('type', 'text');
    		node.appendChild(input);
    		node.appendChild(unit);
    
    		input.addEventListener('click', function(e) {
    			this.select();
    		});
    
    		input.addEventListener('change', function(e) {
    			setValue(topic, e.target.value | 0);
    		});
    
    		subscribe(topic, function(value) {
    			node.children[0].value = value;
    		});
    	}
    
    	var increment = function increment(topic) {
    		var slider = sliders[topic];
    		if (slider === null || slider === undefined)
    			return;
    
    		if (slider.value + slider.step <= slider.max) {
    			slider.value += slider.step;
    			setValue(slider.topic, slider.value)
    			notify.call(slider);
    		}
    	};
    
    	var decrement = function decrement(topic) {
    		var slider = sliders[topic];
    		if (slider === null || slider === undefined)
    			return;
    
    		if (slider.value - slider.step >= slider.min) {
    			slider.value -= slider.step;
    			setValue(topic, slider.value)
    			notify.call(slider);
    		}
    	}
    
    	// this = Slider object
    	var updateSlider = function updateSlider(e) {
    		var node = this.node;
    		var pos = e.pageX - node.offsetLeft;
    		var width = node.clientWidth;
    		var delta = this.max - this.min;
    		var offset = this.pointer.clientWidth + 4; // border width * 2
    
    		if (pos < 0) pos = 0;
    		if (pos > width) pos = width;
    
    		var value = pos * delta / width | 0;
    		var precision = value % this.step;
    		value = value - precision + this.min;
    		if (precision > this.step / 2)
    			value = value + this.step;
    
    		if (this.snap)
    			pos =  (value - this.min) * width / delta;
    
    		this.pointer.style.left = pos - offset/2 + "px";
    		this.value = value;
    		node.setAttribute('data-value', value);
    		notify.call(this);
    	}
    
    	var setValue = function setValue(topic, value) {
    		var slider = sliders[topic];
    
    		if (value > slider.max || value < slider.min)
    			return;
    
    		var delta = slider.max - slider.min;
    		var width = slider.node.clientWidth;
    		var offset = slider.pointer.clientWidth;
    		var pos =  (value - slider.min) * width / delta;
    		slider.value = value;
    		slider.pointer.style.left = pos - offset / 2 + "px";
    		slider.node.setAttribute('data-value', value);
    		notify.call(slider);
    	}
    
    	var setMouseTracking = function setMouseTracking(elem, callback) {
    		elem.addEventListener("mousedown", function(e) {
    			callback(e);
    			document.addEventListener("mousemove", callback);
    		});
    
    		document.addEventListener("mouseup", function(e) {
    			document.removeEventListener("mousemove", callback);
    		});
    	}
    
    	var subscribe = function subscribe(topic, callback) {
    		if (subscribers[topic] === undefined)
    			subscribers[topic] = [];
    		subscribers[topic].push(callback);
    	}
    
    	var unsubscribe = function unsubscribe(topic, callback) {
    		subscribers[topic].indexOf(callback);
    		subscribers[topic].splice(index, 1);
    	}
    
    	var notify = function notify() {
    		if (subscribers[this.topic] === undefined)
    			return;
    
    		for (var i in subscribers[this.topic]) {
    			subscribers[this.topic][i](this.value);
    		}
    	}
    
    	var init = function init() {
    		var elem, size;
    
    		elem = document.querySelectorAll('.ui-slider-btn-set');
    		size = elem.length;
    		for (var i = 0; i < size; i++)
    			setButtonComponent(elem[i]);
    
    		elem = document.querySelectorAll('.ui-slider-input');
    		size = elem.length;
    		for (var i = 0; i < size; i++)
    			setInputComponent(elem[i]);
    
    		elem = document.querySelectorAll('.ui-slider');
    		size = elem.length;
    		for (var i = 0; i < size; i++)
    			new Slider(elem[i]);
    	}
    
    	return {
    		init : init,
    		setValue : setValue,
    		subscribe : subscribe,
    		unsubscribe : unsubscribe
    	}
    
    })();
    
    /**
     * UI-ButtonManager
     */
    
    var ButtonManager = (function CheckBoxManager() {
    
    	var subscribers = [];
    	var buttons = [];
    
    	var CheckBox = function CheckBox(node) {
    		var topic = node.getAttribute('data-topic');
    		var state = node.getAttribute('data-state');
    		var name = node.getAttribute('data-label');
    		var align = node.getAttribute('data-text-on');
    
    		state = (state === "true");
    
    		var checkbox = document.createElement("input");
    		var label = document.createElement("label");
    
    		var id = 'checkbox-' + topic;
    		checkbox.id = id;
    		checkbox.setAttribute('type', 'checkbox');
    		checkbox.checked = state;
    
    		label.setAttribute('for', id);
    		if (name) {
    			label.className = 'text';
    			if (align)
    				label.className += ' ' + align;
    			label.textContent = name;
    		}
    
    		node.appendChild(checkbox);
    		node.appendChild(label);
    
    		this.node = node;
    		this.topic = topic;
    		this.checkbox = checkbox;
    
    		checkbox.addEventListener('change', function(e) {
    			notify.call(this);
    		}.bind(this));
    
    		buttons[topic] = this;
    	}
    
    	var getNode =  function getNode(topic) {
    		return buttons[topic].node;
    	}
    
    	var setValue = function setValue(topic, value) {
    		try {
    			buttons[topic].checkbox.checked = value;
    			notify.call(buttons[topic]);
    		}
    		catch(error) {
    			console.log(error, topic, value);
    		}
    	}
    
    	var subscribe = function subscribe(topic, callback) {
    		if (subscribers[topic] === undefined)
    			subscribers[topic] = [];
    
    		subscribers[topic].push(callback);
    	}
    
    	var unsubscribe = function unsubscribe(topic, callback) {
    		subscribers[topic].indexOf(callback);
    		subscribers[topic].splice(index, 1);
    	}
    
    	var notify = function notify() {
    		if (subscribers[this.topic] === undefined)
    			return;
    		for (var i = 0; i < subscribers[this.topic].length; i++)
    			subscribers[this.topic][i](this.checkbox.checked);
    	}
    
    	var init = function init() {
    		var elem = document.querySelectorAll('.ui-checkbox');
    		var size = elem.length;
    		for (var i = 0; i < size; i++)
    			new CheckBox(elem[i]);
    	}
    
    	return {
    		init : init,
    		setValue : setValue,
    		subscribe : subscribe,
    		unsubscribe : unsubscribe
    	}
    
    })();
    
    
    window.addEventListener("load", function(){
    	BoxShadow.init();
    });
    
    var BoxShadow = (function BoxShadow() {
    
    	function getElemById(id) {
    		return document.getElementById(id);
    	}
    
    	/**
    	 * RGBA Color class
    	 */
    
    	function Color() {
    		this.r = 0;
    		this.g = 0;
    		this.b = 0;
    		this.a = 1;
    		this.hue = 0;
    		this.saturation = 0;
    		this.value = 0;
    	}
    
    	Color.prototype.copy = function copy(obj) {
    		if(obj instanceof Color !== true) {
    			console.log("Typeof instance not Color");
    			return;
    		}
    
    		this.r = obj.r;
    		this.g = obj.g;
    		this.b = obj.b;
    		this.a = obj.a;
    		this.hue = obj.hue;
    		this.saturation = obj.saturation;
    		this.value = obj.value;
    	}
    
    	Color.prototype.setRGBA = function setRGBA(red, green, blue, alpha) {
    		if (red != undefined)
    			this.r = red | 0;
    		if (green != undefined)
    			this.g = green | 0;
    		if (blue != undefined)
    			this.b = blue | 0;
    		if (alpha != undefined)
    			this.a = alpha | 0;
    	}
    
    	/**
    	 * HSV/HSB (hue, saturation, value / brightness)
    	 * @param hue			0-360
    	 * @param saturation	0-100
    	 * @param value 		0-100
    	 */
    	Color.prototype.setHSV = function setHSV(hue, saturation, value) {
    		this.hue = hue;
    		this.saturation = saturation;
    		this.value = value;
    		this.updateRGB();
    	}
    
    	Color.prototype.updateRGB = function updateRGB() {
    		var sat = this.saturation / 100;
    		var value = this.value / 100;
    		var C = sat * value;
    		var H = this.hue / 60;
    		var X = C * (1 - Math.abs(H % 2 - 1));
    		var m = value - C;
    		var precision = 255;
    
    		C = (C + m) * precision;
    		X = (X + m) * precision;
    		m = m * precision;
    
    		if (H >= 0 && H < 1) {	this.setRGBA(C, X, m);	return; }
    		if (H >= 1 && H < 2) {	this.setRGBA(X, C, m);	return; }
    		if (H >= 2 && H < 3) {	this.setRGBA(m, C, X);	return; }
    		if (H >= 3 && H < 4) {	this.setRGBA(m, X, C);	return; }
    		if (H >= 4 && H < 5) {	this.setRGBA(X, m, C);	return; }
    		if (H >= 5 && H < 6) {	this.setRGBA(C, m, X);	return; }
    	}
    
    	Color.prototype.updateHSV = function updateHSV() {
    		var red		= this.r / 255;
    		var green	= this.g / 255;
    		var blue	= this.b / 255;
    
    		var cmax = Math.max(red, green, blue);
    		var cmin = Math.min(red, green, blue);
    		var delta = cmax - cmin;
    		var hue = 0;
    		var saturation = 0;
    
    		if (delta) {
    			if (cmax === red ) { hue = ((green - blue) / delta); }
    			if (cmax === green ) { hue = 2 + (blue - red) / delta; }
    			if (cmax === blue ) { hue = 4 + (red - green) / delta; }
    			if (cmax) saturation = delta / cmax;
    		}
    
    		this.hue = 60 * hue | 0;
    		if (this.hue < 0) this.hue += 360;
    		this.saturation = (saturation * 100) | 0;
    		this.value = (cmax * 100) | 0;
    	}
    
    	Color.prototype.setHexa = function setHexa(value) {
    		var valid  = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)/i.test(value)
    		if (valid !== true)
    			return;
    
    		if (value[0] === '#')
    			value = value.slice(1, value.length);
    
    		if (value.length === 3)
    			value = value.replace(/([0-9A-F])([0-9A-F])([0-9A-F])/i,"$1$1$2$2$3$3");
    
    		this.r = parseInt(value.substr(0, 2), 16);
    		this.g = parseInt(value.substr(2, 2), 16);
    		this.b = parseInt(value.substr(4, 2), 16);
    
    		this.alpha	= 1;
    	}
    
    	Color.prototype.getHexa = function getHexa() {
    		var r = this.r.toString(16);
    		var g = this.g.toString(16);
    		var b = this.b.toString(16);
    		if (this.r < 16) r = '0' + r;
    		if (this.g < 16) g = '0' + g;
    		if (this.b < 16) b = '0' + b;
    		var value = '#' + r + g + b;
    		return value.toUpperCase();
    	}
    
    	Color.prototype.getRGBA = function getRGBA() {
    
    		var rgb = "(" + this.r + ", " + this.g + ", " + this.b;
    		var a = '';
    		var v = '';
    		if (this.a !== 1) {
    			a = 'a';
    			v = ', ' + this.a;
    		}
    
    		var value = "rgb" + a + rgb + v + ")";
    		return value;
    	}
    
    	Color.prototype.getColor = function getColor() {
    		if (this.a | 0 === 1)
    			return this.getHexa();
    		return this.getRGBA();
    	}
    
    	/**
    	 * Shadow Object
    	 */
    	function Shadow() {
    		this.inset  = false;
    		this.posX   = 5;
    		this.posY   = -5;
    		this.blur   = 5;
    		this.spread = 0;
    		this.color  = new Color();
    
    		var hue			= (Math.random() * 360) | 0;
    		var saturation	= (Math.random() * 75) | 0;
    		var value 		= (Math.random() * 50 + 50) | 0;
    		this.color.setHSV(hue, saturation, value, 1);
    	}
    
    	Shadow.prototype.computeCSS = function computeCSS() {
    		var value = "";
    		if (this.inset === true)
    			value += "inset ";
    		value += this.posX + "px ";
    		value += this.posY + "px ";
    		value += this.blur + "px ";
    		value += this.spread + "px ";
    		value += this.color.getColor();
    
    		return value;
    	}
    
    	Shadow.prototype.toggleInset = function toggleInset(value) {
    		if (value !== undefined || typeof value === "boolean")
    			this.inset = value;
    		else
    			this.inset = this.inset === true ? false : true;
    	}
    
    	Shadow.prototype.copy = function copy(obj) {
    		if(obj instanceof Shadow !== true) {
    			console.log("Typeof instance not Shadow");
    			return;
    		}
    
    		this.inset  = obj.inset;
    		this.posX   = obj.posX;
    		this.posY   = obj.posY;
    		this.blur   = obj.blur;
    		this.spread = obj.spread;
    		this.color.copy(obj.color);
    	}
    
    	/**
    	 * Color Picker
    	 */
    	var ColoPicker = (function ColoPicker() {
    
    		var colorpicker;
    		var hue_area;
    		var gradient_area;
    		var alpha_area;
    		var gradient_picker;
    		var hue_selector;
    		var alpha_selector;
    		var pick_object;
    		var info_rgb;
    		var info_hsv;
    		var info_hexa;
    		var output_color;
    		var color = new Color();
    		var subscribers = [];
    
    		var updateColor = function updateColor(e) {
    			var x = e.pageX - gradient_area.offsetLeft;
    			var y = e.pageY - gradient_area.offsetTop;
    
    			// width and height should be the same
    			var size = gradient_area.clientWidth;
    
    			if (x > size)
    				x = size;
    			if (y > size)
    				y = size;
    
    			if (x < 0) x = 0;
    			if (y < 0) y = 0;
    
    			var value = 100 - (y * 100 / size) | 0;
    			var saturation = x * 100 / size | 0;
    
    			color.setHSV(color.hue, saturation, value);
    			// should update just
    			// color pointer location
    			updateUI();
    			notify("color", color);
    		}
    
    		var updateHue = function updateHue(e) {
    			var x = e.pageX - hue_area.offsetLeft;
    			var width = hue_area.clientWidth;
    
    			if (x < 0) x = 0;
    			if (x > width) x = width;
    
    			var hue = ((360 * x) / width) | 0;
    			if (hue === 360) hue = 359;
    
    			color.setHSV(hue, color.saturation, color.value);
    
    			// should update just
    			// hue pointer location
    			// picker area background
    			// alpha area background
    			updateUI();
    			notify("color", color);
    		}
    
    		var updateAlpha = function updateAlpha(e) {
    			var x = e.pageX - alpha_area.offsetLeft;
    			var width = alpha_area.clientWidth;
    
    			if (x < 0) x = 0;
    			if (x > width) x = width;
    
    			color.a = (x / width).toFixed(2);
    
    			// should update just
    			// alpha pointer location
    			updateUI();
    			notify("color", color);
    		}
    
    		var setHueGfx = function setHueGfx(hue) {
    			var sat = color.saturation;
    			var val = color.value;
    			var alpha = color.a;
    
    			color.setHSV(hue, 100, 100);
    			gradient_area.style.backgroundColor = color.getHexa();
    
    			color.a = 0;
    			var start = color.getRGBA();
    			color.a = 1;
    			var end = color.getRGBA();
    			color.a = alpha;
    
    			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
    			alpha_area.style.background = gradient;
    		}
    
    		var updateUI = function updateUI() {
    			var x, y;		// coordinates
    			var size;		// size of the area
    			var offset;		// pointer graphic selector offset
    
    			// Set color pointer location
    			size = gradient_area.clientWidth;
    			offset = gradient_picker.clientWidth / 2 + 2;
    
    			x = (color.saturation * size / 100) | 0;
    			y = size - (color.value * size / 100) | 0;
    
    			gradient_picker.style.left = x - offset + "px";
    			gradient_picker.style.top = y - offset + "px";
    
    			// Set hue pointer location
    			size = hue_area.clientWidth;
    			offset = hue_selector.clientWidth/2;
    			x = (color.hue * size / 360 ) | 0;
    			hue_selector.style.left = x - offset + "px";
    
    			// Set alpha pointer location
    			size = alpha_area.clientWidth;
    			offset = alpha_selector.clientWidth/2;
    			x = (color.a * size) | 0;
    			alpha_selector.style.left = x - offset + "px";
    
    			// Set picker area background
    			var nc = new Color();
    			nc.copy(color);
    			if (nc.hue === 360) nc.hue = 0;
    			nc.setHSV(nc.hue, 100, 100);
    			gradient_area.style.backgroundColor = nc.getHexa();
    
    			// Set alpha area background
    			nc.copy(color);
    			nc.a = 0;
    			var start = nc.getRGBA();
    			nc.a = 1;
    			var end = nc.getRGBA();
    			var gradient = '-moz-linear-gradient(left, ' +	start + '0%, ' + end + ' 100%)';
    			alpha_area.style.background = gradient;
    
    			// Update color info
    			notify("color", color);
    			notify("hue", color.hue);
    			notify("saturation", color.saturation);
    			notify("value", color.value);
    			notify("r", color.r);
    			notify("g", color.g);
    			notify("b", color.b);
    			notify("a", color.a);
    			notify("hexa", color.getHexa());
    			output_color.style.backgroundColor = color.getRGBA();
    		}
    
    		var setInputComponent = function setInputComponent(node) {
    			var topic = node.getAttribute('data-topic');
    			var title = node.getAttribute('data-title');
    			var action = node.getAttribute('data-action');
    			title = title === null ? '' : title;
    
    			var input = document.createElement('input');
    			var info = document.createElement('span');
    			info.textContent = title;
    
    			input.setAttribute('type', 'text');
    			input.setAttribute('data-action', 'set-' + action + '-' + topic);
    			node.appendChild(info);
    			node.appendChild(input);
    
    			input.addEventListener('click', function(e) {
    				this.select();
    			});
    
    			input.addEventListener('change', function(e) {
    				if (action === 'HSV')
    					inputChangeHSV(topic);
    				if (action === 'RGB')
    					inputChangeRGB(topic);
    				if (action === 'alpha')
    					inputChangeAlpha(topic);
    				if (action === 'hexa')
    					inputChangeHexa(topic);
    			});
    
    			subscribe(topic, function(value) {
    				node.children[1].value = value;
    			});
    		}
    
    		var inputChangeHSV = function actionHSV(topic) {
    			var selector = "[data-action='set-HSV-" + topic + "']";
    			var node = document.querySelector("#colorpicker " + selector);
    			var value = parseInt(node.value);
    
    			if (typeof value === 'number' && isNaN(value) === false &&
    				value >= 0 && value < 360)
    				color[topic] = value;
    
    			color.updateRGB();
    			updateUI();
    		}
    
    		var inputChangeRGB = function inputChangeRGB(topic) {
    			var selector = "[data-action='set-RGB-" + topic + "']";
    			var node = document.querySelector("#colorpicker " + selector);
    			var value = parseInt(node.value);
    
    			if (typeof value === 'number' && isNaN(value) === false &&
    				value >= 0 && value <= 255)
    				color[topic] = value;
    
    			color.updateHSV();
    			updateUI();
    		}
    
    		var inputChangeAlpha = function inputChangeAlpha(topic) {
    			var selector = "[data-action='set-alpha-" + topic + "']";
    			var node = document.querySelector("#colorpicker " + selector);
    			var value = parseFloat(node.value);
    
    			if (typeof value === 'number' && isNaN(value) === false &&
    				value >= 0 && value <= 1)
    				color.a = value.toFixed(2);
    
    			updateUI();
    		}
    
    		var inputChangeHexa = function inputChangeHexa(topic) {
    			var selector = "[data-action='set-hexa-" + topic + "']";
    			var node = document.querySelector("#colorpicker " + selector);
    			var value = node.value;
    			color.setHexa(value);
    			color.updateHSV();
    			updateUI();
    		}
    
    		var setMouseTracking = function setMouseTracking(elem, callback) {
    
    			elem.addEventListener("mousedown", function(e) {
    				callback(e);
    				document.addEventListener("mousemove", callback);
    			});
    
    			document.addEventListener("mouseup", function(e) {
    				document.removeEventListener("mousemove", callback);
    			});
    		}
    
    		/*
    		 * Observer
    		 */
    		var setColor = function setColor(obj) {
    			if(obj instanceof Color !== true) {
    				console.log("Typeof instance not Color");
    				return;
    			}
    			color.copy(obj);
    			updateUI();
    		}
    
    		var subscribe = function subscribe(topic, callback) {
    			if (subscribers[topic] === undefined)
    				subscribers[topic] = [];
    
    			subscribers[topic].push(callback);
    		}
    
    		var unsubscribe = function unsubscribe(callback) {
    			subscribers.indexOf(callback);
    			subscribers.splice(index, 1);
    		}
    
    		var notify = function notify(topic, value) {
    			for (var i in subscribers[topic])
    				subscribers[topic][i](value);
    		}
    
    		var init = function init() {
    			colorpicker		= getElemById("colorpicker");
    			hue_area		= getElemById("hue");
    			gradient_area	= getElemById("gradient");
    			alpha_area		= getElemById("alpha");
    			gradient_picker	= getElemById("gradient_picker");
    			hue_selector	= getElemById("hue_selector");
    			alpha_selector	= getElemById("alpha_selector");
    			output_color	= getElemById("output_color");
    
    			var elem = document.querySelectorAll('#colorpicker .input');
    			var size = elem.length;
    			for (var i = 0; i < size; i++)
    				setInputComponent(elem[i]);
    
    			setMouseTracking(gradient_area, updateColor);
    			setMouseTracking(hue_area, updateHue);
    			setMouseTracking(alpha_area, updateAlpha);
    
    		}
    
    		return {
    			init : init,
    			setColor : setColor,
    			subscribe : subscribe,
    			unsubscribe : unsubscribe
    		}
    
    	})();
    
    	/**
    	 * Shadow dragging
    	 */
    	var PreviewMouseTracking = (function Drag() {
    		var active = false;
    		var lastX = 0;
    		var lastY = 0;
    		var subscribers = [];
    
    		var init = function init(id) {
    			var elem = getElemById(id);
    			elem.addEventListener('mousedown', dragStart, false);
    			document.addEventListener('mouseup', dragEnd, false);
    		}
    
    		var dragStart = function dragStart(e) {
    			if (e.button !== 0)
    				return;
    
    			active = true;
    			lastX = e.clientX;
    			lastY = e.clientY;
    			document.addEventListener('mousemove', mouseDrag, false);
    		}
    
    		var dragEnd = function dragEnd(e) {
    			if (e.button !== 0)
    				return;
    
    			if (active === true) {
    				active = false;
    				document.removeEventListener('mousemove', mouseDrag, false);
    			}
    		}
    
    		var mouseDrag = function mouseDrag(e) {
    			notify(e.clientX - lastX, e.clientY - lastY);
    			lastX = e.clientX;
    			lastY = e.clientY;
    		}
    
    		var subscribe = function subscribe(callback) {
    			subscribers.push(callback);
    		}
    
    		var unsubscribe = function unsubscribe(callback) {
    			var index = subscribers.indexOf(callback);
    			subscribers.splice(index, 1);
    		}
    
    		var notify = function notify(deltaX, deltaY) {
    			for (var i in subscribers)
    				subscribers[i](deltaX, deltaY);
    		}
    
    		return {
    			init : init,
    			subscribe : subscribe,
    			unsubscribe : unsubscribe
    		}
    
    	})();
    
    	/*
    	 * Element Class
    	 */
    	var CssClass = function CssClass(id) {
    		this.left = 0;
    		this.top = 0;
    		this.rotate = 0;
    		this.width = 300;
    		this.height = 100;
    		this.display = true;
    		this.border = true;
    		this.zIndex = -1;
    		this.bgcolor = new Color();
    		this.id = id;
    		this.node = getElemById('obj-' + id);
    		this.object = getElemById(id);
    		this.shadowID = null;
    		this.shadows = []
    		this.render = [];
    		this.init();
    	}
    
    	CssClass.prototype.init = function init() {
    		this.left = ((this.node.parentNode.clientWidth - this.node.clientWidth) / 2) | 0;
    		this.top = ((this.node.parentNode.clientHeight - this.node.clientHeight) / 2) | 0;
    
    		this.setTop(this.top);
    		this.setLeft(this.left);
    		this.setHeight(this.height);
    		this.setWidth(this.width);
    		this.bgcolor.setHSV(0, 0, 100);
    		this.updateBgColor(this.bgcolor);
    	}
    
    	CssClass.prototype.updatePos = function updatePos(deltaX, deltaY) {
    		this.left += deltaX;
    		this.top += deltaY;
    		this.node.style.top = this.top + "px";
    		this.node.style.left = this.left + "px";
    		SliderManager.setValue("left", this.left);
    		SliderManager.setValue("top", this.top);
    	}
    
    	CssClass.prototype.setLeft = function setLeft(value) {
    		this.left = value;
    		this.node.style.left = this.left + "px";
    		OutputManager.updateProperty(this.id, 'left', this.left + 'px');
    	}
    
    	CssClass.prototype.setTop = function setTop(value) {
    		this.top = value;
    		this.node.style.top = this.top + 'px';
    		OutputManager.updateProperty(this.id, 'top', this.top + 'px');
    	}
    
    	CssClass.prototype.setWidth = function setWidth(value) {
    		this.width = value;
    		this.node.style.width = this.width + 'px';
    		OutputManager.updateProperty(this.id, 'width', this.width + 'px');
    	}
    
    	CssClass.prototype.setHeight = function setHeight(value) {
    		this.height = value;
    		this.node.style.height = this.height + 'px';
    		OutputManager.updateProperty(this.id, 'height', this.height + 'px');
    	}
    
    	// Browser support
    	CssClass.prototype.setRotate = function setRotate(value) {
    		var cssvalue = 'rotate(' + value +'deg)';
    
    		this.node.style.transform = cssvalue;
    		this.node.style.webkitTransform = cssvalue;
    		this.node.style.msTransform = cssvalue;
    
    		if (value !== 0) {
    			if (this.rotate === 0) {
    				OutputManager.toggleProperty(this.id, 'transform', true);
    				OutputManager.toggleProperty(this.id, '-webkit-transform', true);
    				OutputManager.toggleProperty(this.id, '-ms-transform', true);
    			}
    		}
    		else {
    			OutputManager.toggleProperty(this.id, 'transform', false);
    			OutputManager.toggleProperty(this.id, '-webkit-transform', false);
    			OutputManager.toggleProperty(this.id, '-ms-transform', false);
    		}
    
    		OutputManager.updateProperty(this.id, 'transform', cssvalue);
    		OutputManager.updateProperty(this.id, '-webkit-transform', cssvalue);
    		OutputManager.updateProperty(this.id, '-ms-transform', cssvalue);
    		this.rotate = value;
    	}
    
    	CssClass.prototype.setzIndex = function setzIndex(value) {
    		this.node.style.zIndex = value;
    		OutputManager.updateProperty(this.id, 'z-index', value);
    		this.zIndex = value;
    	}
    
    	CssClass.prototype.toggleDisplay = function toggleDisplay(value) {
    		if (typeof value !== "boolean" || this.display === value)
    			return;
    
    		this.display = value;
    		var display = this.display === true ? "block" : "none";
    		this.node.style.display = display;
    		this.object.style.display = display;
    	}
    
    	CssClass.prototype.toggleBorder = function toggleBorder(value) {
    		if (typeof value !== "boolean" || this.border === value)
    			return;
    
    		this.border = value;
    		var border = this.border === true ? "1px solid #CCC" : "none";
    		this.node.style.border = border;
    	}
    
    	CssClass.prototype.updateBgColor = function updateBgColor(color) {
    		this.bgcolor.copy(color);
    		this.node.style.backgroundColor = color.getColor();
    		OutputManager.updateProperty(this.id, 'background-color', color.getColor());
    	}
    
    	CssClass.prototype.updateShadows = function updateShadows() {
    		if (this.render.length === 0)
    			OutputManager.toggleProperty(this.id, 'box-shadow', false);
    		if (this.render.length === 1)
    			OutputManager.toggleProperty(this.id, 'box-shadow', true);
    
    		this.node.style.boxShadow = this.render.join(", ");
    		OutputManager.updateProperty(this.id, 'box-shadow', this.render.join(", \n"));
    
    	}
    
    
    	/**
    	 * Tool Manager
    	 */
    	var Tool = (function Tool() {
    
    		var preview;
    		var classes = [];
    		var active = null;
    		var animate = false;
    
    		/*
    		 * Toll actions
    		 */
    		var addCssClass = function addCssClass(id) {
    			classes[id] = new CssClass(id);
    		}
    
    		var setActiveClass = function setActiveClass(id) {
    			active = classes[id];
    			active.shadowID = null;
    			ColoPicker.setColor(classes[id].bgcolor);
    			SliderManager.setValue("top", active.top);
    			SliderManager.setValue("left", active.left);
    			SliderManager.setValue("rotate", active.rotate);
    			SliderManager.setValue("z-index", active.zIndex);
    			SliderManager.setValue("width", active.width);
    			SliderManager.setValue("height", active.height);
    			ButtonManager.setValue("border-state", active.border);
    			active.updateShadows();
    		}
    
    		var disableClass = function disableClass(topic) {
    			classes[topic].toggleDisplay(false);
    			ButtonManager.setValue(topic, false);
    		}
    
    		var addShadow = function addShadow(position) {
    			if (animate === true)
    				return -1;
    
    			active.shadows.splice(position, 0, new Shadow());
    			active.render.splice(position, 0, null);
    		}
    
    		var swapShadow = function swapShadow(id1, id2) {
    			var x = active.shadows[id1];
    			active.shadows[id1] = active.shadows[id2];
    			active.shadows[id2] = x;
    			updateShadowCSS(id1);
    			updateShadowCSS(id2);
    		}
    
    		var deleteShadow = function deleteShadow(position) {
    			active.shadows.splice(position, 1);
    			active.render.splice(position, 1);
    			active.updateShadows();
    		}
    
    		var setActiveShadow = function setActiveShadow(id, glow) {
    			active.shadowID = id;
    			ColoPicker.setColor(active.shadows[id].color);
    			ButtonManager.setValue("inset", active.shadows[id].inset);
    			SliderManager.setValue("blur", active.shadows[id].blur);
    			SliderManager.setValue("spread", active.shadows[id].spread);
    			SliderManager.setValue("posX", active.shadows[id].posX);
    			SliderManager.setValue("posY", active.shadows[id].posY);
    			if (glow === true)
    				addGlowEffect(id);
    		}
    
    		var addGlowEffect = function addGlowEffect(id) {
    			if (animate === true)
    				return;
    
    			animate = true;
    			var store = new Shadow();
    			var shadow = active.shadows[id];
    
    			store.copy(shadow);
    			shadow.color.setRGBA(40, 125, 200, 1);
    			shadow.blur = 10;
    			shadow.spread = 10;
    
    			active.node.style.transition = "box-shadow 0.2s";
    			updateShadowCSS(id);
    
    			setTimeout(function() {
    				shadow.copy(store);
    				updateShadowCSS(id);
    				setTimeout(function() {
    					active.node.style.removeProperty("transition");
    					animate = false;
    				}, 100);
    			}, 200);
    		}
    
    		var updateActivePos = function updateActivePos(deltaX, deltaY) {
    			if (active.shadowID === null)
    				active.updatePos(deltaX, deltaY);
    			else
    				updateShadowPos(deltaX, deltaY);
    		}
    
    		/*
    		 * Shadow properties
    		 */
    		var updateShadowCSS = function updateShadowCSS(id) {
    			active.render[id] = active.shadows[id].computeCSS();
    			active.updateShadows();
    		}
    
    		var toggleShadowInset = function toggleShadowInset(value) {
    			if (active.shadowID === null)
    				return;
    			active.shadows[active.shadowID].toggleInset(value);
    			updateShadowCSS(active.shadowID);
    		}
    
    		var updateShadowPos = function updateShadowPos(deltaX, deltaY) {
    			var shadow = active.shadows[active.shadowID];
    			shadow.posX += deltaX;
    			shadow.posY += deltaY;
    			SliderManager.setValue("posX", shadow.posX);
    			SliderManager.setValue("posY", shadow.posY);
    			updateShadowCSS(active.shadowID);
    		}
    
    		var setShadowPosX = function setShadowPosX(value) {
    			if (active.shadowID === null)
    				return;
    			active.shadows[active.shadowID].posX = value;
    			updateShadowCSS(active.shadowID);
    		}
    
    		var setShadowPosY = function setShadowPosY(value) {
    			if (active.shadowID === null)
    				return;
    			active.shadows[active.shadowID].posY = value;
    			updateShadowCSS(active.shadowID);
    		}
    
    		var setShadowBlur = function setShadowBlur(value) {
    			if (active.shadowID === null)
    				return;
    			active.shadows[active.shadowID].blur = value;
    			updateShadowCSS(active.shadowID);
    		}
    
    		var setShadowSpread = function setShadowSpread(value) {
    			if (active.shadowID === null)
    				return;
    			active.shadows[active.shadowID].spread = value;
    			updateShadowCSS(active.shadowID);
    		}
    
    		var updateShadowColor = function updateShadowColor(color) {
    			active.shadows[active.shadowID].color.copy(color);
    			updateShadowCSS(active.shadowID);
    		}
    
    		/*
    		 * Element Properties
    		 */
    		var updateColor = function updateColor(color) {
    			if (active.shadowID === null)
    				active.updateBgColor(color);
    			else
    				updateShadowColor(color);
    		}
    
    		var init = function init() {
    			preview = getElemById("preview");
    
    			ColoPicker.subscribe("color", updateColor);
    			PreviewMouseTracking.subscribe(updateActivePos);
    
    			// Affects shadows
    			ButtonManager.subscribe("inset", toggleShadowInset);
    			SliderManager.subscribe("posX", setShadowPosX);
    			SliderManager.subscribe("posY", setShadowPosY);
    			SliderManager.subscribe("blur", setShadowBlur);
    			SliderManager.subscribe("spread", setShadowSpread);
    
    			// Affects element
    			SliderManager.subscribe("top", function(value){
    				active.setTop(value);
    			});
    			SliderManager.subscribe("left", function(value){
    				active.setLeft(value);
    			});
    			SliderManager.subscribe("rotate", function(value) {
    				if (active == classes["element"])
    					return;
    				active.setRotate(value);
    			});
    
    			SliderManager.subscribe("z-index", function(value) {
    				if (active == classes["element"])
    					return;
    				active.setzIndex(value);
    			});
    
    			SliderManager.subscribe("width", function(value) {
    				active.setWidth(value)
    			});
    
    			SliderManager.subscribe("height", function(value) {
    				active.setHeight(value)
    			});
    
    			// Actions
    			classes['before'].top = -30;
    			classes['before'].left = -30;
    			classes['after'].top = 30;
    			classes['after'].left = 30;
    			classes['before'].toggleDisplay(false);
    			classes['after'].toggleDisplay(false);
    			ButtonManager.setValue('before', false);
    			ButtonManager.setValue('after', false);
    
    			ButtonManager.subscribe("before", classes['before'].toggleDisplay.bind(classes['before']));
    			ButtonManager.subscribe("after", classes['after'].toggleDisplay.bind(classes['after']));
    
    			ButtonManager.subscribe("border-state", function(value) {
    				active.toggleBorder(value);
    			});
    
    		}
    
    		return {
    			init 			: init,
    			addShadow		: addShadow,
    			swapShadow		: swapShadow,
    			addCssClass		: addCssClass,
    			disableClass	: disableClass,
    			deleteShadow	: deleteShadow,
    			setActiveClass	: setActiveClass,
    			setActiveShadow : setActiveShadow
    		}
    
    	})();
    
    	/**
    	 * Layer Manager
    	 */
    	var LayerManager = (function LayerManager() {
    		var stacks = [];
    		var active = {
    			node : null,
    			stack : null
    		}
    		var elements = {};
    
    		var mouseEvents = function mouseEvents(e) {
    			var node = e.target;
    			var type = node.getAttribute('data-type');
    
    			if (type === 'subject')
    				setActiveStack(stacks[node.id]);
    
    			if (type === 'disable') {
    				Tool.disableClass(node.parentNode.id);
    				setActiveStack(stacks['element']);
    			}
    
    			if (type === 'add')
    				active.stack.addLayer();
    
    			if (type === 'layer')
    				active.stack.setActiveLayer(node);
    
    			if (type === 'delete')
    				active.stack.deleteLayer(node.parentNode);
    
    			if (type === 'move-up')
    				active.stack.moveLayer(1);
    
    			if (type === 'move-down')
    				active.stack.moveLayer(-1);
    		}
    
    		var setActiveStack = function setActiveStack(stackObj) {
    			active.stack.hide();
    			active.stack = stackObj;
    			active.stack.show();
    		}
    
    		/*
    		 * Stack object
    		 */
    		var Stack = function Stack(subject) {
    			var S = document.createElement('div');
    			var title = document.createElement('div');
    			var stack = document.createElement('div');
    
    			S.className = 'container';
    			stack.className = 'stack';
    			title.className = 'title';
    			title.textContent = subject.getAttribute('data-title');
    			S.appendChild(title);
    			S.appendChild(stack);
    
    			this.id = subject.id;
    			this.container = S;
    			this.stack = stack;
    			this.subject = subject;
    			this.order = [];
    			this.uid = 0;
    			this.count = 0;
    			this.layer = null;
    			this.layerID = 0;
    		}
    
    		Stack.prototype.addLayer = function addLayer() {
    			if (Tool.addShadow(this.layerID) == -1)
    				return;
    
    			var uid = this.getUID();
    			var layer = this.createLayer(uid);
    
    			if (this.layer === null && this.stack.children.length >= 1)
    				this.layer = this.stack.children[0];
    
    			this.stack.insertBefore(layer, this.layer);
    			this.order.splice(this.layerID, 0, uid);
    			this.count++;
    			this.setActiveLayer(layer);
    		}
    
    		Stack.prototype.createLayer = function createLayer(uid) {
    			var layer = document.createElement('div');
    			var del = document.createElement('span');
    
    			layer.className = 'node';
    			layer.setAttribute('data-shid', uid);
    			layer.setAttribute('data-type', 'layer');
    			layer.textContent = 'shadow ' + uid;
    
    			del.className = 'delete';
    			del.setAttribute('data-type', 'delete');
    
    			layer.appendChild(del);
    			return layer;
    		}
    
    		Stack.prototype.getUID = function getUID() {
    			return this.uid++;
    		}
    
    		// SOLVE IE BUG
    		Stack.prototype.moveLayer = function moveLayer(direction) {
    			if (this.count <= 1 || this.layer === null)
    				return;
    			if (direction === -1 && this.layerID === (this.count - 1) )
    				return;
    			if (direction === 1 && this.layerID === 0 )
    				return;
    
    			if (direction === -1) {
    				var before = null;
    				Tool.swapShadow(this.layerID, this.layerID + 1);
    				this.swapOrder(this.layerID, this.layerID + 1);
    				this.layerID += 1;
    
    				if (this.layerID + 1 !== this.count)
    					before = this.stack.children[this.layerID + 1];
    
    				this.stack.insertBefore(this.layer, before);
    				Tool.setActiveShadow(this.layerID, false);
    			}
    
    			if (direction === 1) {
    				Tool.swapShadow(this.layerID, this.layerID - 1);
    				this.swapOrder(this.layerID, this.layerID - 1);
    				this.layerID -= 1;
    				this.stack.insertBefore(this.layer, this.stack.children[this.layerID]);
    				Tool.setActiveShadow(this.layerID, false);
    			}
    		}
    
    		Stack.prototype.swapOrder = function swapOrder(pos1, pos2) {
    			var x = this.order[pos1];
    			this.order[pos1] = this.order[pos2];
    			this.order[pos2] = x;
    		}
    
    		Stack.prototype.deleteLayer = function deleteLayer(node) {
    			var shadowID =  node.getAttribute('data-shid') | 0;
    			var index = this.order.indexOf(shadowID);
    			this.stack.removeChild(this.stack.children[index]);
    			this.order.splice(index, 1);
    			this.count--;
    
    			Tool.deleteShadow(index);
    
    			if (index > this.layerID)
    				return;
    
    			if (index == this.layerID) {
    				if (this.count >= 1) {
    					this.layerID = 0;
    					this.setActiveLayer(this.stack.children[0], true);
    				}
    				else {
    					this.layer = null;
    					this.show();
    				}
    			}
    
    			if (index < this.layerID) {
    				this.layerID--;
    				Tool.setActiveShadow(this.layerID, true);
    			}
    
    		}
    
    		Stack.prototype.setActiveLayer = function setActiveLayer(node) {
    			elements.shadow_properties.style.display = 'block';
    			elements.element_properties.style.display = 'none';
    
    			if (this.layer)
    				this.layer.removeAttribute('data-active');
    
    			this.layer = node;
    			this.layer.setAttribute('data-active', 'layer');
    
    			var shadowID =  node.getAttribute('data-shid') | 0;
    			this.layerID = this.order.indexOf(shadowID);
    			Tool.setActiveShadow(this.layerID, true);
    		}
    
    		Stack.prototype.unsetActiveLayer = function unsetActiveLayer() {
    			if (this.layer)
    				this.layer.removeAttribute('data-active');
    
    			this.layer = null;
    			this.layerID = 0;
    		}
    
    		Stack.prototype.hide = function hide() {
    			this.unsetActiveLayer();
    			this.subject.removeAttribute('data-active');
    			var style = this.container.style;
    			style.left = '100%';
    			style.zIndex = '0';
    		}
    
    		Stack.prototype.show = function show() {
    			elements.shadow_properties.style.display = 'none';
    			elements.element_properties.style.display = 'block';
    
    			if (this.id === 'element') {
    				elements.zIndex.style.display = 'none';
    				elements.transform_rotate.style.display = 'none';
    			}
    			else {
    				elements.zIndex.style.display = 'block';
    				elements.transform_rotate.style.display = 'block';
    			}
    
    			this.subject.setAttribute('data-active', 'subject');
    			var style = this.container.style;
    			style.left = '0';
    			style.zIndex = '10';
    			Tool.setActiveClass(this.id);
    		}
    
    		function init() {
    
    			var elem, size;
    			var layerManager = getElemById("layer_manager");
    			var layerMenu = getElemById("layer_menu");
    			var container = getElemById("stack_container");
    
    			elements.shadow_properties = getElemById('shadow_properties');
    			elements.element_properties = getElemById('element_properties');
    			elements.transform_rotate = getElemById('transform_rotate');
    			elements.zIndex = getElemById('z-index');
    
    			elem = document.querySelectorAll('#layer_menu [data-type="subject"]');
    			size = elem.length;
    
    			for (var i = 0; i < size; i++) {
    				var S = new Stack(elem[i]);
    				stacks[elem[i].id] = S;
    				container.appendChild(S.container);
    				Tool.addCssClass(elem[i].id);
    			}
    
    			active.stack = stacks['element'];
    			stacks['element'].show();
    
    			layerManager.addEventListener("click", mouseEvents);
    			layerMenu.addEventListener("click", mouseEvents);
    
    			ButtonManager.subscribe("before", function(value) {
    				if (value === false && active.stack === stacks['before'])
    					setActiveStack(stacks['element'])
    				if (value === true && active.stack !== stacks['before'])
    					setActiveStack(stacks['before'])
    			});
    
    			ButtonManager.subscribe("after", function(value) {
    				if (value === false && active.stack === stacks['after'])
    					setActiveStack(stacks['element'])
    				if (value === true && active.stack !== stacks['after'])
    					setActiveStack(stacks['after'])
    			});
    		}
    
    		return {
    			init : init
    		}
    	})();
    
    	/*
    	 * OutputManager
    	 */
    	var OutputManager = (function OutputManager() {
    		var classes = [];
    		var buttons = [];
    		var active = null;
    		var menu = null;
    		var button_offset = 0;
    
    		var crateOutputNode = function(topic, property) {
    
    			var prop = document.createElement('div');
    			var name = document.createElement('span');
    			var value = document.createElement('span');
    
    			var pmatch = property.match(/(^([a-z0-9\-]*)=\[([a-z0-9\-\"]*)\])|^([a-z0-9\-]*)/i);
    
    			name.textContent = '\t' + pmatch[4];
    
    			if (pmatch[3] !== undefined) {
    				name.textContent = '\t' + pmatch[2];
    				value.textContent = pmatch[3] + ';';
    			}
    
    			name.textContent += ': ';
    			prop.className = 'css-property';
    			name.className = 'name';
    			value.className = 'value';
    			prop.appendChild(name);
    			prop.appendChild(value);
    
    			classes[topic].node.appendChild(prop);
    			classes[topic].line[property] = prop;
    			classes[topic].prop[property] = value;
    		}
    
    		var OutputClass = function OutputClass(node) {
    			var topic = node.getAttribute('data-topic');
    			var prop = node.getAttribute('data-prop');
    			var name = node.getAttribute('data-name');
    			var properties = prop.split(' ');
    
    			classes[topic] = {};
    			classes[topic].node = node;
    			classes[topic].prop = [];
    			classes[topic].line = [];
    			classes[topic].button = new Button(topic);
    
    			var open_decl = document.createElement('div');
    			var end_decl = document.createElement('div');
    
    			open_decl.textContent = name + ' {';
    			end_decl.textContent = '}';
    			node.appendChild(open_decl);
    
    			for (var i in properties)
    				crateOutputNode(topic, properties[i]);
    
    			node.appendChild(end_decl);
    		}
    
    		var Button = function Button(topic) {
    			var button = document.createElement('div');
    
    			button.className = 'button';
    			button.textContent = topic;
    			button.style.left = button_offset + 'px';
    			button_offset += 100;
    
    			button.addEventListener("click", function() {
    				toggleDisplay(topic);
    			})
    
    			menu.appendChild(button);
    			return button;
    		}
    
    		var toggleDisplay = function toggleDisplay(topic) {
    			active.button.removeAttribute('data-active');
    			active.node.style.display = 'none';
    			active = classes[topic];
    			active.node.style.display = 'block';
    			active.button.setAttribute('data-active', 'true');
    		}
    
    		var toggleButton = function toggleButton(topic, value) {
    			var display = (value === true) ? 'block' : 'none';
    			classes[topic].button.style.display = display;
    
    			if (value === true)
    				toggleDisplay(topic);
    			else
    				toggleDisplay('element');
    		}
    
    		var updateProperty = function updateProperty(topic, property, data) {
    			try {
    				classes[topic].prop[property].textContent = data + ';';
    			}
    			catch(error) {
    				// console.log("ERROR undefined : ", topic, property, data);
    			}
    		}
    
    		var toggleProperty = function toggleProperty(topic, property, value) {
    			var display = (value === true) ? 'block' : 'none';
    			try {
    				classes[topic].line[property].style.display = display;
    			}
    			catch(error) {
    				// console.log("ERROR undefined : ",classes, topic, property, value);
    			}
    		}
    
    		var init = function init() {
    
    			menu = getElemById('menu');
    
    			var elem = document.querySelectorAll('#output .output');
    			var size = elem.length;
    			for (var i = 0; i < size; i++)
    				OutputClass(elem[i]);
    
    			active = classes['element'];
    			toggleDisplay('element');
    
    			ButtonManager.subscribe("before", function(value) {
    				toggleButton('before', value);
    			});
    
    			ButtonManager.subscribe("after", function(value) {
    				toggleButton('after', value);
    			});
    		}
    
    		return {
    			init : init,
    			updateProperty : updateProperty,
    			toggleProperty : toggleProperty
    		}
    
    	})();
    
    
    	/**
    	 * Init Tool
    	 */
    	var init = function init() {
    		ButtonManager.init();
    		OutputManager.init();
    		ColoPicker.init();
    		SliderManager.init();
    		LayerManager.init();
    		PreviewMouseTracking.init("preview");
    		Tool.init();
    	}
    
    	return {
    		init : init
    	}
    
    })();
    
    
    

     

    Document Tags and Contributors

    Contributors to this page: groovecoder, Sheppy, teoli, gabriel_ivanica
    Last updated by: Sheppy,