diff --git a/public/css/app.css b/public/css/app.css index c4d0947..479bc31 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -53,9 +53,15 @@ input[type='radio'] { border: 0; } /* css_result */ .css_result { position: relative; float: right; width: 402px; } -.css_result .code { white-space: pre; padding: 10px; display: block; width: 380px; font-size: 12px; font-family: 'Courier new'; font-weight: bold; background: #8c9196; background: rgba(0, 0, 0, 0.15); border-radius: 4px; color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); border: 1px solid #696d72; border-color: rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px 0 rgba(255, 255, 255, 0.3), inset 0 1px 5px rgba(0, 0, 0, 0.1); } +.css_result .code { overflow-x:auto; white-space: pre; padding: 10px; display: block; width: 380px; font-size: 12px; font-family: 'Courier new'; font-weight: bold; background: #8c9196; background: rgba(0, 0, 0, 0.15); border-radius: 4px; color: #fff; text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); border: 1px solid #696d72; border-color: rgba(0, 0, 0, 0.2); box-shadow: 0 1px 1px 0 rgba(255, 255, 255, 0.3), inset 0 1px 5px rgba(0, 0, 0, 0.1); } .css_result .copy_code { position: absolute; bottom: 5px; right: 10px; width: 14px; height: 22px; background: url(../img/clippy.png) no-repeat 0 4px; } +.css_result .btn-group { margin-bottom: 10px; } +.css_result .btn { font-size: 12px; margin:0; padding: 4px 10px; color: #CCC; border: 1px solid #ccc; cursor: pointer; background: #8c9196; background: rgba(0, 0, 0, 0.15); box-shadow: 0 1px 1px 0 rgba(255, 255, 255, 0.3), inset 0 1px 5px rgba(0, 0, 0, 0.1); text-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); border: 1px solid #696d72; } +.css_result .btn:first-child { border-radius: 4px 0 0 4px;} +.css_result .btn:last-child { border-radius: 0 4px 4px 0;} +.css_result .btn.active { color: #ffffff; } +.btn-group > .btn + .btn { margin-left: -1px; } /* fork_me */ .fork_me { position: absolute; top: 0; right: 0; display: block; width: 149px; height: 149px; background: url(../img/fork.png); diff --git a/public/index.html b/public/index.html index 413f523..471a3f2 100644 --- a/public/index.html +++ b/public/index.html @@ -52,6 +52,11 @@

Arrow configuration

+
+ +
diff --git a/public/js/lib/models/arrow.js b/public/js/lib/models/arrow.js index 262db02..cc88824 100644 --- a/public/js/lib/models/arrow.js +++ b/public/js/lib/models/arrow.js @@ -179,6 +179,165 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {}; return css.join('\n'); }, + + /** + @method _baseLESS + @description generates the base less + @returns {String} less + @protected + **/ + _baseLESS: function () { + var pos = this.get('position'), + iPos = this.invertedPosition(), + color = this.get('color'), + borderWidth = this.get('borderWidth') + 'px', + borderColor = this.get('borderColor'), + size = this.get('size') + 'px', + hasBorder = parseInt(borderWidth) > 0, + less = '@arrow_size : ' + size + ';\n'; + + less += '@arrow_color: ' + color + ';\n'; + less += '@arrow_border_width : ' + borderWidth + ';\n'; + less += '@arrow_border_color : ' + borderColor + ';\n\n'; + + less += '.arrow_box {\n'; + less += '\tposition: relative;\n'; + less += '\tbackground: @arrow_color;\n'; + + if (hasBorder) less += '\tborder: @arrow_border_width solid @arrow_border_color;\n'; + + less += '\t&:after'; + + if (hasBorder) less += ', &:before {\n'; + else less += ' {\n'; + + less += '\t\t' + iPos +': 100%;\n'; + less += '\t\tborder: solid transparent;\n'; + less += '\t\tcontent: " ";\n'; + less += '\t\theight: 0;\n'; + less += '\t\twidth: 0;\n'; + less += '\t\tposition: absolute;\n'; + less += '\t\tpointer-events: none;\n'; + less += '\t}\n'; + + less += '\t&:after{\n'; + less += '\t\tborder-color: hsla(hue(@arrow_color), saturation(@arrow_color), lightness(@arrow_color), 0);\n' + less += '\t\tborder-' + iPos + '-color: @arrow_color;\n'; + less += '\t\tborder-width: @arrow_size;\n'; + if (pos === 'top' || pos === 'bottom') { + less += '\t\tleft: 50%;\n\t\tmargin-left: -@arrow_size;\n'; + } + else { + less += '\t\ttop: 50%;\n\t\tmargin-top: -@arrow_size;\n'; + } + less += '\t}\n'; + + + less += '\t&:before{\n'; + less += '\t\tborder-color: hsla(hue(@arrow_border_color), saturation(@arrow_border_color), lightness(@arrow_border_color), 0);\n' + less += '\t\tborder-' + iPos + '-color: @arrow_border_color;\n'; + less += '\t\tborder-width: (@arrow_size + round(@arrow_border_width * 1.41421356));\n'; + if (pos === 'top' || pos === 'bottom') { + less += '\t\tleft: 50%;\n\t\tmargin-left: -(@arrow_size + round(@arrow_border_width * 1.41421356));\n'; + } + else { + less += '\t\ttop: 50%;\n\t\tmargin-top: -(@arrow_size + round(@arrow_border_width * 1.41421356));\n'; + } + less += '\t}\n'; + + less += '}\n'; + + return less; + }, + + /** + @method toLESS + @description returns a LESS representation of the arrow + @returns {String} less + **/ + toLESS: function() { + return this._baseLESS(); + }, + + /** + @method _baseSCSS + @description generates the base scss + @returns {String} scss + @protected + **/ + _baseSCSS: function () { + var pos = this.get('position'), + iPos = this.invertedPosition(), + color = this.get('color'), + borderWidth = this.get('borderWidth') + 'px', + borderColor = this.get('borderColor'), + size = this.get('size') + 'px', + hasBorder = parseInt(borderWidth) > 0, + scss = '$arrow_size : ' + size + ';\n'; + + scss += '$arrow_color: ' + color + ';\n'; + scss += '$arrow_border_width : ' + borderWidth + ';\n'; + scss += '$arrow_border_color : ' + borderColor + ';\n\n'; + + scss += '.arrow_box {\n'; + scss += '\tposition: relative;\n'; + scss += '\tbackground: $arrow_color;\n'; + + if (hasBorder) scss += '\tborder: $arrow_border_width solid $arrow_border_color;\n'; + + scss += '\t&:after'; + + if (hasBorder) scss += ', &:before {\n'; + else scss += ' {\n'; + + scss += '\t\t' + iPos +': 100%;\n'; + scss += '\t\tborder: solid transparent;\n'; + scss += '\t\tcontent: " ";\n'; + scss += '\t\theight: 0;\n'; + scss += '\t\twidth: 0;\n'; + scss += '\t\tposition: absolute;\n'; + scss += '\t\tpointer-events: none;\n'; + scss += '\t}\n'; + + scss += '\t&:after{\n'; + scss += '\t\tborder-color: hsla(hue($arrow_color), saturation($arrow_color), lightness($arrow_color), 0);\n' + scss += '\t\tborder-' + iPos + '-color: $arrow_color;\n'; + scss += '\t\tborder-width: $arrow_size;\n'; + if (pos === 'top' || pos === 'bottom') { + scss += '\t\tleft: 50%;\n\t\tmargin-left: -$arrow_size;\n'; + } + else { + scss += '\t\ttop: 50%;\n\t\tmargin-top: -$arrow_size;\n'; + } + scss += '\t}\n'; + + + scss += '\t&:before{\n'; + scss += '\t\tborder-color: hsla(hue($arrow_border_color), saturation($arrow_border_color), lightness($arrow_border_color), 0);\n' + scss += '\t\tborder-' + iPos + '-color: $arrow_border_color;\n'; + scss += '\t\tborder-width: ($arrow_size + round($arrow_border_width * 1.41421356));\n'; + if (pos === 'top' || pos === 'bottom') { + scss += '\t\tleft: 50%;\n\t\tmargin-left: -($arrow_size + round($arrow_border_width * 1.41421356));\n'; + } + else { + scss += '\t\ttop: 50%;\n\t\tmargin-top: -($arrow_size + round($arrow_border_width * 1.41421356));\n'; + } + scss += '\t}\n'; + + scss += '}\n'; + + return scss; + }, + + /** + @method toSCSS + @description returns a SCSS representation of the arrow + @returns {String} scss + **/ + toSCSS: function() { + return this._baseSCSS(); + }, + /** @method _createAttrs @description creates attributes from the ATTR constant diff --git a/public/js/lib/views/arrow_css_view.js b/public/js/lib/views/arrow_css_view.js index fdcb688..014fbf7 100644 --- a/public/js/lib/views/arrow_css_view.js +++ b/public/js/lib/views/arrow_css_view.js @@ -20,8 +20,33 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {}; this.model = options.model; this.model.on('change', this._handleChange, this); + this.output_type = 'css'; + this._attachEvents(); }, + /** + @method _attachEvents + @description attaches dom events + @protected + **/ + _attachEvents: function () { + $('.btn', this.container).click($.proxy(this._handleClick, this)); + }, + + /** + @method _handleClick + @description handles click on output type CSS / LESS / SCSS + @chainable + **/ + _handleClick: function (e) { + var target = $(e.target); + this.output_type = target.val(); + $('.btn', this.container).removeClass('active'); + target.addClass('active'); + this.render(); + }, + + /** @method _handleChange @description handles changes to the model @@ -37,10 +62,19 @@ if (!('CSSArrowPlease' in window)) window.CSSArrowPlease = {}; @chainable **/ render: function () { - var css = this.model.toCSS(); - this._codeNode.text( css ); - this._copyNode.text( css ) + var text; + switch(this.output_type){ + case 'css': + text = this.model.toCSS(); break; + case 'less': + text = this.model.toLESS(); break; + case 'scss': + text = this.model.toSCSS(); break; + } + + this._codeNode.text( text ); + this._copyNode.text( text ) .clippy({ transparent: true }); return this;