diff --git a/package.json b/package.json index bdef07cd..33faf477 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "lodash.merge": "4.6.2", "react": "16.14.0", "react-clock": "^2.4.0", + "react-color-gradient-picker": "^0.1.2", "react-dom": "16.14.0", "react-modal": "3.11.2", "react-toastify": "6.0.9", diff --git a/src/components/modals/settings/Section.jsx b/src/components/modals/settings/Section.jsx index 7b71cab5..46654057 100644 --- a/src/components/modals/settings/Section.jsx +++ b/src/components/modals/settings/Section.jsx @@ -6,8 +6,8 @@ export default class Section extends React.PureComponent { constructor(...args) { super(...args); this.state = { - display: 'none', - transform: 'rotate(0)' + display: 'block', + transform: 'rotate(-180deg)' }; } diff --git a/src/components/modals/settings/sections/BackgroundSettings.jsx b/src/components/modals/settings/sections/BackgroundSettings.jsx index dae31f65..156f5c96 100644 --- a/src/components/modals/settings/sections/BackgroundSettings.jsx +++ b/src/components/modals/settings/sections/BackgroundSettings.jsx @@ -2,9 +2,12 @@ import React from 'react'; import { toast } from 'react-toastify'; import Checkbox from '../Checkbox'; import Section from '../Section'; +import { ColorPicker } from 'react-color-gradient-picker'; +import 'react-color-gradient-picker/dist/index.css'; export default class BackgroundSettings extends React.PureComponent { DefaultGradientSettings = { "angle": "180", "gradient": [{ "colour": this.props.language.background.disabled, "stop": 0 }], "type": "linear" }; + GradientPickerInitalState = {}; constructor(...args) { super(...args); @@ -35,6 +38,132 @@ export default class BackgroundSettings extends React.PureComponent { toast(this.props.toastLanguage.reset); } + + setRGBA(red, green, blue, alpha) { + if (this.isValidRGBValue(red) && this.isValidRGBValue(green) && this.isValidRGBValue(blue)) { + var color = { + red: red | 0, + green: green | 0, + blue: blue | 0, + }; + + if (this.isValidRGBValue(alpha) === true) { + color.alpha = alpha | 0; + } + + // RGBToHSL(color.r, color.g, color.b); + + return color; + } +} + isValidRGBValue(value) { + return (typeof (value) === 'number' && Number.isNaN(value) === false && value >= 0 && value <= 255); +} + rgbToHSv(ref) { + var red = ref.red; + var green = ref.green; + var blue = ref.blue; + + var rr; + var gg; + var bb; + var h; + var s; + + var rabs = red / 255; + var gabs = green / 255; + var babs = blue / 255; + var v = Math.max(rabs, gabs, babs); + var diff = v - Math.min(rabs, gabs, babs); + var diffc = function (c) { return (v - c) / 6 / diff + 1 / 2; }; + if (diff === 0) { + h = 0; + s = 0; + } else { + s = diff / v; + rr = diffc(rabs); + gg = diffc(gabs); + bb = diffc(babs); + + if (rabs === v) { + h = bb - gg; + } else if (gabs === v) { + h = (1 / 3) + rr - bb; + } else if (babs === v) { + h = (2 / 3) + gg - rr; + } + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + } + + return { + hue: Math.round(h * 360), + saturation: Math.round(s * 100), + value: Math.round(v * 100), + }; +} + + + hexToRgb(value) { + var hexRegexp = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)|(^#{0,1}[0-9A-F]{8}$)/i; + + var regexp = /([0-9A-F])([0-9A-F])([0-9A-F])/i; + var valid = hexRegexp.test(value); + + if (valid) { + if (value[0] === '#') { value = value.slice(1, value.length); } + + if (value.length === 3) { value = value.replace(regexp, '$1$1$2$2$3$3'); } + + var red = parseInt(value.substr(0, 2), 16); + var green = parseInt(value.substr(2, 2), 16); + var blue = parseInt(value.substr(4, 2), 16); + var alpha = parseInt(value.substr(6, 2), 16) / 255; + + var color = this.setRGBA(red, green, blue, alpha); + var hsv = this.rgbToHSv(Object.assign({}, color)); + + return Object.assign({}, color, + hsv); + } + + return false; +} + +UNSAFE_componentWillMount(){ + const hex = localStorage.getItem('customBackgroundColour'); + let gradientSettings = undefined; + + if (hex !== '') { + try { + gradientSettings = JSON.parse(hex); + } catch (e) { + //Disregard exception. + } + } + + if (gradientSettings === undefined) gradientSettings = this.DefaultGradientSettings; + + console.log(this.hexToRgb("#ff12ab")); + this.GradientPickerInitalState = { + points: gradientSettings.gradient.map((g) => { + const rgb = this.hexToRgb(g.colour); + return { + left: +g.stop, + red: rgb.red, + green: rgb.green, + blue: rgb.blue, + alpha: 1 + } + }), + degree: +gradientSettings.angle, + type: gradientSettings.type + } +} + componentDidMount() { document.getElementById('bg-input').onchange = (e) => { const reader = new FileReader(); @@ -63,7 +192,7 @@ export default class BackgroundSettings extends React.PureComponent { } if (gradientSettings === undefined) gradientSettings = this.DefaultGradientSettings; - + this.setState({ blur: localStorage.getItem('blur'), brightness: localStorage.getItem('brightness'), @@ -129,6 +258,24 @@ export default class BackgroundSettings extends React.PureComponent { return this.props.language.background.disabled; } + onChange = (attrs, name) => { + console.log(attrs, name); + function rgbToHex(red, green, blue) { + let r16 = red.toString(16); + let g16 = green.toString(16); + let b16 = blue.toString(16); + + if (red < 16) r16 = `0${r16}`; + if (green < 16) g16 = `0${g16}`; + if (blue < 16) b16 = `0${b16}`; + + return r16 + g16 + b16; + } + this.setState({ + gradientSettings: { 'angle': attrs.degree, 'gradient': attrs.points.map((p) => {return {'colour': '#'+rgbToHex(p.red, p.green, p.blue), 'stop': p.left }}), 'type': attrs.type } + }); + }; + render() { let colourSettings = null; if (typeof this.state.gradientSettings === 'object') { @@ -140,8 +287,8 @@ export default class BackgroundSettings extends React.PureComponent { this.onGradientChange(event, i)} value={g.colour}> {gradientHasMoreThanOneColour ? ( - this.onGradientChange(event, i)} /> - ) : null} + this.onGradientChange(event, i)} /> + ) : null} ); }); colourSettings = ( @@ -189,6 +336,12 @@ export default class BackgroundSettings extends React.PureComponent {
{this.props.language.background.customcolour} this.resetItem('customBackgroundColour')}>{this.props.language.reset}
{colourSettings} +