Box-shadow generator - CSS: Cascading Style Sheets 编辑
box-shadow generator
This tool lets you construct CSS box-shadow
effects, to add box shadow effects to your CSS objects.
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=[""] 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=[""] 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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/add-black.png");
}
#layer_manager [data-type='add']:hover {
background-image: url("https://www.wenjiangs.com/wp-content/uploads/2020/mozilla/add-white.png");
}
#layer_manager [data-type='move-up'] {
background-image: url("https://www.wenjiangs.com/wp-content/uploads/2020/mozilla/up-black.png");
margin-left: 5%;
margin-right: 5%;
}
#layer_manager [data-type='move-up']:hover {
background-image: url("https://www.wenjiangs.com/wp-content/uploads/2020/mozilla/up-white.png");
}
#layer_manager [data-type='move-down'] {
background-image: url("https://www.wenjiangs.com/wp-content/uploads/2020/mozilla/down-black.png");
}
#layer_manager [data-type='move-down']:hover {
background-image: url("https://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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://www.wenjiangs.com/wp-content/uploads/2020/mozilla/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
}
})();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论