diff options
author | MDN <actions@users.noreply.github.com> | 2021-08-22 00:45:00 +0000 |
---|---|---|
committer | MDN <actions@users.noreply.github.com> | 2021-08-22 00:45:00 +0000 |
commit | 1e5ef69352fca974bc2c3b0c507b20c97189fd1e (patch) | |
tree | f3bbe11f8dfa81c42c20b1f14d6318007007eae9 /files/zh-cn/web/css/css_backgrounds_and_borders | |
parent | f01fdc6f036d12665d4a3707e1ba9af47a4a2310 (diff) | |
download | translated-content-1e5ef69352fca974bc2c3b0c507b20c97189fd1e.tar.gz translated-content-1e5ef69352fca974bc2c3b0c507b20c97189fd1e.tar.bz2 translated-content-1e5ef69352fca974bc2c3b0c507b20c97189fd1e.zip |
[CRON] sync translated content
Diffstat (limited to 'files/zh-cn/web/css/css_backgrounds_and_borders')
3 files changed, 7110 insertions, 0 deletions
diff --git a/files/zh-cn/web/css/css_backgrounds_and_borders/border-image_generator/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/border-image_generator/index.html new file mode 100644 index 0000000000..870e84f663 --- /dev/null +++ b/files/zh-cn/web/css/css_backgrounds_and_borders/border-image_generator/index.html @@ -0,0 +1,2629 @@ +--- +title: Border-image 生成器 +slug: Web/CSS/CSS_Backgrounds_and_Borders/Border-image_generator +tags: + - CSS + - Tools +translation_of: Web/CSS/CSS_Background_and_Borders/Border-image_generator +original_slug: Web/CSS/CSS_Background_and_Borders/Border-image_generator +--- +<p>这个工具用于生成 CSS3 {{cssxref("border-image")}} 的值.</p> + +<div class="hidden"> +<h2 id="Border_Image_Generator" name="Border_Image_Generator">Border Image Generator</h2> + +<h3 id="HTML_Content">HTML Content</h3> + +<pre class="brush: html"> <div id="container"> + + <div id="gallery"> + <div id="image-gallery"> + <img class="image" src="https://mdn.mozillademos.org/files/6007/border-image-1.png" data-stateID="border1"/> + <img class="image" src="https://mdn.mozillademos.org/files/6009/border-image-2.png" data-stateID="border2"/> + <img class="image" src="https://mdn.mozillademos.org/files/6011/border-image-3.png" data-stateID="border3"/> + <img class="image" src="https://mdn.mozillademos.org/files/6013/border-image-4.png" data-stateID="border4"/> + <img class="image" src="https://mdn.mozillademos.org/files/6015/border-image-5.png" data-stateID="border5"/> + <img class="image" src="https://mdn.mozillademos.org/files/6017/border-image-6.svg" data-stateID="border6"/> + </div> + </div> + + <div id="load-actions" class="group section"> + <div id="toggle-gallery" data-action="hide"> </div> + <div id="load-image" class="button"> Upload image </div> + <input id="remote-url" type="text" placeholder="Load an image from URL"/> + <div id="load-remote" class="button"> </div> + </div> + + <div id="general-controls" class="group section"> + <div class="name"> Control Box </div> + <div class="separator"></div> + <div class="property"> + <div class="name">scale</div> + <div class="ui-input-slider" data-topic="scale" + data-unit="%" data-max="300" data-sensivity="10"> + </div> + </div> + <div class="separator"></div> + <div class="property"> + <div class="name">draggable</div> + <div class="ui-checkbox" data-topic='drag-subject'></div> + </div> + <div class="property right"> + <div class="name">section height</div> + <div class="ui-input-slider" data-topic="preview-area-height" + data-min="400" data-max="1000"> + </div> + </div> + </div> + + <div id="preview_section" class="group section"> + <div id="subject"> + <div class="guideline" data-axis="Y" data-topic="slice-top"></div> + <div class="guideline" data-axis="X" data-topic="slice-right"></div> + <div class="guideline" data-axis="Y" data-topic="slice-bottom"></div> + <div class="guideline" data-axis="X" data-topic="slice-left"></div> + </div> + <div id="preview"> </div> + </div> + + <!-- controls --> + <div id="controls" class="group section"> + + <!-- border-image-slice --> + <div id="border-slice-control" class="category"> + <div class="title"> border-image-slice </div> + <div class="property"> + <div class="name">fill</div> + <div class="ui-checkbox" data-topic='slice-fill'></div> + </div> + </div> + + <!-- border-image-width --> + <div id="border-width-control" class="category"> + <div class="title"> border-image-width </div> + </div> + + <!-- border-image-outset --> + <div id="border-outset-control" class="category"> + <div class="title"> border-image-outset </div> + </div> + + <!-- other-settings --> + <div id="aditional-properties" class="category"> + <div class="title"> aditional-properties </div> + <div class="property"> + <div class="name"> repeat-x </div> + <div class="ui-dropdown border-repeat" data-topic="image-repeat-X" data-selected="2"> + <div data-value="0">repeat</div> + <div data-value="0">stretch</div> + <div data-value="0">round</div> + </div> + </div> + <div class="property"> + <div class="name"> repeat-y </div> + <div class="ui-dropdown border-repeat" data-topic="image-repeat-Y" data-selected="2"> + <div data-value="1">repeat</div> + <div data-value="1">stretch</div> + <div data-value="1">round</div> + </div> + </div> + <div class="property"> + <div class="ui-input-slider" data-topic="font-size" data-info="em size" + data-unit="px" data-value="12" data-sensivity="3"> + </div> + </div> + + <div class="property"> + <div class="ui-input-slider" data-topic="preview-width" data-info="width" + data-unit=" px" data-min="10" data-max="10000" data-sensivity="3"></div> + </div> + <div class="property"> + <div class="ui-input-slider" data-topic="preview-height" data-info="height" + data-unit=" px" data-min="10" data-max="10000" data-sensivity="3"> + </div> + </div> + </div> + + + <div id="output" class="category"> + <div class="title"> CSS Code </div> + <div class="css-property"> + <span class="name"> border-image-slice: </span> + <span id="out-border-slice" class="value"> </span> + </div> + <div class="css-property"> + <span class="name"> border-image-width: </span> + <span id="out-border-width" class="value"> </span> + </div> + <div class="css-property"> + <span class="name"> border-image-outset: </span> + <span id="out-border-outset" class="value"> </span> + </div> + <div class="css-property"> + <span class="name"> border-image-repeat: </span> + <span id="out-border-repeat" class="value"> </span> + </div> + <div class="css-property"> + <span class="name"> border-image-source: </span> + <span id="out-border-source" class="value"> </span> + </div> + </div> + + </div> + </div></pre> + +<h3 id="CSS_Content">CSS Content</h3> + +<pre class="brush: css">/* 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 Component + */ + +.ui-input-slider { + height: 20px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + -moz-user-select: none; + user-select: none; +} + +.ui-input-slider * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Input Slider */ + +.ui-input-slider > input { + margin: 0; + padding: 0; + width: 50px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-input-slider-info { + width: 90px; + padding: 0px 10px 0px 0px; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-left, .ui-input-slider-right { + width: 16px; + cursor: pointer; + background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center left no-repeat; +} + +.ui-input-slider-right { + background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center right no-repeat; +} + +.ui-input-slider-name { + width: 90px; + padding: 0 10px 0 0; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-btn-set { + width: 25px; + background-color: #2C9FC9; + border-radius: 5px; + color: #FFF; + font-weight: bold; + line-height: 14px; + text-align: center; +} + +.ui-input-slider-btn-set:hover { + background-color: #379B4A; + cursor: pointer; +} + +/*************************************************************************************/ +/*************************************************************************************/ + +/* + * UI DropDown + */ + +/* Dropdown */ + +.ui-dropdown { + height: 2em; + width: 120px; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + font-size: 12px; + + background-image: url("https://mdn.mozillademos.org/files/6037/drop_arrow_icon.png"); + background-position: right center; + background-repeat: no-repeat; + background-color: #359740; + + position: relative; + + -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; + user-select: none; +} + +.ui-dropdown:hover { + cursor: pointer; + background-color: #208B20; +} + +/* Dropdown Select Button */ + +.ui-dropdown-select { + height: inherit; + padding: 0 0.75em; + color: #FFF; + line-height: 2em; +} + +/* Dropdown List */ + +.ui-dropdown-list { + width: 100%; + height: 150px; + max-height: 150px; + margin: 0; + padding: 0 0.3em; + + border: 3px solid #3490D2; + border-color: #208B20; + background: #666; + background-color: #EEF1F5; + color: #000; + + position: absolute; + top: 2em; + left: 0; + z-index: 100; + + overflow: hidden; + transition: all 0.3s; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-dropdown-list:hover { + overflow: auto; +} + +.ui-dropdown-list[data-hidden='true'] { + height: 0 !important; + opacity: 0; + visibility: hidden; +} + +.ui-dropdown[data-position='left'] .ui-dropdown-list { + left: -100%; + top: 0; +} + +.ui-dropdown[data-position='right'] .ui-dropdown-list { + left: 100%; + top: 0; +} + +.ui-dropdown-list > div { + width: 100%; + height: 1.6em; + margin: 0.3em 0; + padding: 0.3em; + line-height: 1em; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-dropdown-list > div:hover { + background: #3490D2; + color:#FFF; + border-radius: 2px; + cursor: pointer; +} + + +/*************************************************************************************/ +/*************************************************************************************/ + +/* + * 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: 2px; + 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; +} + +/*************************************************************************************/ +/*************************************************************************************/ + +/* + * BORDER IMAGE GENERATOR TOOL + */ + +body { + width: 100%; + margin: 0 auto; + padding: 0 0 20px 0; + + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + + /*background: url("https://mdn.mozillademos.org/files/6025/grain.png");*/ + border: 1px solid #EEE; + + -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; + user-select: none; +} + +body[data-move='X'] { + cursor: w-resize !important; +} + +body[data-move='Y'] { + cursor: s-resize !important; +} + +#container { + width: 100%; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +[data-draggable='true']:hover { + cursor: move; +} + +[data-draggable='true']:hover > * { + cursor: default; +} + + + +/******************************************************************************/ +/******************************************************************************/ + +/* + * Border Image Picker + */ + +#gallery { + box-shadow: 0 0 3px 0 #BABABA; +} + +#image-gallery { + width: 600px; + height: 100px; + margin: 0 auto; + transition: margin 0.4s; +} + +#image-gallery .image { + height: 80px; + float: left; + margin: 10px; + opacity: 0.5; + background-color: #FFF; + box-shadow: 0px 0px 3px 1px #BABABA; +} + +#image-gallery .image[selected="true"] { + box-shadow: 0px 0px 3px 1px #3BBA52; + opacity: 1; +} + +#image-gallery .image:hover { + cursor: pointer; + box-shadow: 0px 0px 3px 1px #30ACE5; + opacity: 1; +} + +#image-gallery[data-collapsed='true'] { + margin-top: -100px; +} + +/* Load Menu */ + +#load-actions { + margin: 10px 0; +} + +#toggle-gallery { + width: 30px; + height: 25px; + margin: 10px; + color: #FFF; + + background-image: url('https://mdn.mozillademos.org/files/6005/arrow-up-white.png'); + background-repeat: no-repeat; + background-position: top 4px center; + background-color: #888888 !important; + + border-radius: 2px; + float: left; +} + +#toggle-gallery:hover { + cursor: pointer; +} + +#toggle-gallery[data-action='show'] { + background-image: url('https://mdn.mozillademos.org/files/6001/arrow-down-white.png'); + background-color: #888888 !important; +} + +#toggle-gallery[data-action='hide'] { + background-image: url('https://mdn.mozillademos.org/files/6005/arrow-up-white.png'); +} + +.button { + width: 100px; + height: 25px; + margin: 10px; + color: #FFF; + text-align: center; + font-size: 12px; + line-height: 25px; + background-color: #379B4A; + border-radius: 2px; + float: left; +} + +.button:hover { + cursor: pointer; + background-color: #3380C4; +} + +#load-image { + float: left; +} + +#load-remote { + width: 30px; + background-image: url('https://mdn.mozillademos.org/files/6003/arrow-right-white.png'); + background-repeat: no-repeat; + background-position: center center; +} + +#remote-url { + width: 200px; + height: 23px; + margin: 10px; + padding: 0 5px; + border: 1px solid #379B4A; + border-radius: 2px; + float: left; + + transition: width 0.5s; +} + +#remote-url:focus { + box-shadow: 0px 0px 3px -1px #379B4A; /*#68ACE8; */ + border-color: rgba(55, 155, 74, 0.5); + width: 450px; +} + +/* + * Visible Area + */ + +#preview_section { + position: relative; + min-height: 400px; +} + +/* Image Control */ + +#subject { + width: 300px; + height: 300px; + background-repeat: no-repeat; + background-size: 100%; + background-color: #FFF; + border: 1px solid #CCC; + + position: absolute; + z-index: 10; + top: 15%; + left: 10%; + + box-shadow: 0 0 3px 0 #BABABA; + transition-property: width, height; + transition-duration: 0.1s; +} + +#subject .guideline { + background-color: rgba(255, 255, 255, 0.7); + border: 1px solid rgba(0, 0, 0, 0.3); + position: absolute; +} + +#subject .guideline:hover { + background-color: #F00; +} + +#subject .guideline[data-active] { + background-color: #F00; + z-index: 10; +} + +#subject .guideline[data-axis='X'] { + width: 1px; + height: 100%; + top: -1px; +} + +#subject .guideline[data-axis='Y'] { + width: 100%; + height: 1px; + left: -1px; +} + +#subject .guideline[data-axis='X']:hover { + cursor: w-resize; +} + +#subject .guideline[data-axis='Y']:hover { + cursor: s-resize; +} + + +#subject .relative { + position: relative; + font-size: 12px; +} + +#subject .tooltip, #subject .tooltip2 { + width: 40px; + height: 20px; + line-height: 20px; + font-size: 12px; + text-align: center; + + position: absolute; + opacity: 0.5; + transition: opacity 0.25s; +} + +#subject .tooltip { + background: #EEE; + border-radius: 2px; + border: 1px solid #CCC; +} + +#subject .tooltip2{ + color: #555; +} + +#subject [data-active] > * { + opacity: 1; +} + +#subject .tooltip[data-info='top'] { + top: -10px; + right: -50px; +} + +#subject .tooltip[data-info='right'] { + bottom: -30px; + right: -20px; +} + +#subject .tooltip[data-info='bottom'] { + top: -10px; + left: -50px; +} + +#subject .tooltip[data-info='left'] { + top: -30px; + right: -20px; +} + +#subject .tooltip2[data-info='top'] { + top: -10px; + left: -50px; +} + +#subject .tooltip2[data-info='right'] { + top: -30px; + right: -20px; +} + +#subject .tooltip2[data-info='bottom'] { + top: -10px; + right: -50px; +} + +#subject .tooltip2[data-info='left'] { + bottom: -30px; + right: -20px; +} + +/* Preview */ + +#preview { + width: 30%; + height: 50%; + background-color: #FFF; + text-align: center; + overflow: hidden; + position: absolute; + z-index: 10; + + left: 60%; + top: 15%; + + border-radius: 2px; + border-image-width: 20px; + border-image-repeat: round; + box-shadow: 0 0 3px 0 #BABABA; +} + +#preview .resize-handle { + width: 10px; + height: 10px; + background: url("https://mdn.mozillademos.org/files/6027/resize.png") center center no-repeat; + position: absolute; + bottom: 0; + right: 0; +} + +#preview .resize-handle:hover { + cursor: nw-resize; +} + + +/* + * General controls MENU + */ + +#general-controls { + padding: 10px 30px; + background-color: #FFF; + opacity: 0.95; + color: #888; + /*border-radius: 2px;*/ + box-shadow: 0 0 3px 0 #BABABA; +} + +#general-controls .property { + width: 130px; + float: left; +} + +#general-controls .name { + height: 20px; + margin: 0 10px 0 0; + line-height: 100%; + text-align: right; + float: left; +} + +#general-controls .right { + width: 200px; + float: right; +} + +#general-controls .ui-checkbox label { + height: 10px; +} + +#general-controls .separator { + height: 40px; + width: 1px; + margin: -10px 15px; + background-color: #EEE; + float: left; +} + +/* + * Controls + */ + +#controls { + color: #444; + margin: 10px 0 0 0; +} + +#controls .category { + height: 190px; + min-width: 260px; + margin: 10px; + padding: 10px; + border: 1px solid #CCC; + border-radius: 3px; + float: left; + + box-shadow: 0 0 3px 0 #BABABA; + transition: all 0.25s; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +@media (min-width: 880px) { + #controls .category { + width: 30%; + margin-left: 1.66%; + margin-right: 1.66%; + } +} + +@media (max-width: 879px) { + #controls .category { + width: 37%; + margin-left: 6.5%; + margin-right: 6.5%; + } +} + +#controls .category .title { + width: 100%; + height: 30px; + margin: 0 0 10px 0; + line-height: 25px; + + text-align: center; + color: #AAA; +} + +#controls .category:hover .title { + color: #777; +} + +#controls .category > .group { + border: 1px solid #CCC; + border-radius: 2px; +} + + +/* property */ + +#controls .property { + width: 250px; + height: 20px; + margin: 5px auto; +} + +#controls .property .ui-input-slider { + margin: 0; + float: left; +} + +#controls .property .ui-input-slider-info { + width: 60px; +} + +#controls .property .ui-input-slider-left { + transition: opacity 0.15s; + opacity: 0; +} + +#controls .property .ui-input-slider-right { + transition: opacity 0.15s; + opacity: 0; +} + +#controls .property .name { + width: 60px; + height: 20px; + padding: 0px 10px 0px 0px; + text-align: right; + line-height: 100%; + float: left; +} + +#controls .property .config { + width: 20px; + height: 20px; + float: left; + background: url("https://mdn.mozillademos.org/files/6021/config.png") center center no-repeat; + opacity: 0.5; +} + +#controls .property .config:hover { + cursor: pointer; + opacity: 1; +} + +#controls .ui-input-slider:hover .ui-input-slider-right { + opacity: 1; +} + +#controls .ui-input-slider:hover .ui-input-slider-left { + opacity: 1; +} + +#controls .property .ui-dropdown { + margin: 0 10px; + float: left; +} + + +#controls .property .ui-checkbox { + margin: 0 0 0 16px; + float: left; +} + +#controls .property .ui-checkbox label { + height: 0.85em; + width: 10px; +} + +/* dropdowns */ +#controls .ui-dropdown { + width: 50px; + height: 1.7em; + border-radius: 2px; +} + +#controls .ui-dropdown-select { + line-height: 1.6em; +} + +#controls .ui-dropdown-list { + top: 20px; +} + +#controls .ui-dropdown-list { + border-width: 1px; + text-align: center; +} + +#controls .ui-dropdown-list:hover { + overflow: hidden; +} + +#controls .border-repeat { + margin: 0 0 0 16px !important; + width: 80px; +} + +#controls .border-repeat .ui-dropdown-list { + height: 6.2em; + border-width: 1px; + text-align: center; +} + +/* border-image-slice */ + + +#border-slice-control .ui-dropdown-list { + height: 4.3em; +} + +/* border-image-width */ + +#border-width-control .ui-dropdown-list { + height: 6.2em; +} + +/* border-image-outset */ + +#border-outset-control .ui-dropdown-list { + height: 4.3em; +} + +#aditional-properties .property { + width: 200px; +} + +#aditional-properties .ui-input-slider > input { + width: 80px !important; +} + +/* unit settings panel */ + +#unit-settings { + padding: 10px; + position: absolute; + + background: #FFF; + + font-size: 12px; + border-radius: 3px; + border: 1px solid #CCC; + text-align: center; + color: #555; + + position: absolute; + z-index: 1000; + + box-shadow: 0 0 3px 0 #BABABA; + transition: all 0.25s; +} + +#unit-settings .title { + width: 100%; + margin: -5px auto 0; + + color: #666; + font-size: 14px; + font-weight: bold; + line-height: 25px; + border-bottom: 1px solid #E5E5E5; +} + +#unit-settings .ui-input-slider { + margin: 10px 0 0 0; +} + +#unit-settings .ui-input-slider-info { + width: 50px; + line-height: 1.5em; +} + +#unit-settings input { + font-size: 12px; + width: 40px !important; +} + +#unit-settings .close { + width: 16px; + height: 16px; + background: url('https://mdn.mozillademos.org/files/6019/close.png') no-repeat center center; + background-size: 75%; + + position: absolute; + top: 4px; + right: 4px; + opacity: 0.5; +} + +#unit-settings .close:hover { + cursor: pointer; + opacity: 1; +} + +#unit-settings[data-active='true'] { + opacity: 1; +} + +#unit-settings[data-active='false'] { + opacity: 0; + top: -100px !important; +} + +/* + * CSS Output Code + */ + +#output { + padding: 10px; + border: 2px dashed #888 !important; + box-shadow: none !important; + border-radius: 3px; + overflow: hidden; + + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; + user-select: text; +} + + +@media (min-width: 880px) { + #output { + width: 63.33% !important; + } +} + +@media (max-width: 879px) { + #output { + width: 87% !important; + } +} + + +#output .title { + width: 100%; + height: 30px; + margin: 0 0 10px 0; + line-height: 25px; + + text-align: center; + color: #AAA; +} + +#output .css-property { + width: 100%; + margin: 0; + color: #555; + font-size: 14px; + line-height: 18px; + float: left; +} + +#output .css-property .name { + width: 30%; + font-weight: bold; + text-align: right; + float: left; +} + +#output .css-property .value { + width: 65%; + padding: 0 2.5%; + word-break: break-all; + float: left; +} + +</pre> + +<h3 id="JavaScript_Content">JavaScript Content</h3> + +<pre class="brush: js">'use strict'; + +/** + * UI-SlidersManager + */ + +var InputSliderManager = (function InputSliderManager() { + + var subscribers = {}; + var sliders = []; + + var InputComponent = function InputComponent(obj) { + var input = document.createElement('input'); + input.setAttribute('type', 'text'); + input.style.width = 50 + obj.precision * 10 + 'px'; + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + var value = parseFloat(e.target.value); + + if (isNaN(value) === true) + setValue(obj.topic, obj.value); + else + setValue(obj.topic, value); + }); + + return input; + }; + + var SliderComponent = function SliderComponent(obj, sign) { + var slider = document.createElement('div'); + var startX = null; + var start_value = 0; + + slider.addEventListener("click", function(e) { + document.removeEventListener("mousemove", sliderMotion); + setValue(obj.topic, obj.value + obj.step * sign); + }); + + slider.addEventListener("mousedown", function(e) { + startX = e.clientX; + start_value = obj.value; + document.body.style.cursor = "e-resize"; + + document.addEventListener("mouseup", slideEnd); + document.addEventListener("mousemove", sliderMotion); + }); + + var slideEnd = function slideEnd(e) { + document.removeEventListener("mousemove", sliderMotion); + document.body.style.cursor = "auto"; + slider.style.cursor = "pointer"; + }; + + var sliderMotion = function sliderMotion(e) { + slider.style.cursor = "e-resize"; + var delta = (e.clientX - startX) / obj.sensivity | 0; + var value = delta * obj.step + start_value; + setValue(obj.topic, value); + }; + + return slider; + }; + + var InputSlider = function(node) { + var min = parseFloat(node.getAttribute('data-min')); + var max = parseFloat(node.getAttribute('data-max')); + var step = parseFloat(node.getAttribute('data-step')); + var value = parseFloat(node.getAttribute('data-value')); + var topic = node.getAttribute('data-topic'); + var unit = node.getAttribute('data-unit'); + var name = node.getAttribute('data-info'); + var sensivity = node.getAttribute('data-sensivity') | 0; + var precision = node.getAttribute('data-precision') | 0; + + this.min = isNaN(min) ? 0 : min; + this.max = isNaN(max) ? 100 : max; + this.precision = precision >= 0 ? precision : 0; + this.step = step < 0 || isNaN(step) ? 1 : step.toFixed(precision); + this.topic = topic; + this.node = node; + this.unit = unit === null ? '' : unit; + this.sensivity = sensivity > 0 ? sensivity : 5; + value = isNaN(value) ? this.min : value; + + var input = new InputComponent(this); + var slider_left = new SliderComponent(this, -1); + var slider_right = new SliderComponent(this, 1); + + slider_left.className = 'ui-input-slider-left'; + slider_right.className = 'ui-input-slider-right'; + + if (name) { + var info = document.createElement('span'); + info.className = 'ui-input-slider-info'; + info.textContent = name; + node.appendChild(info); + } + + node.appendChild(slider_left); + node.appendChild(input); + node.appendChild(slider_right); + + this.input = input; + sliders[topic] = this; + setValue(topic, value); + }; + + InputSlider.prototype.setInputValue = function setInputValue() { + this.input.value = this.value.toFixed(this.precision) + this.unit; + }; + + var setValue = function setValue(topic, value, send_notify) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = parseFloat(value.toFixed(slider.precision)); + + if (value > slider.max) value = slider.max; + if (value < slider.min) value = slider.min; + + slider.value = value; + slider.node.setAttribute('data-value', value); + + slider.setInputValue(); + + if (send_notify === false) + return; + + notify.call(slider); + }; + + var setMax = function setMax(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.max = value; + setValue(topic, slider.value); + }; + + var setMin = function setMin(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.min = value; + setValue(topic, slider.value); + }; + + var setUnit = function setUnit(topic, unit) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.unit = unit; + setValue(topic, slider.value); + }; + + var setStep = function setStep(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.step = parseFloat(value); + setValue(topic, slider.value); + }; + + var setPrecision = function setPrecision(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = value | 0; + slider.precision = value; + + var step = parseFloat(slider.step.toFixed(value)); + if (step === 0) + slider.step = 1 / Math.pow(10, value); + + setValue(topic, slider.value); + }; + + var setSensivity = function setSensivity(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + value = value | 0; + + slider.sensivity = value > 0 ? value : 5; + }; + + var getNode = function getNode(topic) { + return sliders[topic].node; + }; + + var getPrecision = function getPrecision(topic) { + return sliders[topic].precision; + }; + + var getStep = function getStep(topic) { + return sliders[topic].step; + }; + + 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.value); + }; + + var createSlider = function createSlider(topic, label) { + var slider = document.createElement('div'); + slider.className = 'ui-input-slider'; + slider.setAttribute('data-topic', topic); + + if (label !== undefined) + slider.setAttribute('data-info', label); + + new InputSlider(slider); + return slider; + }; + + var init = function init() { + var elem = document.querySelectorAll('.ui-input-slider'); + var size = elem.length; + for (var i = 0; i < size; i++) + new InputSlider(elem[i]); + }; + + return { + init : init, + setMax : setMax, + setMin : setMin, + setUnit : setUnit, + setStep : setStep, + getNode : getNode, + getStep : getStep, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe, + setPrecision : setPrecision, + setSensivity : setSensivity, + getPrecision : getPrecision, + createSlider : createSlider, + }; + +})(); + + +/** + * UI-DropDown Select + */ + +var DropDownManager = (function DropdownManager() { + + var subscribers = {}; + var dropdowns = []; + var active = null; + + var visbility = ["hidden", "visible"]; + + + var DropDown = function DropDown(node) { + var topic = node.getAttribute('data-topic'); + var label = node.getAttribute('data-label'); + var selected = node.getAttribute('data-selected') | 0; + + var select = document.createElement('div'); + var list = document.createElement('div'); + var uval = 0; + var option = null; + var option_value = null; + + list.className = 'ui-dropdown-list'; + select.className = 'ui-dropdown-select'; + + while (node.firstElementChild !== null) { + option = node.firstElementChild; + option_value = option.getAttribute('data-value'); + + if (option_value === null) + option.setAttribute('data-value', uval); + + list.appendChild(node.firstElementChild); + uval++; + } + + node.appendChild(select); + node.appendChild(list); + + select.onclick = this.toggle.bind(this); + list.onclick = this.updateValue.bind(this); + document.addEventListener('click', clickOut); + + this.state = 0; + this.time = 0; + this.dropmenu = list; + this.select = select; + this.toggle(false); + this.value = {}; + this.topic = topic; + + if (label) + select.textContent = label; + else + this.setNodeValue(list.children[selected]); + + dropdowns[topic] = this; + + }; + + DropDown.prototype.toggle = function toggle(state) { + if (typeof(state) === 'boolean') + this.state = state === false ? 0 : 1; + else + this.state = 1 ^ this.state; + + if (active !== this) { + if (active) + active.toggle(false); + active = this; + } + + if (this.state === 0) + this.dropmenu.setAttribute('data-hidden', 'true'); + else + this.dropmenu.removeAttribute('data-hidden'); + + }; + + var clickOut = function clickOut(e) { + if (active.state === 0 || + e.target === active.dropmenu || + e.target === active.select) + return; + + active.toggle(false); + }; + + DropDown.prototype.updateValue = function updateValue(e) { + + if (Date.now() - this.time < 500) + return; + + if (e.target.className !== "ui-dropdown-list") { + this.setNodeValue(e.target); + this.toggle(false); + } + + this.time = Date.now(); + }; + + DropDown.prototype.setNodeValue = function setNodeValue(node) { + this.value['name'] = node.textContent; + this.value['value'] = node.getAttribute('data-value'); + + this.select.textContent = node.textContent; + this.select.setAttribute('data-value', this.value['value']); + + notify.call(this); + }; + + var createDropDown = function createDropDown(topic, options) { + + var dropdown = document.createElement('div'); + dropdown.setAttribute('data-topic', topic); + dropdown.className = 'ui-dropdown'; + + for (var i in options) { + var x = document.createElement('div'); + x.setAttribute('data-value', i); + x.textContent = options[i]; + dropdown.appendChild(x); + } + + new DropDown(dropdown); + + return dropdown; + }; + + var setValue = function setValue(topic, index) { + if (dropdowns[topic] === undefined || + index >= dropdowns[topic].dropmenu.children.length) + return; + + dropdowns[topic].setNodeValue(dropdowns[topic].dropmenu.children[index]); + }; + + var subscribe = function subscribe(topic, callback) { + if (subscribers[topic] === undefined) + subscribers[topic] = []; + subscribers[topic].push(callback); + }; + + var unsubscribe = function unsubscribe(topic, callback) { + var index = 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-dropdown'); + size = elem.length; + for (var i = 0; i < size; i++) + new DropDown(elem[i]); + + }; + + return { + init : init, + setValue : setValue, + subscribe : subscribe, + unsubscribe : unsubscribe, + createDropDown : createDropDown + }; + +})(); + + +/** + * 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) { + var obj = buttons[topic]; + if (obj === undefined) + return; + + obj.checkbox.checked = value; + notify.call(obj); + }; + + 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() { + BorderImage.init(); +}); + +var BorderImage = (function BorderImage() { + + var getElemById = document.getElementById.bind(document); + + var subject; + var preview; + var guidelines = []; + var positions = ['top', 'right', 'bottom', 'left']; + + var makeDraggable = function makeDraggable(elem) { + + var offsetTop; + var offsetLeft; + + elem.setAttribute('data-draggable', 'true'); + + var dragStart = function dragStart(e) { + if (e.target.getAttribute('data-draggable') !== 'true' || + e.target !== elem || e.button !== 0) + return; + + offsetLeft = e.clientX - elem.offsetLeft; + offsetTop = e.clientY - elem.offsetTop; + + document.addEventListener('mousemove', mouseDrag); + document.addEventListener('mouseup', dragEnd); + }; + + var dragEnd = function dragEnd(e) { + if (e.button !== 0) + return; + + document.removeEventListener('mousemove', mouseDrag); + document.removeEventListener('mouseup', dragEnd); + }; + + var mouseDrag = function mouseDrag(e) { + + elem.style.left = e.clientX - offsetLeft + 'px'; + elem.style.top = e.clientY - offsetTop + 'px'; + }; + + elem.addEventListener('mousedown', dragStart, false); + }; + + var PreviewControl = function PreviewControl() { + + var dragging = false; + var valueX = null; + var valueY = null; + + var dragStart = function dragStart(e) { + if (e.button !== 0) + return; + + valueX = e.clientX - preview.clientWidth; + valueY = e.clientY - preview.clientHeight; + dragging = true; + + document.addEventListener('mousemove', mouseDrag); + }; + + var dragEnd = function dragEnd(e) { + if (e.button !== 0 || dragging === false) + return; + + document.removeEventListener('mousemove', mouseDrag); + dragging = false; + }; + + var mouseDrag = function mouseDrag(e) { + InputSliderManager.setValue('preview-width', e.clientX - valueX); + InputSliderManager.setValue('preview-height', e.clientY - valueY); + }; + + var init = function init() { + + makeDraggable(preview); + makeDraggable(subject); + + var handle = document.createElement('div'); + handle.className = 'resize-handle'; + + handle.addEventListener('mousedown', dragStart); + document.addEventListener('mouseup', dragEnd); + + preview.appendChild(handle); + + }; + + return { + init: init + }; + + }(); + + var ImageReader = (function ImageReader() { + + var fReader = new FileReader(); + var browse = document.createElement('input'); + + var loadImage = function loadImage(e) { + if (browse.files.length === 0) + return; + + var file = browse.files[0]; + + if (file.type.slice(0, 5) !== 'image') + return; + + fReader.readAsDataURL(file); + + return false; + }; + + fReader.onload = function(e) { + ImageControl.loadRemoteImage(e.target.result); + }; + + var load = function load() { + browse.click(); + }; + + browse.setAttribute('type', 'file'); + browse.style.display = 'none'; + browse.onchange = loadImage; + + return { + load: load + }; + + })(); + + var ImageControl = (function ImageControl() { + + var scale = 0.5; + var imgSource = new Image(); + var imgState = null; + var selected = null; + + + var topics = ['slice', 'width', 'outset']; + var properties = {}; + properties['border1'] = { + fill : false, + + slice_values : [27, 27, 27, 27], + width_values : [20, 20, 20, 20], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [1, 1], + size : [300, 200], + preview_area : 400 + }; + + properties['border2'] = { + fill : false, + + slice_values : [33, 33, 33, 33], + width_values : [1.5, 1.5, 1.5, 1.5], + outset_values : [0, 0, 0, 0], + + slice_units : [1, 1, 1, 1], + width_units : [2, 2, 2, 2], + outset_units : [0, 0, 0, 0], + + repeat : [2, 2], + size : [300, 200], + preview_area : 400 + }; + + properties['border3'] = { + fill : true, + + slice_values : [15, 15, 15, 15], + width_values : [10, 10, 10, 10], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [2, 2], + size : [300, 200], + preview_area : 400 + }; + + properties['border4'] = { + fill : false, + + slice_values : [13, 13, 13, 13], + width_values : [13, 13, 13, 13], + outset_values : [13, 13, 13, 13], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [0, 0], + size : [300, 200], + preview_area : 400 + }; + + properties['border5'] = { + fill : false, + + slice_values : [0, 12, 0, 12], + width_values : [0, 12, 0, 12], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [0, 0], + size : [300, 200], + preview_area : 400, + }; + + properties['border6'] = { + fill : false, + + slice_values : [42, 42, 42, 42], + width_values : [42, 42, 42, 42], + outset_values : [0, 0, 0, 0], + + slice_units : [0, 0, 0, 0], + width_units : [0, 0, 0, 0], + outset_units : [0, 0, 0, 0], + + repeat : [2, 2], + size : [350, 350], + preview_area : 500, + }; + + + var loadLocalImage = function loadLocalImage(source) { + var location = "images/" + source; + imgSource.src = location; + }; + + var loadRemoteImage = function loadRemoteImage(source) { + imgSource.src = source; + if (selected) + selected.removeAttribute('selected'); + Tool.setOutputCSS('source', 'url("' + source + '")'); + }; + + var pickImage = function pickImage(e) { + if (e.target.className === 'image') { + selected = e.target; + selected.setAttribute('selected', 'true'); + loadRemoteImage(e.target.src); + imgState = e.target.getAttribute('data-stateID'); + } + }; + + var loadImageState = function loadImageState(stateID) { + if (properties[stateID] === undefined) + return; + + var prop = properties[stateID]; + var topic; + var unit_array; + var value_array; + + for (var i in topics) { + for (var j=0; j<4; j++) { + topic = topics[i] + '-' + positions[j]; + unit_array = topics[i] + '_units'; + value_array = topics[i] + '_values'; + InputSliderManager.setValue(topic, prop[value_array][j]); + DropDownManager.setValue(topic, prop[unit_array][j]); + } + } + + ButtonManager.setValue('slice-fill', prop['fill']); + DropDownManager.setValue('image-repeat-X', prop['repeat'][0]); + DropDownManager.setValue('image-repeat-Y', prop['repeat'][1]); + InputSliderManager.setValue('preview-width', prop['size'][0]); + InputSliderManager.setValue('preview-height', prop['size'][1]); + InputSliderManager.setValue('preview-area-height', prop['preview_area']); + }; + + var update = function update() { + scale = Math.min(300, (30000 / this.width) | 0); + setScale(scale); + InputSliderManager.setValue('scale', scale, false); + + subject.style.backgroundImage = 'url("' + this.src + '")'; + preview.style.borderImageSource = 'url("' + this.src + '")'; + + guidelines['slice-top'].setMax(this.height); + guidelines['slice-right'].setMax(this.width); + guidelines['slice-bottom'].setMax(this.height); + guidelines['slice-left'].setMax(this.width); + + if (imgState) + loadImageState(imgState); + }; + + var setScale = function setScale(value) { + scale = value; + var w = imgSource.width * scale / 100 | 0; + var h = imgSource.height * scale / 100 | 0; + subject.style.width = w + 'px'; + subject.style.height = h + 'px'; + + for (var i = 0; i < positions.length; i++) + guidelines['slice-' + positions[i]].updateGuidelinePos(); + }; + + var getScale = function getScale() { + return scale/100; + }; + + var toggleGallery = function toggleGallery() { + var gallery = getElemById('image-gallery'); + var button = getElemById('toggle-gallery'); + var state = 1; + button.addEventListener('click', function() { + state = 1 ^ state; + if (state === 0) { + gallery.setAttribute('data-collapsed', 'true'); + button.setAttribute('data-action', 'show'); + } + else { + gallery.removeAttribute('data-collapsed'); + button.setAttribute('data-action', 'hide'); + } + }); + }; + + var init = function init() { + var gallery = getElemById('image-gallery'); + var browse = getElemById('load-image'); + var remote = getElemById('remote-url'); + var load_remote = getElemById('load-remote'); + + remote.addEventListener('change', function(){ + loadRemoteImage(this.value); + }); + + load_remote.addEventListener('click', function(){ + loadRemoteImage(remote.value); + }); + + browse.addEventListener('click', ImageReader.load); + gallery.addEventListener('click', pickImage); + imgSource.addEventListener('load', update); + + InputSliderManager.subscribe('scale', setScale); + InputSliderManager.setValue('scale', scale); + imgState = 'border1'; + loadRemoteImage('https://mdn.mozillademos.org/files/6007/border-image-1.png'); + toggleGallery(); + }; + + return { + init: init, + getScale : getScale, + loadRemoteImage: loadRemoteImage + }; + + })(); + + var GuideLine = function GuideLine(node) { + var topic = node.getAttribute('data-topic'); + var axis = node.getAttribute('data-axis'); + + this.node = node; + this.topic = topic; + this.axis = axis; + this.info = topic.split('-')[1]; + + this.position = 0; + this.value = 0; + this.unit = 0; + this.max = 0; + this.pos = positions.indexOf(this.info); + + guidelines[topic] = this; + + var relative_container = document.createElement('div'); + var tooltip = document.createElement('div'); + var tooltip2 = document.createElement('div'); + + tooltip.className = 'tooltip'; + tooltip.setAttribute('data-info', this.info); + + tooltip2.className = 'tooltip2'; + tooltip2.textContent = this.info; + tooltip2.setAttribute('data-info', this.info); + + this.tooltip = tooltip; + + relative_container.appendChild(tooltip); + relative_container.appendChild(tooltip2); + node.appendChild(relative_container); + + var startX = 0; + var startY = 0; + var start = 0; + + var startDrag = function startDrag(e) { + startX = e.clientX; + startY = e.clientY; + start = guidelines[topic].position; + document.body.setAttribute('data-move', axis); + relative_container.setAttribute('data-active', ''); + node.setAttribute('data-active', ''); + + document.addEventListener('mousemove', updateGuideline); + document.addEventListener('mouseup', endDrag); + }; + + var endDrag = function endDrag() { + document.body.removeAttribute('data-move'); + relative_container.removeAttribute('data-active'); + node.removeAttribute('data-active'); + + document.removeEventListener('mousemove', updateGuideline); + }; + + var updateGuideline = function updateGuideline(e) { + var value; + if (topic === 'slice-top') + value = e.clientY - startY + start; + + if (topic === 'slice-right') + value = startX - e.clientX + start; + + if (topic === 'slice-bottom') + value = startY - e.clientY + start; + + if (topic === 'slice-left') + value = e.clientX - startX + start; + + if (this.unit === 0) + InputSliderManager.setValue(topic, value * 1 / ImageControl.getScale() | 0); + else { + InputSliderManager.setValue(topic, (value * 100 / (this.max * ImageControl.getScale())) | 0); + } + + }.bind(this); + + node.addEventListener("mousedown", startDrag); + + InputSliderManager.subscribe(topic, this.setPosition.bind(this)); + InputSliderManager.setValue(topic, this.position); + }; + + + GuideLine.prototype.updateGuidelinePos = function updateGuidelinePos() { + if (this.unit === 0) + this.position = this.value * ImageControl.getScale() | 0; + else + this.position = this.value * this.max * ImageControl.getScale() / 100 | 0; + + this.node.style[this.info] = this.position + 'px'; + }; + + GuideLine.prototype.setPosition = function setPosition(value) { + this.value = value; + this.tooltip.textContent = value; + this.updateGuidelinePos(); + Tool.setBorderSlice(this.pos, value); + }; + + GuideLine.prototype.setMax = function setMax(max) { + this.max = max; + this.updateLimit(); + }; + + GuideLine.prototype.updateLimit = function updateLimit() { + if (this.unit === 1) + InputSliderManager.setMax(this.topic, 100); + else + InputSliderManager.setMax(this.topic, this.max); + }; + + GuideLine.prototype.setUnit = function setUnit(type) { + if (type === '%') this.unit = 1; + if (type === '') this.unit = 0; + this.updateLimit(); + }; + + /* + * Unit panel + */ + var UnitPanel = (function UnitPanel () { + + var panel; + var title; + var precision; + var step; + var unit_topic = null; // settings are made for this topic + var step_option = [1, 0.1, 0.01]; + + var updatePrecision = function updatePrecision(value) { + InputSliderManager.setPrecision('unit-step', value); + InputSliderManager.setStep('unit-step', step_option[value]); + InputSliderManager.setMin('unit-step', step_option[value]); + + if (unit_topic) + InputSliderManager.setPrecision(unit_topic, value); + }; + + var updateUnitSettings = function updateUnitSettings(value) { + if (unit_topic) + InputSliderManager.setStep(unit_topic, value); + }; + + var show = function show(e) { + var topic = e.target.getAttribute('data-topic'); + var precision = InputSliderManager.getPrecision(topic); + var step = InputSliderManager.getStep(topic); + + unit_topic = topic; + title.textContent = topic; + + panel.setAttribute('data-active', 'true'); + panel.style.top = e.target.offsetTop - 40 + 'px'; + panel.style.left = e.target.offsetLeft + 30 + 'px'; + + InputSliderManager.setValue('unit-precision', precision); + InputSliderManager.setValue('unit-step', step); + }; + + var init = function init() { + panel = document.createElement('div'); + title = document.createElement('div'); + var close = document.createElement('div'); + + step = InputSliderManager.createSlider('unit-step', 'step'); + precision = InputSliderManager.createSlider('unit-precision', 'precision'); + + InputSliderManager.setStep('unit-precision', 1); + InputSliderManager.setMax('unit-precision', 2); + InputSliderManager.setValue('unit-precision', 2); + InputSliderManager.setSensivity('unit-precision', 20); + + InputSliderManager.setValue('unit-step', 1); + InputSliderManager.setStep('unit-step', 0.01); + InputSliderManager.setPrecision('unit-step', 2); + + InputSliderManager.subscribe('unit-precision', updatePrecision); + InputSliderManager.subscribe('unit-step', updateUnitSettings); + + close.addEventListener('click', function () { + panel.setAttribute('data-active', 'false'); + }); + + title.textContent = 'Properties'; + title.className = 'title'; + close.className = 'close'; + panel.id = 'unit-settings'; + panel.setAttribute('data-active', 'false'); + panel.appendChild(title); + panel.appendChild(precision); + panel.appendChild(step); + panel.appendChild(close); + document.body.appendChild(panel); + }; + + return { + init : init, + show : show + }; + + })(); + + /** + * Tool Manager + */ + var Tool = (function Tool() { + var preview_area; + var dropdown_unit_options = [ + { '' : '--', '%' : '%'}, + { 'px' : 'px', '%' : '%', 'em' : 'em'}, + { 'px' : 'px', 'em' : 'em'}, + ]; + + var border_slice = []; + var border_width = []; + var border_outset = []; + + var border_slice_values = []; + var border_width_values = []; + var border_outset_values = []; + + var border_slice_units = ['', '', '', '']; + var border_width_units = ['px', 'px', 'px', 'px']; + var border_outset_units = ['px', 'px', 'px', 'px']; + + var border_fill = false; + var border_repeat = ['round', 'round']; + var CSS_code = { + 'source' : null, + 'slice' : null, + 'width' : null, + 'outset' : null, + 'repeat' : null + }; + + var setBorderSlice = function setBorderSlice(positionID, value) { + border_slice[positionID] = value + border_slice_units[positionID]; + updateBorderSlice(); + }; + + var updateBorderSlice = function updateBorderSlice() { + var value = border_slice.join(' '); + if (border_fill === true) + value += ' fill'; + + preview.style.borderImageSlice = value; + setOutputCSS('slice', value); + }; + + var setBorderFill = function setBorderFill(value) { + border_fill = value; + var bimgslice = border_slice.join(' ');; + if (value === true) + bimgslice += ' fill'; + + preview.style.borderImageSlice = bimgslice; + }; + + var updateBorderWidth = function updateBorderWidth() { + var value = border_width.join(' '); + preview.style.borderImageWidth = value; + setOutputCSS('width', value); + }; + + var updateBorderOutset = function updateBorderOutset() { + var value = border_outset.join(' '); + preview.style.borderImageOutset = border_outset.join(' '); + setOutputCSS('outset', value); + }; + + var setBorderRepeat = function setBorderRepeat(obj) { + border_repeat[obj.value] = obj.name; + var value = border_repeat.join(' '); + preview.style.borderImageRepeat = value; + setOutputCSS('repeat', value); + }; + + var setOutputCSS = function setOutputCSS(topic, value) { + CSS_code[topic].textContent = value + ';'; + }; + + var setPreviewFontSize = function setPreviewFontSize(value) { + preview.style.fontSize = value + 'px'; + }; + + var setPreviewWidth = function setPreviewWidth(value) { + preview.style.width = value + 'px'; + }; + + var setPreviewHeight = function setPreviewHeight(value) { + preview.style.height = value + 'px'; + }; + + var setPreviewAreaHeight = function setPreviewAreaHeight(value) { + preview_area.style.height = value + 'px'; + }; + + var updateDragOption = function updateDragOption(value) { + if (value === true) + subject.setAttribute('data-draggable', 'true'); + else + subject.removeAttribute('data-draggable'); + }; + + var createProperty = function createProperty(topic, labelID, optionsID) { + + var slider = InputSliderManager.createSlider(topic, positions[labelID]); + var dropdown = DropDownManager.createDropDown(topic, dropdown_unit_options[optionsID]); + + InputSliderManager.setSensivity(topic, 3); + InputSliderManager.setPrecision(topic, 1); + + var property = document.createElement('div'); + var config = document.createElement('div'); + + property.className = 'property'; + config.className = 'config'; + config.setAttribute('data-topic', topic); + config.addEventListener('click', UnitPanel.show); + + property.appendChild(slider); + property.appendChild(dropdown); + property.appendChild(config); + + return property; + }; + + var initBorderSliceControls = function initBorderSliceControls() { + var container = getElemById('border-slice-control'); + + var listenForChanges = function listenForChanges(topic, id) { + InputSliderManager.subscribe(topic, function(value) { + border_slice_values[id] = value; + border_slice[id] = value + border_slice_units[id]; + updateBorderSlice(); + }); + + DropDownManager.subscribe(topic, function(obj) { + guidelines[topic].setUnit(obj.value); + border_slice_units[id] = obj.value; + border_slice[id] = border_slice_values[id] + obj.value; + updateBorderSlice(); + }); + }; + + for (var i = 0; i < positions.length; i++) { + var topic = 'slice-' + positions[i]; + var property = createProperty(topic, i, 0); + listenForChanges(topic, i); + + container.appendChild(property); + } + + container.appendChild(container.children[1]); + + }; + + var initBorderWidthControls = function initBorderWidthControls() { + var container = getElemById('border-width-control'); + + var listenForChanges = function listenForChanges(topic, id) { + InputSliderManager.subscribe(topic, function(value) { + border_width_values[id] = value; + border_width[id] = value + border_width_units[id]; + updateBorderWidth(); + }); + + DropDownManager.subscribe(topic, function(obj) { + if (obj.value === '%') + InputSliderManager.setMax(topic, 100); + else + InputSliderManager.setMax(topic, 1000); + + border_width_units[id] = obj.value; + border_width[id] = border_width_values[id] + obj.value; + updateBorderWidth(); + }); + }; + + for (var i = 0; i < positions.length; i++) { + var topic = 'width-' + positions[i]; + var property = createProperty(topic, i, 1); + InputSliderManager.setMax(topic, 1000); + listenForChanges(topic, i); + + container.appendChild(property); + } + }; + + var initBorderOutsetControls = function initBorderOutsetControls() { + + var container = getElemById('border-outset-control'); + + var listenForChanges = function listenForChanges(topic, id) { + InputSliderManager.subscribe(topic, function(value) { + border_outset_values[id] = value; + border_outset[id] = value + border_outset_units[id]; + updateBorderOutset(); + }); + + DropDownManager.subscribe(topic, function(obj) { + border_outset_units[id] = obj.value; + border_outset[id] = border_outset_values[id] + obj.value; + updateBorderOutset(); + }); + }; + + for (var i = 0; i < positions.length; i++) { + var topic = 'outset-' + positions[i]; + var property = createProperty(topic, i, 2); + InputSliderManager.setMax(topic, 1000); + listenForChanges(topic, i); + + container.appendChild(property); + } + }; + + var init = function init() { + + var gallery = + subject = getElemById('subject'); + preview = getElemById("preview"); + preview_area = getElemById("preview_section"); + + + CSS_code['source'] = getElemById("out-border-source"); + CSS_code['slice'] = getElemById("out-border-slice"); + CSS_code['width'] = getElemById("out-border-width"); + CSS_code['outset'] = getElemById("out-border-outset"); + CSS_code['repeat'] = getElemById("out-border-repeat"); + + initBorderSliceControls(); + initBorderWidthControls(); + initBorderOutsetControls(); + + var elem = document.querySelectorAll('.guideline'); + var size = elem.length; + for (var i = 0; i < size; i++) + new GuideLine(elem[i]); + + PreviewControl.init(); + + ButtonManager.subscribe('slice-fill',setBorderFill); + ButtonManager.subscribe('drag-subject', updateDragOption); + ButtonManager.setValue('drag-subject', false); + + DropDownManager.subscribe('image-repeat-X', setBorderRepeat); + DropDownManager.subscribe('image-repeat-Y', setBorderRepeat); + + InputSliderManager.subscribe('preview-area-height', setPreviewAreaHeight); + InputSliderManager.subscribe('preview-width', setPreviewWidth); + InputSliderManager.subscribe('preview-height', setPreviewHeight); + InputSliderManager.subscribe('font-size', setPreviewFontSize); + InputSliderManager.setValue('preview-width', 300); + InputSliderManager.setValue('preview-height', 200); + }; + + return { + init: init, + setOutputCSS: setOutputCSS, + setBorderSlice: setBorderSlice + }; + + })(); + + /** + * Init Tool + */ + var init = function init() { + InputSliderManager.init(); + DropDownManager.init(); + ButtonManager.init(); + UnitPanel.init(); + Tool.init(); + ImageControl.init(); + }; + + return { + init : init + }; + +})(); + +</pre> +</div> + +<p>{{ EmbedLiveSample('Border_Image_Generator', '100%', '1270px') }}</p> + +<p> </p> diff --git a/files/zh-cn/web/css/css_backgrounds_and_borders/border-radius_generator/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/border-radius_generator/index.html new file mode 100644 index 0000000000..4781337bc3 --- /dev/null +++ b/files/zh-cn/web/css/css_backgrounds_and_borders/border-radius_generator/index.html @@ -0,0 +1,1600 @@ +--- +title: 圆角边框生成器 +slug: Web/CSS/CSS_Backgrounds_and_Borders/Border-radius_generator +translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +original_slug: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +--- +<p>使用<em>Border-radius generator</em>生成 CSS3 {{cssxref("border-radius")}} 样式</p> + +<div class="hidden"> +<h2 id="border-radius-generator" name="border-radius-generator">border-radius</h2> + +<h3 id="HTML_Content">HTML Content</h3> + +<pre class="brush: html"><div id="container"> + <div class="group section"> + <div id="preview" class="col span_12"> + <div id="subject"> + <div id="top-left" class="radius-container" + data-X="left" data-Y="top"> + </div> + <div id="top-right" class="radius-container" + data-X="right" data-Y="top"> + </div> + <div id="bottom-right" class="radius-container" + data-X="right" data-Y="bottom"> + </div> + <div id="bottom-left" class="radius-container" + data-X="left" data-Y="bottom"> + </div> + + <div id="radius-ui-sliders"> + <div id="tlr" class="ui-input-slider" data-topic="top-left" + data-unit=" px" data-sensivity="2"></div> + + <div id="tlw" class="ui-input-slider" data-topic="top-left-w" + data-unit=" px" data-sensivity="2"></div> + + <div id="tlh" class="ui-input-slider" data-topic="top-left-h" + data-unit=" px" data-sensivity="2"></div> + + <div id="trr" class="ui-input-slider" data-topic="top-right" + data-unit=" px" data-sensivity="2"></div> + + <div id="trw" class="ui-input-slider" data-topic="top-right-w" + data-unit=" px" data-sensivity="2"></div> + + <div id="trh" class="ui-input-slider" data-topic="top-right-h" + data-unit=" px" data-sensivity="2"></div> + + <div id="brr" class="ui-input-slider" data-topic="bottom-right" + data-unit=" px" data-sensivity="2"></div> + + <div id="brw" class="ui-input-slider" data-topic="bottom-right-w" + data-unit=" px" data-sensivity="2"></div> + + <div id="brh" class="ui-input-slider" data-topic="bottom-right-h" + data-unit=" px" data-sensivity="2"></div> + + <div id="blr" class="ui-input-slider" data-topic="bottom-left" + data-unit=" px" data-sensivity="2"></div> + + <div id="blw" class="ui-input-slider" data-topic="bottom-left-w" + data-unit=" px" data-sensivity="2"></div> + + <div id="blh" class="ui-input-slider" data-topic="bottom-left-h" + data-unit=" px" data-sensivity="2"></div> + </div> + </div> + </div> + </div> + <div id="controls" class="group section"> + + <div class="group section"> + <div id="dimensions"> + <div class="ui-input-slider" data-topic="width" data-info="width" + data-unit=" px" data-min="150" data-max="700" data-sensivity="1"></div> + + <div class="ui-input-slider" data-topic="height" data-info="height" + data-unit=" px" data-min="75" data-max="350" data-sensivity="1"></div> + </div> + + <div id="output"></div> + </div> + + <div class="group section"> + <div id="radius-lock"> + <div class="info"> rounded corner </div> + <div class="ui-checkbox" data-topic='top-left'></div> + <div class="ui-checkbox" data-topic='top-right'></div> + <div class="ui-checkbox" data-topic='bottom-right'></div> + <div class="ui-checkbox" data-topic='bottom-left'></div> + </div> + + <div id="unit-selection"> + <div class="info"> select border units </div> + </div> + </div> + + </div> +</div> +</pre> + +<h3 id="CSS_Content">CSS Content</h3> + +<pre class="brush: css">/* GRID OF TEN + * ========================================================================== */ + +.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 Component + */ + +.ui-input-slider-container { + height: 20px; + margin: 10px 0; + font-family: "Segoe UI", Arial, Helvetica, sans-serif; + -moz-user-select: none; + user-select: none; +} + +.ui-input-slider-container * { + float: left; + height: 100%; + line-height: 100%; +} + +/* Input Slider */ + +.ui-input-slider > input { + margin: 0; + padding: 0; + width: 50px; + text-align: center; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.ui-input-slider-info { + width: 90px; + padding: 0px 10px 0px 0px; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-left, .ui-input-slider-right { + width: 16px; + cursor: pointer; + background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center left no-repeat; +} + +.ui-input-slider-right { + background: url("https://mdn.mozillademos.org/files/5679/arrows.png") center right no-repeat; +} + +.ui-input-slider-name { + width: 90px; + padding: 0 10px 0 0; + text-align: right; + text-transform: lowercase; +} + +.ui-input-slider-btn-set { + width: 25px; + background-color: #2C9FC9; + border-radius: 5px; + color: #FFF; + font-weight: bold; + line-height: 14px; + text-align: center; +} + +.ui-input-slider-btn-set:hover { + background-color: #379B4A; + cursor: pointer; +} + +/* + * UI Component + */ + +/* 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; +} + +body { + max-width: 1000px; + margin: 0 auto; + + 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; + user-select: none; +} + +#container { + width: 100%; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +/******************************************************************************/ +/******************************************************************************/ +/* + * Preview Area + */ + +#preview { + height: 500px; + border: 1px solid #CCC; + border-radius: 3px; + text-align: center; + overflow: hidden; + position: relative; +} + +#preview .content { + width: 100%; + height: 100%; + display: block; +} + +#preview input { + color: #333; + border: 1px solid #CCC; + border-radius: 3px; +} + +#subject { + width: 400px; + height: 150px; + margin: 0 auto; + border: 3px solid #C60; + background: #FFF; + position: relative; +} + +.radius { + width: 50%; + height: 50%; + border: 1px solid #CCC; + display: none; + position: absolute; + z-index: 1; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.handle { + width: 16px; + height: 16px; + position: absolute; + z-index: 2; +} + +.handle-top-left { + top: -12px; + left: -12px; + cursor: se-resize; + background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top left no-repeat; +} + +.handle-top-right { + top: -12px; + right: -12px; + cursor: sw-resize; + background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") top right no-repeat; +} + +.handle-bottom-right { + bottom: -12px; + right: -12px; + cursor: nw-resize; + background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom right no-repeat; +} + +.handle-bottom-left { + bottom: -12px; + left: -12px; + cursor: ne-resize; + background: url("https://mdn.mozillademos.org/files/5677/resize-handle.png") bottom left no-repeat; +} + + +.radius-container { + position: absolute; + display : block; + z-index: 1; + + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + + +/* TOP LEFT */ +#top-left { + top: 0; + left: 0; +} + +#top-left .radius { + border-top-left-radius: 100%; + top: 0; + left: 0; +} + +/* TOP RIGHT */ +#top-right { + top: 0; + right: 0; +} + +#top-right .radius { + border-top-right-radius: 100%; + top: 0; + right: 0; +} + +/* BOTTOM RIGHT */ +#bottom-right { + bottom: 0; + right: 0; +} + +#bottom-right .radius { + border-bottom-right-radius: 100%; + bottom: 0; + right: 0; +} + +/* BOTTOM lEFT */ +#bottom-left { + bottom: 0; + left: 0; +} + +#bottom-left .radius { + border-bottom-left-radius: 100%; + bottom: 0; +} + +/* INPUT SLIDERS */ + +#preview .ui-input-slider { + margin: 10px; + position: absolute; + z-index: 10; +} + +#radius-ui-sliders { + width: 100%; + height: 100%; + min-height: 75px; + min-width: 150px; + padding: 20px 50px; + top: -20px; + left: -50px; + position: relative; +} + +#tlr { + top: -30px; + left: -50px; + display: none; +} + +#tlw { + top: -30px; + left: 30px; +} + +#tlh { + top: 20px; + left: -50px; +} + +#trr { + top: -30px; + right: -50px; + display: none; +} + +#trw { + top: -30px; + right: 30px; +} + +#trh { + top: 20px; + right: -50px; +} + +#brr { + bottom: -30px; + right: -50px; + display: none; +} + +#brw { + bottom: -30px; + right: 30px; +} + +#brh { + bottom: 20px; + right: -50px; +} + +#blr { + bottom: -30px; + left: -50px; + display: none; +} + +#blw { + bottom: -30px; + left: 30px; +} + +#blh { + bottom: 20px; + left: -50px; +} + +#preview .ui-input-slider-left, #preview .ui-input-slider-right { + visibility: hidden; +} + +#preview .ui-input-slider-container:hover .ui-input-slider-left { + visibility: visible; +} + +#preview .ui-input-slider-container:hover .ui-input-slider-right { + visibility: visible; +} + +/* + * + */ + +#unit-selection { + width: 200px; + height: 75px; + margin: 30px 30px 0 0; + padding: 30px; + border: 3px solid #555; + border-radius: 10px; + position: relative; + float: right; +} + +#unit-selection .info { + height: 20%; + width: 100%; + line-height: 20%; + font-size: 20px; + text-align: center; + position: relative; + top: 40%; +} + +#unit-selection .dropdown { + width: 50px; + height: 20px; + margin: 10px; + padding: 0; + border-radius: 3px; + position: absolute; + overflow: hidden; +} + +#unit-selection select { + width: 50px; + height: 20px; + marign: 0; + padding: 0 0 0 10px; + background: #555; + border: 1px solid #555; + border: none; + color: #FFF; + float: left; +} + +#unit-selection select option { + background: #FFF; + color: #333; +} + +#unit-selection select:hover { + cursor: pointer; +} + +#unit-selection .dropdown:before { + content: ""; + width: 18px; + height: 20px; + display: block; + background-color: #555; + background-image: url("https://mdn.mozillademos.org/files/5675/dropdown.png"); + background-position: center center; + background-repeat: no-repeat; + top: 0px; + right: 0px; + position: absolute; + z-index: 1; + pointer-events: none; +} + +#unit-selection .unit-top-left { + top: 0; + left: 0; + display: none; +} + +#unit-selection .unit-top-left-w { + top: -22px; + left: 30px; +} + +#unit-selection .unit-top-left-h { + top: 20px; + left: -37px; +} + +#unit-selection .unit-top-right { + top: 0; + right: 0; + display: none; +} + +#unit-selection .unit-top-right-w { + top: -22px; + right: 30px; +} + +#unit-selection .unit-top-right-h { + top: 20px; + right: -37px; +} + +#unit-selection .unit-bottom-right { + bottom: 0; + right: 0; + display: none; +} + +#unit-selection .unit-bottom-right-w { + bottom: -22px; + right: 30px; +} + +#unit-selection .unit-bottom-right-h { + bottom: 20px; + right: -37px; +} + +#unit-selection .unit-bottom-left { + bottom: 0; + left: 0; + display: none; +} + +#unit-selection .unit-bottom-left-w { + bottom: -22px; + left: 30px; +} + +#unit-selection .unit-bottom-left-h { + bottom: 20px; + left: -37px; +} + +/******************************************************************************/ +/******************************************************************************/ + + +#radius-lock { + width: 200px; + height: 75px; + margin: 30px 0 0 30px; + padding: 30px; + border: 3px solid #555; + border-radius: 10px; + position: relative; + float: left; +} + +#radius-lock .ui-checkbox { + color: #FFF; + position: absolute; +} + +#radius-lock .ui-checkbox > label { + height: 20px; + width: 34px; + padding: 0; +} + +#radius-lock .info { + height: 20%; + width: 100%; + line-height: 20%; + font-size: 20px; + text-align: center; + position: relative; + top: 40%; +} + +#radius-lock [data-topic="top-left"] { + top: 10px; + left: 10px; +} + +#radius-lock [data-topic="top-right"] { + top: 10px; + right: 10px; +} + +#radius-lock [data-topic="bottom-right"] { + bottom: 10px; + right: 10px; +} + +#radius-lock [data-topic="bottom-left"] { + bottom: 10px; + left: 10px; +} + +/** + * Controls + */ + +#dimensions { + width: 200px; + color: #444; + float:left; +} + +#dimensions input { + background: #555; + color: #FFF; + border: none; + border-radius: 3px; +} + +#output { + width: 500px; + padding: 10px 0; + margin: 10px 0; + color: #555; + text-align: center; + border: 1px dashed #999; + border-radius: 3px; + -moz-user-select: text; + -webkit-user-select: text; + -ms-user-select: text; + user-select: text; + + float: right; +} + + +</pre> + +<h3 id="JavaScript_Content">JavaScript Content</h3> + +<pre class="brush: js"><code class="language-js">'use strict'; + + +/** + * UI-InputSliderManager + */ + +var InputSliderManager = (function InputSliderManager() { + + var subscribers = {}; + var sliders = []; + + var InputComponent = function InputComponent(obj) { + var input = document.createElement('input'); + input.setAttribute('type', 'text'); + + input.addEventListener('click', function(e) { + this.select(); + }); + + input.addEventListener('change', function(e) { + var value = parseInt(e.target.value); + + if (isNaN(value) === true) + setValue(obj.topic, obj.value); + else + setValue(obj.topic, value); + }); + + subscribe(obj.topic, function(value) { + input.value = value + obj.unit; + }); + + return input; + } + + var SliderComponent = function SliderComponent(obj, sign) { + var slider = document.createElement('div'); + var startX = null; + var start_value = 0; + + slider.addEventListener("click", function(e) { + setValue(obj.topic, obj.value + obj.step * sign); + }); + + slider.addEventListener("mousedown", function(e) { + startX = e.clientX; + start_value = obj.value; + document.body.style.cursor = "e-resize"; + document.addEventListener("mousemove", sliderMotion); + }); + + document.addEventListener("mouseup", function(e) { + document.removeEventListener("mousemove", sliderMotion); + document.body.style.cursor = "auto"; + slider.style.cursor = "pointer"; + }); + + var sliderMotion = function sliderMotion(e) { + slider.style.cursor = "e-resize"; + var delta = (e.clientX - startX) / obj.sensivity | 0; + var value = delta * obj.step + start_value; + setValue(obj.topic, value); + } + + return slider; + } + + var InputSlider = 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 topic = node.getAttribute('data-topic'); + var unit = node.getAttribute('data-unit'); + var name = node.getAttribute('data-info'); + var sensivity = node.getAttribute('data-sensivity') | 0; + + this.min = min; + this.max = max > 0 ? max : 100; + this.step = step === 0 ? 1 : step; + this.topic = topic; + this.node = node; + this.unit = unit; + this.sensivity = sensivity > 0 ? sensivity : 5; + + var input = new InputComponent(this); + var slider_left = new SliderComponent(this, -1); + var slider_right = new SliderComponent(this, 1); + + slider_left.className = 'ui-input-slider-left'; + slider_right.className = 'ui-input-slider-right'; + + if (name) { + var info = document.createElement('span'); + info.className = 'ui-input-slider-info'; + info.textContent = name; + node.appendChild(info); + } + + node.appendChild(slider_left); + node.appendChild(input); + node.appendChild(slider_right); + node.className = 'ui-input-slider ui-input-slider-container'; + + this.input = input; + sliders[topic] = this; + setValue(topic, value); + } + + var setValue = function setValue(topic, value, send_notify) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + if (value > slider.max) value = slider.max; + if (value < slider.min) value = slider.min; + + slider.value = value; + slider.node.setAttribute('data-value', value); + + if (send_notify !== undefined && send_notify === false) { + slider.input.value = value + slider.unit; + return; + } + + notify.call(slider); + } + + var setMax = function setMax(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.max = value; + setValue(topic, slider.value); + } + + var setMin = function setMin(topic, value) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.min = value; + setValue(topic, slider.value); + } + + var setUnit = function setUnit(topic, unit) { + var slider = sliders[topic]; + if (slider === undefined) + return; + + slider.unit = unit; + setValue(topic, slider.value); + } + + var getNode = function getNode(topic) { + return sliders[topic].node; + } + + 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() { + for (var i in subscribers[this.topic]) { + subscribers[this.topic][i](this.value); + } + } + + var init = function init() { + var elem = document.querySelectorAll('.ui-input-slider'); + var size = elem.length; + for (var i = 0; i < size; i++) + new InputSlider(elem[i]); + } + + return { + init : init, + setMax : setMax, + setMin : setMin, + setUnit : setUnit, + getNode : getNode, + 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; + } + catch(error) { + console.log(error); + } + } + + 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() { + 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() { + BorderRadius.init(); +}); + +var BorderRadius = (function BorderRadius() { + + function getElemById(id) { + return document.getElementById(id); + } + + /** + * 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 + } + + })(); + + var subject; + var units = ['px', '%']; + var output = null; + + var UnitSelector = function UnitSelector(topic) { + + this.container = document.createElement("div"); + this.select = document.createElement("select"); + for (var i in units) { + var option = document.createElement("option"); + option.value = i; + option.textContent = units[i]; + this.select.appendChild(option); + } + + this.container.className = 'dropdown ' + 'unit-' + topic; + this.container.appendChild(this.select); + } + + UnitSelector.prototype.setValue = function setValue(value) { + this.salect.value = value; + } + + + var RadiusContainer = function RadiusContainer(node) { + var radius = document.createElement('div'); + var handle = document.createElement('div'); + var x = node.getAttribute('data-x'); + var y = node.getAttribute('data-y'); + var active = false; + + this.id = node.id; + this.node = node; + this.radius = radius; + this.handle = handle; + this.width = 100; + this.height = 50; + this.size = 0; + this.rounded = false; + + this.unitX = 0; + this.unitY = 0; + this.unitR = 0; + + this.maxW = 100; + this.maxH = 100; + this.maxR = 100; + + this.topic = y + '-' + x; + + var sliderW = InputSliderManager.getNode(this.topic + '-w'); + var sliderH = InputSliderManager.getNode(this.topic + '-h'); + var sliderR = InputSliderManager.getNode(this.topic); + + this.setUnitX(this.unitX); + this.setUnitY(this.unitY); + this.setUnitR(this.unitR); + + this.updateWidth(); + this.updateHeight(); + this.updateRadius(); + + if (x === 'left') this.resizeX = 1; + if (x === 'right') this.resizeX = -1; + if (y === 'top') this.resizeY = 1; + if (y === 'bottom') this.resizeY = -1; + + radius.className = 'radius'; + + var unit_selector = document.getElementById("unit-selection"); + var unitW = new UnitSelector(this.topic + '-w'); + var unitH = new UnitSelector(this.topic + '-h'); + var unitR = new UnitSelector(this.topic); + + unit_selector.appendChild(unitW.container); + unit_selector.appendChild(unitH.container); + unit_selector.appendChild(unitR.container); + node.appendChild(radius); + subject.appendChild(handle); + + unitW.select.addEventListener('change', function(e) { + this.setUnitX(e.target.value | 0); + }.bind(this)); + + unitH.select.addEventListener('change', function(e) { + this.setUnitY(e.target.value | 0); + }.bind(this)); + + unitR.select.addEventListener('change', function(e) { + this.setUnitR(e.target.value | 0); + }.bind(this)); + + if (x === 'left' && y == 'top') handle.className = 'handle handle-top-left' + if (x === 'right' && y == 'top') handle.className = 'handle handle-top-right'; + if (x === 'right' && y == 'bottom') handle.className = 'handle handle-bottom-right'; + if (x === 'left' && y == 'bottom') handle.className = 'handle handle-bottom-left'; + + handle.addEventListener("mousedown", function(e) { + active = true; + this.radius.style.display = 'block'; + PreviewMouseTracking.subscribe(this.updateContainer.bind(this)); + }.bind(this)); + + document.addEventListener("mouseup", function(e) { + this.radius.style.display = 'none'; + if (active === true) + PreviewMouseTracking.unsubscribe(this.updateContainer.bind(this)); + }.bind(this)); + + InputSliderManager.subscribe(this.topic + '-w', this.setWidth.bind(this)); + InputSliderManager.subscribe(this.topic + '-h', this.setHeight.bind(this)); + InputSliderManager.subscribe(this.topic, this.setRadius.bind(this)); + + ButtonManager.subscribe(this.topic, function(value) { + this.rounded = value; + if (value === true) { + unitW.container.style.display = 'none'; + unitH.container.style.display = 'none'; + unitR.container.style.display = 'block'; + sliderW.style.display = 'none'; + sliderH.style.display = 'none'; + sliderR.style.display = 'block'; + this.setUnitR(this.unitR); + this.updateRadius(); + } + + if (value === false) { + unitW.container.style.display = 'block'; + unitH.container.style.display = 'block'; + unitR.container.style.display = 'none'; + sliderW.style.display = 'block'; + sliderH.style.display = 'block'; + sliderR.style.display = 'none'; + this.setUnitX(this.unitX); + this.setUnitY(this.unitY); + this.updateWidth(); + this.updateHeight(); + } + + this.updateBorderRadius(); + + }.bind(this)); + + this.updateBorderRadius(); + } + + RadiusContainer.prototype.updateWidth = function updateWidth() { + this.node.style.width = this.width + units[this.unitX]; + var value = Math.round(this.width / 2); + InputSliderManager.setValue(this.topic + '-w', value, false); + } + + RadiusContainer.prototype.updateHeight = function updateHeight() { + this.node.style.height = this.height + units[this.unitY]; + var value = Math.round(this.height / 2); + InputSliderManager.setValue(this.topic + '-h', value, false); + } + + RadiusContainer.prototype.updateRadius = function updateRadius() { + var value = Math.round(this.size / 2); + this.node.style.width = this.size + units[this.unitR]; + this.node.style.height = this.size + units[this.unitR]; + InputSliderManager.setValue(this.topic, value, false); + } + + RadiusContainer.prototype.setWidth = function setWidth(value) { + this.radius.style.display = 'block'; + this.width = 2 * value; + this.node.style.width = this.width + units[this.unitX]; + this.updateBorderRadius(); + } + + RadiusContainer.prototype.setHeight = function setHeight(value) { + this.radius.style.display = 'block'; + this.height = 2 * value; + this.node.style.height = this.height + units[this.unitY]; + this.updateBorderRadius(); + } + + RadiusContainer.prototype.setRadius = function setRadius(value) { + this.radius.style.display = 'block'; + this.size = 2 * value; + this.node.style.width = this.size + units[this.unitR]; + this.node.style.height = this.size + units[this.unitR]; + this.updateBorderRadius(); + } + + RadiusContainer.prototype.setUnitX = function setUnitX(value) { + this.unitX = value; + if (this.unitX === 0) this.maxW = 2 * subject.clientWidth; + if (this.unitX === 1) this.maxW = 200; + InputSliderManager.setUnit(this.topic + '-w', units[this.unitX]); + InputSliderManager.setMax(this.topic + '-w', this.maxW / 2); + } + + RadiusContainer.prototype.setUnitY = function setUnitY(value) { + this.unitY = value; + if (this.unitY === 0) this.maxH = 2 * subject.clientHeight; + if (this.unitY === 1) this.maxH = 200; + InputSliderManager.setUnit(this.topic + '-h', units[this.unitY]); + InputSliderManager.setMax(this.topic + '-h', this.maxH / 2); + } + + RadiusContainer.prototype.setUnitR = function setUnitR(value) { + this.unitR = value; + + if (this.unitR === 0) + this.maxR = 2 * Math.min(subject.clientHeight , subject.clientWidth); + + if (this.unitR === 1) + this.maxR = 200; + + InputSliderManager.setUnit(this.topic, units[this.unitR]); + InputSliderManager.setMax(this.topic, this.maxR / 2); + } + + RadiusContainer.prototype.updateUnits = function updateUnits(unit) { + if (this.rounded) { + this.setUnitR(this.unitR); + return; + } + + if (unit === 0) + this.setUnitX(this.unitX); + + if (unit === 1) + this.setUnitY(this.unitY); + } + + RadiusContainer.prototype.composeBorderRadius = function composeBorderRadius () { + + if (this.rounded === true) { + var unit = units[this.unitR]; + var value = Math.round(this.size / 2); + return value + unit; + } + + var unitX = units[this.unitX]; + var unitY = units[this.unitY]; + var valueX = Math.round(this.width / 2); + var valueY = Math.round(this.height / 2); + + if (valueX === valueY && this.unitX === this.unitY) + return valueX + unitX; + + return valueX + unitX + ' ' + valueY + unitY; + } + + RadiusContainer.prototype.updateBorderRadius = function updateBorderRadius () { + var radius = this.composeBorderRadius(); + var corner = 0; + + if (this.topic === 'top-left') { + subject.style.borderTopLeftRadius = radius; + corner = 0; + } + + if (this.topic === 'top-right') { + subject.style.borderTopRightRadius = radius; + corner = 1; + } + + if (this.topic === 'bottom-right') { + subject.style.borderBottomRightRadius = radius; + corner = 2; + } + + if (this.topic === 'bottom-left') { + subject.style.borderBottomLeftRadius = radius; + corner = 3; + } + + Tool.updateOutput(corner, radius); + } + + RadiusContainer.prototype.updateContainer = function updateContainer(deltaX, deltaY) { + + if (this.rounded === true) { + this.size += this.resizeX * deltaX + this.resizeY * deltaY; + if (this.size < 0) this.size = 0; + if (this.size > this.maxR) this.size = this.maxR; + this.updateRadius(); + this.updateBorderRadius(); + return; + } + + if (deltaX) { + this.width += this.resizeX * deltaX; + if (this.width < 0) this.width = 0; + if (this.width > this.maxW) this.width = this.maxW; + this.updateWidth(); + } + + if (deltaY) { + this.height += this.resizeY * deltaY; + if (this.height < 0) this.height = 0; + if (this.height > this.maxH) this.height = this.maxH; + this.updateHeight(); + } + + if (deltaX || deltaY) + this.updateBorderRadius(); + } + + + /** + * Tool Manager + */ + var Tool = (function Tool() { + var preview; + var preview_ui; + var radius_containers = []; + var border_width = 3; + var borders1 = [null, null, null, null]; + var borders2 = [0, 0, 0, 0]; + + var updateUIWidth = function updateUIWidth(value) { + var pwidth = subject.parentElement.clientWidth; + var left = (pwidth - value) / 2; + subject.style.width = value + "px"; + + for (var i = 0; i < 4; i++) + radius_containers[i].updateUnits(0); + } + + var updateUIHeight = function updateUIHeight(value) { + var pheight = subject.parentElement.clientHeight; + var top = (pheight - value) / 2; + subject.style.height = value + "px"; + subject.style.top = top - border_width + "px"; + + for (var i = 0; i < 4; i++) + radius_containers[i].updateUnits(1); + } + + var updatePreviewUIWidth = function updatePreviewUIWidth() { + var p = subject.parentElement.clientWidth; + var v = preview_ui.clientWidth; + console.log(p, v, (p - v ) / 2); + preview_ui.style.left = (p - v) / 2 + "px" ; + } + + var updatePreviewUIHeight = function updatePreviewUIHeight() { + var p = subject.parentElement.clientHeight; + var v = preview_ui.clientHeight; + console.log(p, v, (p - v ) / 2); + preview_ui.style.top = (p - v) / 2 + "px" ; + } + + var updateOutput = function updateOutput(corner, radius) { + var values = radius.split(" "); + + borders1[corner] = values[0]; + borders2[corner] = values[0]; + + if (values.length === 2) + borders2[corner] = values[1]; + + var border_1_value = borders1.join(" "); + var border_2_value = borders2.join(" "); + var border_radius = 'border-radius: ' + border_1_value; + + if (border_2_value !== border_1_value) + border_radius += ' / ' + border_2_value; + + border_radius += ';'; + output.textContent = border_radius; + } + + var init = function init() { + preview = getElemById("preview"); + subject = getElemById("subject"); + output = getElemById("output"); + preview_ui = getElemById("radius-ui-sliders"); + + var elem = document.querySelectorAll('.radius-container'); + var size = elem.length; + for (var i = 0; i < size; i++) + radius_containers[i] = new RadiusContainer(elem[i]); + + InputSliderManager.subscribe("width", updateUIWidth); + InputSliderManager.subscribe("height", updateUIHeight); + + InputSliderManager.setValue("width", subject.clientWidth); + InputSliderManager.setValue("height", subject.clientHeight); + } + + return { + init : init, + updateOutput : updateOutput + } + + })(); + + /** + * Init Tool + */ + var init = function init() { + ButtonManager.init(); + InputSliderManager.init(); + PreviewMouseTracking.init("preview"); + Tool.init(); + } + + return { + init : init + } + +})(); + + +</code></pre> +</div> + +<p>{{ EmbedLiveSample('border-radius-generator', '100%', '800px', '') }}</p> + +<p> </p> diff --git a/files/zh-cn/web/css/css_backgrounds_and_borders/box-shadow_generator/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/box-shadow_generator/index.html new file mode 100644 index 0000000000..2847389264 --- /dev/null +++ b/files/zh-cn/web/css/css_backgrounds_and_borders/box-shadow_generator/index.html @@ -0,0 +1,2881 @@ +--- +title: Box-shadow generator +slug: Web/CSS/CSS_Backgrounds_and_Borders/Box-shadow_generator +translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +original_slug: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +--- +<p>这个可视化工具可以帮助你生成一个元素的CSS{{cssxref("box-shadow")}}相关代码,添加box shadow效果到你的CSS对象上。</p> + +<div class="hidden"> +<h2 id="box-shadow_generator" name="box-shadow_generator">box-shadow generator</h2> + +<h3 id="HTML_Content">HTML Content</h3> + +<pre class="brush: html"><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> +</pre> + +<h3 id="CSS_Content">CSS Content</h3> + +<pre class="brush: css">/* 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; +} + +</pre> + +<h3 id="JavaScript_Content">JavaScript Content</h3> + +<pre class="brush: js"><code class="language-js"> + +'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 + } + +})(); + + +</code></pre> +</div> + +<div>{{ EmbedLiveSample('box-shadow_generator', '100%', '1100px', '') }}</div> + +<p><strong>Related Tool: </strong><a href="https://cssgenerator.org/box-shadow-css-generator.html">Box Shadow CSS Generator</a></p> |