From e3bdc391cd2a40c4c6346645cb30529d7dccd356 Mon Sep 17 00:00:00 2001 From: Nick Walke Date: Thu, 3 Mar 2016 12:01:14 -0600 Subject: [PATCH] Closes #55. Allows you to set the primary color. This certainly should not be seen as the final implementation of this. I imagine that requests like this will happen for many other colors in the system, it might be good at some point to allow them to upload their own stylesheet to be used. --- app/Http/Controllers/SettingController.php | 50 ++++++++++++++++++++++ public/libs/jscolor/jscolor.min.js | 10 +++++ resources/views/base.blade.php | 19 ++++++++ resources/views/public.blade.php | 14 +++++- resources/views/settings/index.blade.php | 9 ++++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 public/libs/jscolor/jscolor.min.js diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php index 1739e0b53..47f59efbb 100644 --- a/app/Http/Controllers/SettingController.php +++ b/app/Http/Controllers/SettingController.php @@ -38,6 +38,9 @@ class SettingController extends Controller foreach($request->all() as $name => $value) { if(strpos($name, 'setting-') !== 0) continue; $key = str_replace('setting-', '', trim($name)); + if($key == 'app-color') { + Setting::put('app-color-rgba', $this->hex2rgba($value, 0.15)); + } Setting::put($key, $value); } @@ -45,4 +48,51 @@ class SettingController extends Controller return redirect('/settings'); } + /** + * Adapted from http://mekshq.com/how-to-convert-hexadecimal-color-code-to-rgb-or-rgba-using-php/ + * Converts a hex color code in to an RGBA string. + * + * @param string $color + * @param float|boolean $opacity + * @return boolean|string + */ + protected function hex2rgba($color, $opacity = false) + { + // Return false if no color provided + if(empty($color)) { + return false; + } + // Trim any whitespace + $color = trim($color); + + // Sanitize $color if "#" is provided + if($color[0] == '#' ) { + $color = substr($color, 1); + } + + // Check if color has 6 or 3 characters and get values + if(strlen($color) == 6) { + $hex = array( $color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5] ); + } elseif( strlen( $color ) == 3 ) { + $hex = array( $color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2] ); + } else { + return false; + } + + // Convert hexadec to rgb + $rgb = array_map('hexdec', $hex); + + // Check if opacity is set(rgba or rgb) + if($opacity) { + if(abs($opacity) > 1) + $opacity = 1.0; + $output = 'rgba('.implode(",",$rgb).','.$opacity.')'; + } else { + $output = 'rgb('.implode(",",$rgb).')'; + } + + // Return rgb(a) color string + return $output; + } + } diff --git a/public/libs/jscolor/jscolor.min.js b/public/libs/jscolor/jscolor.min.js new file mode 100644 index 000000000..2a7a788be --- /dev/null +++ b/public/libs/jscolor/jscolor.min.js @@ -0,0 +1,10 @@ +/** + * jscolor - JavaScript Color Picker + * + * @link http://jscolor.com + * @license For open source use: GPLv3 + * For commercial use: JSColor Commercial License + * @author Jan Odvarko + * + * See usage examples at http://jscolor.com/examples/ + */"use strict";window.jscolor||(window.jscolor=function(){var e={register:function(){e.attachDOMReadyEvent(e.init),e.attachEvent(document,"mousedown",e.onDocumentMouseDown),e.attachEvent(document,"touchstart",e.onDocumentTouchStart),e.attachEvent(window,"resize",e.onWindowResize)},init:function(){e.jscolor.lookupClass&&e.jscolor.installByClassName(e.jscolor.lookupClass)},tryInstallOnElements:function(t,n){var r=new RegExp("(^|\\s)("+n+")(\\s*(\\{[^}]*\\})|\\s|$)","i");for(var i=0;is[u]?-r[u]+n[u]+i[u]/2>s[u]/2&&n[u]+i[u]-o[u]>=0?n[u]+i[u]-o[u]:n[u]:n[u],-r[a]+n[a]+i[a]+o[a]-l+l*f>s[a]?-r[a]+n[a]+i[a]/2>s[a]/2&&n[a]+i[a]-l-l*f>=0?n[a]+i[a]-l-l*f:n[a]+i[a]-l+l*f:n[a]+i[a]-l+l*f>=0?n[a]+i[a]-l+l*f:n[a]+i[a]-l-l*f];var h=c[u],p=c[a],d=t.fixed?"fixed":"absolute",v=(c[0]+o[0]>n[0]||c[0]2)switch(e.mode.charAt(2).toLowerCase()){case"s":return"s";case"v":return"v"}return null},onDocumentMouseDown:function(t){t||(t=window.event);var n=t.target||t.srcElement;n._jscLinkedInstance?n._jscLinkedInstance.showOnClick&&n._jscLinkedInstance.show():n._jscControlName?e.onControlPointerStart(t,n,n._jscControlName,"mouse"):e.picker&&e.picker.owner&&e.picker.owner.hide()},onDocumentTouchStart:function(t){t||(t=window.event);var n=t.target||t.srcElement;n._jscLinkedInstance?n._jscLinkedInstance.showOnClick&&n._jscLinkedInstance.show():n._jscControlName?e.onControlPointerStart(t,n,n._jscControlName,"touch"):e.picker&&e.picker.owner&&e.picker.owner.hide()},onWindowResize:function(t){e.redrawPosition()},onParentScroll:function(t){e.picker&&e.picker.owner&&e.picker.owner.hide()},_pointerMoveEvent:{mouse:"mousemove",touch:"touchmove"},_pointerEndEvent:{mouse:"mouseup",touch:"touchend"},_pointerOrigin:null,_capturedTarget:null,onControlPointerStart:function(t,n,r,i){var s=n._jscInstance;e.preventDefault(t),e.captureTarget(n);var o=function(s,o){e.attachGroupEvent("drag",s,e._pointerMoveEvent[i],e.onDocumentPointerMove(t,n,r,i,o)),e.attachGroupEvent("drag",s,e._pointerEndEvent[i],e.onDocumentPointerEnd(t,n,r,i))};o(document,[0,0]);if(window.parent&&window.frameElement){var u=window.frameElement.getBoundingClientRect(),a=[-u.left,-u.top];o(window.parent.window.document,a)}var f=e.getAbsPointerPos(t),l=e.getRelPointerPos(t);e._pointerOrigin={x:f.x-l.x,y:f.y-l.y};switch(r){case"pad":switch(e.getSliderComponent(s)){case"s":s.hsv[1]===0&&s.fromHSV(null,100,null);break;case"v":s.hsv[2]===0&&s.fromHSV(null,null,100)}e.setPad(s,t,0,0);break;case"sld":e.setSld(s,t,0)}e.dispatchFineChange(s)},onDocumentPointerMove:function(t,n,r,i,s){return function(t){var i=n._jscInstance;switch(r){case"pad":t||(t=window.event),e.setPad(i,t,s[0],s[1]),e.dispatchFineChange(i);break;case"sld":t||(t=window.event),e.setSld(i,t,s[1]),e.dispatchFineChange(i)}}},onDocumentPointerEnd:function(t,n,r,i){return function(t){var r=n._jscInstance;e.detachGroupEvents("drag"),e.releaseTarget(),e.dispatchChange(r)}},dispatchChange:function(t){t.valueElement&&e.isElementType(t.valueElement,"input")&&e.fireEvent(t.valueElement,"change")},dispatchFineChange:function(e){if(e.onFineChange){var t;typeof e.onFineChange=="string"?t=new Function(e.onFineChange):t=e.onFineChange,t.call(e)}},setPad:function(t,n,r,i){var s=e.getAbsPointerPos(n),o=r+s.x-e._pointerOrigin.x-t.padding-t.insetWidth,u=i+s.y-e._pointerOrigin.y-t.padding-t.insetWidth,a=o*(360/(t.width-1)),f=100-u*(100/(t.height-1));switch(e.getPadYComponent(t)){case"s":t.fromHSV(a,f,null,e.leaveSld);break;case"v":t.fromHSV(a,null,f,e.leaveSld)}},setSld:function(t,n,r){var i=e.getAbsPointerPos(n),s=r+i.y-e._pointerOrigin.y-t.padding-t.insetWidth,o=100-s*(100/(t.height-1));switch(e.getSliderComponent(t)){case"s":t.fromHSV(null,o,null,e.leavePad);break;case"v":t.fromHSV(null,null,o,e.leavePad)}},_vmlNS:"jsc_vml_",_vmlCSS:"jsc_vml_css_",_vmlReady:!1,initVML:function(){if(!e._vmlReady){var t=document;t.namespaces[e._vmlNS]||t.namespaces.add(e._vmlNS,"urn:schemas-microsoft-com:vml");if(!t.styleSheets[e._vmlCSS]){var n=["shape","shapetype","group","background","path","formulas","handles","fill","stroke","shadow","textbox","textpath","imagedata","line","polyline","curve","rect","roundrect","oval","arc","image"],r=t.createStyleSheet();r.owningElement.id=e._vmlCSS;for(var i=0;i=3&&(s=r[0].match(i))&&(o=r[1].match(i))&&(u=r[2].match(i))){var a=parseFloat((s[1]||"0")+(s[2]||"")),f=parseFloat((o[1]||"0")+(o[2]||"")),l=parseFloat((u[1]||"0")+(u[2]||""));return this.fromRGB(a,f,l,t),!0}}return!1},this.toString=function(){return(256|Math.round(this.rgb[0])).toString(16).substr(1)+(256|Math.round(this.rgb[1])).toString(16).substr(1)+(256|Math.round(this.rgb[2])).toString(16).substr(1)},this.toHEXString=function(){return"#"+this.toString().toUpperCase()},this.toRGBString=function(){return"rgb("+Math.round(this.rgb[0])+","+Math.round(this.rgb[1])+","+Math.round(this.rgb[2])+")"},this.isLight=function(){return.213*this.rgb[0]+.715*this.rgb[1]+.072*this.rgb[2]>127.5},this._processParentElementsInDOM=function(){if(this._linkedElementsProcessed)return;this._linkedElementsProcessed=!0;var t=this.targetElement;do{var n=e.getStyle(t);n&&n.position.toLowerCase()==="fixed"&&(this.fixed=!0),t!==this.targetElement&&(t._jscEventsAttached||(e.attachEvent(t,"scroll",e.onParentScroll),t._jscEventsAttached=!0))}while((t=t.parentNode)&&!e.isElementType(t,"body"))};if(typeof t=="string"){var h=t,p=document.getElementById(h);p?this.targetElement=p:e.warn("Could not find target element with ID '"+h+"'")}else t?this.targetElement=t:e.warn("Invalid target element: '"+t+"'");if(this.targetElement._jscLinkedInstance){e.warn("Cannot link jscolor twice to the same element. Skipping.");return}this.targetElement._jscLinkedInstance=this,this.valueElement=e.fetchElement(this.valueElement),this.styleElement=e.fetchElement(this.styleElement);var d=this,v=this.container?e.fetchElement(this.container):document.getElementsByTagName("body")[0],m=3;if(e.isElementType(this.targetElement,"button"))if(this.targetElement.onclick){var g=this.targetElement.onclick;this.targetElement.onclick=function(e){return g.call(this,e),!1}}else this.targetElement.onclick=function(){return!1};if(this.valueElement&&e.isElementType(this.valueElement,"input")){var y=function(){d.fromString(d.valueElement.value,e.leaveValue),e.dispatchFineChange(d)};e.attachEvent(this.valueElement,"keyup",y),e.attachEvent(this.valueElement,"input",y),e.attachEvent(this.valueElement,"blur",c),this.valueElement.setAttribute("autocomplete","off")}this.styleElement&&(this.styleElement._jscOrigStyle={backgroundImage:this.styleElement.style.backgroundImage,backgroundColor:this.styleElement.style.backgroundColor,color:this.styleElement.style.color}),this.value?this.fromString(this.value)||this.exportColor():this.importColor()}};return e.jscolor.lookupClass="jscolor",e.jscolor.installByClassName=function(t){var n=document.getElementsByTagName("input"),r=document.getElementsByTagName("button");e.tryInstallOnElements(n,t),e.tryInstallOnElements(r,t)},e.register(),e.jscolor}()); \ No newline at end of file diff --git a/resources/views/base.blade.php b/resources/views/base.blade.php index 0df49485e..830976657 100644 --- a/resources/views/base.blade.php +++ b/resources/views/base.blade.php @@ -17,6 +17,25 @@ @yield('head') + @if(Setting::get('app-color')) + + @endif diff --git a/resources/views/public.blade.php b/resources/views/public.blade.php index d34c490a7..618e8acae 100644 --- a/resources/views/public.blade.php +++ b/resources/views/public.blade.php @@ -15,7 +15,19 @@ - + @if(Setting::get('app-color')) + + @endif diff --git a/resources/views/settings/index.blade.php b/resources/views/settings/index.blade.php index b5b5d0a4f..6b01583ae 100644 --- a/resources/views/settings/index.blade.php +++ b/resources/views/settings/index.blade.php @@ -35,6 +35,11 @@

This image should be 43px in height.
Large images will be scaled down.

+
+ +

This should be a hex value.

+ +
@@ -89,3 +94,7 @@ @include('partials/image-manager', ['imageType' => 'system']) @stop + +@section('scripts') + +@stop \ No newline at end of file