mirror of
https://github.com/mue/mue.git
synced 2026-07-12 10:46:12 +02:00
Merge things
This commit is contained in:
@@ -19,6 +19,10 @@ export default class Section extends React.PureComponent {
|
||||
display: display,
|
||||
transform: transform
|
||||
});
|
||||
|
||||
if (this.props.onToggle) {
|
||||
this.props.onToggle(display);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -3,16 +3,21 @@ import { toast } from 'react-toastify';
|
||||
import Checkbox from '../Checkbox';
|
||||
import Dropdown from '../Dropdown';
|
||||
import Section from '../Section';
|
||||
import { ColorPicker } from 'react-color-gradient-picker';
|
||||
import hexToRgb from '../../../../modules/helpers/background/hexToRgb';
|
||||
import rgbToHex from '../../../../modules/helpers/background/rgbToHex';
|
||||
|
||||
export default class BackgroundSettings extends React.PureComponent {
|
||||
DefaultGradientSettings = { 'angle': '180', 'gradient': [{ 'colour': this.props.language.background.disabled, 'stop': 0 }], 'type': 'linear' };
|
||||
DefaultGradientSettings = { "angle": "180", "gradient": [{ "colour": this.props.language.background.disabled, "stop": 0 }], "type": "linear" };
|
||||
GradientPickerInitalState = undefined;
|
||||
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {
|
||||
blur: 0,
|
||||
brightness: 100,
|
||||
gradientSettings: this.DefaultGradientSettings
|
||||
gradientSettings: this.DefaultGradientSettings,
|
||||
shown: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,6 +41,23 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
toast(this.props.toastLanguage.reset);
|
||||
}
|
||||
|
||||
InitializeColorPickerState(gradientSettings) {
|
||||
this.GradientPickerInitalState = {
|
||||
points: gradientSettings.gradient.map((g) => {
|
||||
const rgb = 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();
|
||||
@@ -59,7 +81,7 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
try {
|
||||
gradientSettings = JSON.parse(hex);
|
||||
} catch (e) {
|
||||
//Disregard exception.
|
||||
// Disregard exception.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,30 +111,13 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
pickFirstColour = (event) => {
|
||||
const value = event.target.value;
|
||||
this.setState({ gradientSettings: { 'angle': '180', 'gradient': [{ 'colour': value, 'stop': 0 }], 'type': 'linear' } });
|
||||
}
|
||||
|
||||
addColour = () => {
|
||||
this.setState((s) => {
|
||||
const [lastGradient, ...initGradients] = s.gradientSettings.gradient.reverse();
|
||||
const newState = {
|
||||
gradientSettings: {
|
||||
...s.gradientSettings,
|
||||
gradient: [...initGradients, lastGradient, { ...lastGradient, stop: 100 }].sort((a, b) => (a.stop > b.stop) ? 1 : -1)
|
||||
}
|
||||
};
|
||||
return newState;
|
||||
});
|
||||
}
|
||||
|
||||
removeColour = (index) => {
|
||||
this.setState((s) => {
|
||||
const newState = {
|
||||
gradientSettings: {
|
||||
...s.gradientSettings,
|
||||
gradient: s.gradientSettings.gradient.filter((g, i) => i !== index)
|
||||
gradient: [...initGradients, lastGradient, { 'colour': localStorage.getItem('darkTheme') === 'true' ? '#000000' : '#ffffff', stop: 100 }].sort((a, b) => (a.stop > b.stop) ? 1 : -1)
|
||||
}
|
||||
};
|
||||
return newState;
|
||||
@@ -130,31 +135,54 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
return this.props.language.background.disabled;
|
||||
}
|
||||
|
||||
onColorPickerChange = (attrs, name) => {
|
||||
if (process.env.NODE_ENV === 'development') console.log(attrs, name);
|
||||
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 }
|
||||
});
|
||||
};
|
||||
|
||||
onSectionToggle = () => {
|
||||
this.setState((state) => {
|
||||
return {
|
||||
shown: !state.shown
|
||||
};
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let colourSettings = null;
|
||||
if (typeof this.state.gradientSettings === 'object') {
|
||||
const gradientInputs = this.state.gradientSettings.gradient.map((g, i) => {
|
||||
const gradientHasMoreThanOneColour = this.state.gradientSettings.gradient.length > 1;
|
||||
return (
|
||||
<div key={i}>
|
||||
{gradientHasMoreThanOneColour ? (<button type='button' className='remove' onClick={() => this.removeColour(i)}>×</button>) : null}
|
||||
<input id={'colour_' + i} type='color' name='colour' className='colour' onChange={(event) => this.onGradientChange(event, i)} value={g.colour}></input>
|
||||
<label htmlFor={'colour_' + i} className='customBackgroundHex'>{g.colour}</label>
|
||||
{gradientHasMoreThanOneColour ? (
|
||||
<input type='number' name='stop' className='stop' min={0} max={100} value={g.stop} onChange={(event) => this.onGradientChange(event, i)} />
|
||||
) : null}
|
||||
</div>);
|
||||
});
|
||||
const gradientHasMoreThanOneColour = this.state.gradientSettings.gradient.length > 1;
|
||||
let gradientInputs;
|
||||
if (gradientHasMoreThanOneColour) {
|
||||
if (this.GradientPickerInitalState === undefined) {
|
||||
this.InitializeColorPickerState(this.state.gradientSettings);
|
||||
}
|
||||
gradientInputs = (<ColorPicker
|
||||
onStartChange={color => this.onColorPickerChange(color, 'start')}
|
||||
onChange={color => this.onColorPickerChange(color, 'change')}
|
||||
onEndChange={color => this.onColorPickerChange(color, 'end')}
|
||||
gradient={this.GradientPickerInitalState}
|
||||
isGradient />);
|
||||
} else {
|
||||
gradientInputs = this.state.gradientSettings.gradient.map((g, i) => {
|
||||
return (
|
||||
<div key={i}>
|
||||
<input id={'colour_' + i} type='color' name='colour' className="colour" onChange={(event) => this.onGradientChange(event, i)} value={g.colour}></input>
|
||||
<label htmlFor={'colour_' + i} className="customBackgroundHex">{g.colour}</label>
|
||||
</div>);
|
||||
});
|
||||
}
|
||||
colourSettings = (
|
||||
<div>
|
||||
{gradientInputs}
|
||||
{this.state.gradientSettings.gradient[0].colour !== this.props.language.background.disabled ? (<button type='button' className='add' onClick={this.addColour}>{this.props.language.background.add_colour}</button>) : null}
|
||||
{this.state.gradientSettings.gradient[0].colour !== this.props.language.background.disabled && !gradientHasMoreThanOneColour ? (<button type="button" className="add" onClick={this.addColour}>{this.props.language.background.add_colour}</button>) : null}
|
||||
</div>);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Section title={this.props.language.background.title} name='background'>
|
||||
<Section title={this.props.language.background.title} name='background' onToggle={this.onSectionToggle}>
|
||||
<ul>
|
||||
<Checkbox name='view' text={this.props.language.background.view} />
|
||||
<Checkbox name='favouriteEnabled' text={this.props.language.background.favourite} />
|
||||
@@ -190,8 +218,8 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
</ul>
|
||||
<ul>
|
||||
<p>{this.props.language.background.custom_colour} <span className='modalLink' onClick={() => this.resetItem('customBackgroundColour')}>{this.props.language.reset}</span></p>
|
||||
<input id='customBackgroundHex' type='hidden' value={this.currentGradientSettings()} />
|
||||
{colourSettings}
|
||||
<input id='customBackgroundHex' type='hidden' value={this.currentGradientSettings()} />
|
||||
{this.state.shown && colourSettings}
|
||||
</ul>
|
||||
</Section>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -6,9 +6,9 @@ export default class Background extends React.PureComponent {
|
||||
const { type, angle, gradient } = gradientSettings;
|
||||
let style = `background: ${gradient[0].colour};`;
|
||||
if (gradient.length > 1) {
|
||||
//Note: Append the gradient for additional browser support.
|
||||
// Note: Append the gradient for additional browser support.
|
||||
const stepStyles = gradient.map(g => ` ${g.colour} ${g.stop}%`).join();
|
||||
style += ` background: ${type}-gradient(${angle}deg,${stepStyles})`;
|
||||
style += ` background: ${type}-gradient(${(type === 'linear' ? (`${angle}deg,`) : '')}${stepStyles})`;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
@@ -20,7 +20,7 @@ export default class Background extends React.PureComponent {
|
||||
} catch (e) {
|
||||
const hexColorRegex = /#[0-9a-fA-F]{6}/s;
|
||||
if (hexColorRegex.exec(colour)) {
|
||||
//colour use to be simply a hex colour or a NULL value before it was a JSON object. This automatically upgrades the hex colour value to the new standard. (NULL would not trigger an exception)
|
||||
// Colour use to be simply a hex colour or a NULL value before it was a JSON object. This automatically upgrades the hex colour value to the new standard. (NULL would not trigger an exception)
|
||||
gradientSettings = { "type": "linear", "angle": "180", "gradient": [{ "colour": colour, "stop": 0 }] };
|
||||
localStorage.setItem('customBackgroundColour', JSON.stringify(gradientSettings));
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import ReactDOM from 'react-dom';
|
||||
|
||||
import App from './App';
|
||||
|
||||
import 'react-color-gradient-picker/dist/index.css';
|
||||
import './scss/react-color-picker-gradient-picker-custom-styles.scss';
|
||||
import './scss/index.scss';
|
||||
import 'react-toastify/dist/ReactToastify.css'; // the toast css is based on default so we need to import it
|
||||
|
||||
|
||||
31
src/modules/helpers/background/hexToRgb.js
Normal file
31
src/modules/helpers/background/hexToRgb.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import rgbToHsv from './rgbToHsv';
|
||||
import setRgba from './setRgba';
|
||||
|
||||
const hexRegexp = /(^#{0,1}[0-9A-F]{6}$)|(^#{0,1}[0-9A-F]{3}$)|(^#{0,1}[0-9A-F]{8}$)/i;
|
||||
|
||||
const regexp = /([0-9A-F])([0-9A-F])([0-9A-F])/i;
|
||||
|
||||
export default function hexToRgb(value) {
|
||||
const 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');
|
||||
|
||||
const red = parseInt(value.substr(0, 2), 16);
|
||||
const green = parseInt(value.substr(2, 2), 16);
|
||||
const blue = parseInt(value.substr(4, 2), 16);
|
||||
const alpha = parseInt(value.substr(6, 2), 16) / 255;
|
||||
|
||||
const color = setRgba(red, green, blue, alpha);
|
||||
const hsv = rgbToHsv({ ...color });
|
||||
|
||||
return {
|
||||
...color,
|
||||
...hsv,
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
11
src/modules/helpers/background/rgbToHex.js
Normal file
11
src/modules/helpers/background/rgbToHex.js
Normal file
@@ -0,0 +1,11 @@
|
||||
export default 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;
|
||||
}
|
||||
42
src/modules/helpers/background/rgbToHsv.js
Normal file
42
src/modules/helpers/background/rgbToHsv.js
Normal file
@@ -0,0 +1,42 @@
|
||||
export default function rgbToHSv({ red, green, blue }) {
|
||||
let rr;
|
||||
let gg;
|
||||
let bb;
|
||||
let h;
|
||||
let s;
|
||||
|
||||
const rabs = red / 255;
|
||||
const gabs = green / 255;
|
||||
const babs = blue / 255;
|
||||
const v = Math.max(rabs, gabs, babs);
|
||||
const diff = v - Math.min(rabs, gabs, babs);
|
||||
const diffc = c => (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),
|
||||
};
|
||||
}
|
||||
21
src/modules/helpers/background/setRgba.js
Normal file
21
src/modules/helpers/background/setRgba.js
Normal file
@@ -0,0 +1,21 @@
|
||||
function isValidRGBValue(value) {
|
||||
return (typeof (value) === 'number' && Number.isNaN(value) === false && value >= 0 && value <= 255);
|
||||
}
|
||||
|
||||
export default function setRGBA(red, green, blue, alpha) {
|
||||
if (isValidRGBValue(red) && isValidRGBValue(green) && isValidRGBValue(blue)) {
|
||||
const color = {
|
||||
red: red | 0,
|
||||
green: green | 0,
|
||||
blue: blue | 0,
|
||||
};
|
||||
|
||||
if (isValidRGBValue(alpha) === true) {
|
||||
color.alpha = alpha | 0;
|
||||
}
|
||||
|
||||
// RGBToHSL(color.r, color.g, color.b);
|
||||
|
||||
return color;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// The following CSS is to work around some assumptions made by the react-color-gradient-picker
|
||||
* {
|
||||
box-sizing: inherit; // Required to work around https://github.com/arthay/react-color-gradient-picker/issues/11
|
||||
}
|
||||
|
||||
div.picker-area > div.preview > div.color-hue-alpha > div.alpha,
|
||||
div.color-preview-area > div > div:nth-child(5) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui-color-picker {
|
||||
margin: 8px -12px;
|
||||
}
|
||||
|
||||
.input-field .label {
|
||||
color: inherit;
|
||||
}
|
||||
Reference in New Issue
Block a user