Tweak color palette

This commit is contained in:
Wei Zhu 2017-12-26 14:57:49 +08:00
parent 03e3eff01b
commit 600c8c69f0
6 changed files with 230 additions and 164 deletions

View File

@ -32,7 +32,11 @@ Ant Design 的色板还具备进一步拓展的能力。经过设计师和程序
### 中性色板
todo...
`````__react
import Palette from '../../site/theme/template/Color/Palette';
ReactDOM.render(<Palette color={{ name: 'grey' }} direction="horizontal" />, mountNode);
`````
### 数据可视化色板

View File

@ -81,6 +81,57 @@
}
}
.color-palette-horizontal {
width: 100%;
.main-color {
display: flex;
&-item {
flex: 1;
position: relative;
padding: 0;
margin-right: 0;
border-radius: 0;
height: 86px;
text-align: center;
padding-top: 37px;
line-height: normal;
.main-color-text {
float: none;
}
&:hover {
margin-top: -10px;
height: 96px;
border-radius: 4px 4px 0 0;
}
}
&-value {
position: absolute;
text-align: center;
width: 100%;
left: 0;
bottom: 0;
float: none;
transform-origin: unset;
}
&:hover {
.main-color-item {
padding-top: 8px;
}
.main-color-value {
opacity: 0.7;
bottom: 8px;
}
}
}
}
.make-palatte(@color, @index: 1) when (@index <= 10) {
.palatte-@{color}-@{index} {
@background: "@{color}-@{index}";

View File

@ -1,112 +1,25 @@
import React, { Component } from 'react';
import Color from 'color-standalone';
import { FormattedMessage } from 'react-intl';
import ColorBlock from './ColorBlock';
import ColorPicker from './ColorPicker';
const hueStep = 2; //
const saturationStep = 16; //
const saturationStep2 = 5; //
const brightnessStep1 = 5; //
const brightnessStep2 = 15; //
const lightColorCount = 5; //
const darkColorCount = 4; //
import ColorPalettes from './ColorPatterns';
// eslint-disable-next-line
export default class ColorPaletteTool extends Component {
state = {
primaryColor: '#1890ff',
};
handleChangeColor = (e) => {
const value = e.target ? e.target.value : e;
this.setState({
primaryColor: value,
});
}
// eslint-disable-next-line
getHue(hsv, i, light) {
let hue;
//
if (hsv.h >= 60 && hsv.h <= 240) {
hue = light ? hsv.h - (hueStep * i) : hsv.h + (hueStep * i);
} else {
hue = light ? hsv.h + (hueStep * i) : hsv.h - (hueStep * i);
}
if (hue < 0) {
hue += 360;
} else if (hue >= 360) {
hue -= 360;
}
return hue;
}
// eslint-disable-next-line
getSaturation(hsv, i, light) {
let saturation;
if (light) {
saturation = hsv.s - (saturationStep * i);
} else if (i === darkColorCount) {
saturation = hsv.s + (saturationStep);
} else {
saturation = hsv.s + (saturationStep2 * i);
}
//
if (saturation > 100) {
saturation = 100;
}
// s 6-10
if (light && i === lightColorCount && saturation > 10) {
saturation = 10;
}
if (saturation < 6) {
saturation = 6;
}
return saturation;
}
// eslint-disable-next-line
getValue(hsv, i, light) {
if (light) {
return hsv.v + (brightnessStep1 * i);
}
return hsv.v - (brightnessStep2 * i);
}
renderColorPatterns() {
const patterns = [];
const pColor = Color(this.state.primaryColor);
let index = 0;
for (let i = lightColorCount; i > 0; i -= 1) {
const hsv = pColor.clone().hsv();
const colorString = Color({
h: this.getHue(hsv, i, true),
s: this.getSaturation(hsv, i, true),
v: this.getValue(hsv, i, true),
}).hexString();
index += 1;
patterns.push(
<ColorBlock color={colorString} index={index} key={index} />
);
}
index += 1;
patterns.push(
<ColorBlock color={pColor.hexString()} index={index} key={index} />
);
for (let i = 1; i <= darkColorCount; i += 1) {
const hsv = pColor.clone().hsv();
const colorString = Color({
h: this.getHue(hsv, i),
s: this.getSaturation(hsv, i),
v: this.getValue(hsv, i),
}).hexString();
index += 1;
patterns.push(
<ColorBlock color={colorString} index={index} key={index} />
);
}
return patterns;
}
render() {
return (
<div style={{ margin: '0 auto', textAlign: 'center' }}>
<div className="color-palette">
<div className="color-palette-horizontal">
<div className="color-palette-pick">
<FormattedMessage id="app.docs.color.pick-primary" />
<div className="color-palette-picker">
@ -119,7 +32,7 @@ export default class ColorPaletteTool extends Component {
</div>
</div>
<div className="main-color">
{this.renderColorPatterns()}
<ColorPalettes color={this.state.primaryColor} />
</div>
</div>
</div>

View File

@ -1,73 +1,5 @@
import React, { Component } from 'react';
import CopyToClipboard from 'react-copy-to-clipboard';
import { message } from 'antd';
const rgbToHex = (rgbString) => {
const rgb = rgbString.match(/\d+/g);
let r = parseInt(rgb[0], 10).toString(16);
let g = parseInt(rgb[1], 10).toString(16);
let b = parseInt(rgb[2], 10).toString(16);
r = r.length === 1 ? `0${r}` : r;
g = g.length === 1 ? `0${g}` : g;
b = b.length === 1 ? `0${b}` : b;
return `#${r}${g}${b}`;
};
class Palette extends Component {
componentDidMount() {
this.hexColors = {};
Object.keys(this.colorNodes).forEach((key) => {
const computedColor = getComputedStyle(this.colorNodes[key])['background-color'];
if (computedColor.indexOf('rgba') >= 0) {
this.hexColors[key] = computedColor;
} else {
this.hexColors[key] = rgbToHex(computedColor);
}
});
this.forceUpdate();
}
render() {
this.colorNodes = this.colorNodes || {};
const { name, description, english, chinese } = this.props.color;
const colors = [];
const colorName = `${english} / ${chinese}`;
for (let i = 1; i <= 10; i += 1) {
const colorText = `${name}-${i}`;
colors.push(
<CopyToClipboard
text={this.hexColors ? this.hexColors[colorText] : ''}
onCopy={() => message.success(`@${colorText} copied: ${this.hexColors[colorText]}`)}
key={colorText}
>
<div
key={i}
ref={(node) => { this.colorNodes[`${name}-${i}`] = node; }}
className={`main-color-item palatte-${name}-${i}`}
style={{
color: (name === 'yellow' ? i > 6 : i > 5) ? '#fff' : 'unset',
fontWeight: i === 6 ? 'bold' : 'normal',
}}
title="click to copy color"
>
<span className="main-color-text">{colorText}</span>
{this.hexColors
? <span className="main-color-value">{this.hexColors[colorText]}</span>
: null}
</div>
</CopyToClipboard>
);
}
return (
<div className="color-palette">
<div className="color-title">
{colorName}
<span className="color-description">{description}</span>
</div>
<div className="main-color">{colors}</div>
</div>
);
}
}
import React from 'react';
import Palette from './Palette';
const ColorPalettes = () => {
const colors = [
@ -146,7 +78,7 @@ const ColorPalettes = () => {
];
return (
<div className="color-palettes">
{colors.map(color => <Palette key={color.name} color={color} />)}
{colors.map(color => <Palette key={color.name} color={color} showTitle />)}
</div>
);
};

View File

@ -0,0 +1,92 @@
import React from 'react';
import Color from 'color-standalone';
import ColorBlock from './ColorBlock';
const hueStep = 2; //
const saturationStep = 16; //
const saturationStep2 = 5; //
const brightnessStep1 = 5; //
const brightnessStep2 = 15; //
const lightColorCount = 5; //
const darkColorCount = 4; //
function getHue(hsv, i, light) {
let hue;
//
if (hsv.h >= 60 && hsv.h <= 240) {
hue = light ? hsv.h - (hueStep * i) : hsv.h + (hueStep * i);
} else {
hue = light ? hsv.h + (hueStep * i) : hsv.h - (hueStep * i);
}
if (hue < 0) {
hue += 360;
} else if (hue >= 360) {
hue -= 360;
}
return hue;
}
function getSaturation(hsv, i, light) {
let saturation;
if (light) {
saturation = hsv.s - (saturationStep * i);
} else if (i === darkColorCount) {
saturation = hsv.s + (saturationStep);
} else {
saturation = hsv.s + (saturationStep2 * i);
}
//
if (saturation > 100) {
saturation = 100;
}
// s 6-10
if (light && i === lightColorCount && saturation > 10) {
saturation = 10;
}
if (saturation < 6) {
saturation = 6;
}
return saturation;
}
function getValue(hsv, i, light) {
if (light) {
return hsv.v + (brightnessStep1 * i);
}
return hsv.v - (brightnessStep2 * i);
}
export default function ColorPatterns({ color }) {
const patterns = [];
const pColor = Color(color);
let index = 0;
for (let i = lightColorCount; i > 0; i -= 1) {
const hsv = pColor.clone().hsv();
const colorString = Color({
h: getHue(hsv, i, true),
s: getSaturation(hsv, i, true),
v: getValue(hsv, i, true),
}).hexString();
index += 1;
patterns.push(
<ColorBlock color={colorString} index={index} key={index} />
);
}
index += 1;
patterns.push(
<ColorBlock color={pColor.hexString()} index={index} key={index} />
);
for (let i = 1; i <= darkColorCount; i += 1) {
const hsv = pColor.clone().hsv();
const colorString = Color({
h: getHue(hsv, i),
s: getSaturation(hsv, i),
v: getValue(hsv, i),
}).hexString();
index += 1;
patterns.push(
<ColorBlock color={colorString} index={index} key={index} />
);
}
return patterns;
}

View File

@ -0,0 +1,74 @@
import React from 'react';
import { message } from 'antd';
import CopyToClipboard from 'react-copy-to-clipboard';
const rgbToHex = (rgbString) => {
const rgb = rgbString.match(/\d+/g);
let r = parseInt(rgb[0], 10).toString(16);
let g = parseInt(rgb[1], 10).toString(16);
let b = parseInt(rgb[2], 10).toString(16);
r = r.length === 1 ? `0${r}` : r;
g = g.length === 1 ? `0${g}` : g;
b = b.length === 1 ? `0${b}` : b;
return `#${r}${g}${b}`;
};
export default class Palette extends React.Component {
componentDidMount() {
this.hexColors = {};
Object.keys(this.colorNodes).forEach((key) => {
const computedColor = getComputedStyle(this.colorNodes[key])['background-color'];
if (computedColor.indexOf('rgba') >= 0) {
this.hexColors[key] = computedColor;
} else {
this.hexColors[key] = rgbToHex(computedColor);
}
});
this.forceUpdate();
}
render() {
this.colorNodes = this.colorNodes || {};
const { showTitle, direction } = this.props;
const { name, description, english, chinese } = this.props.color;
const className = direction === 'horizontal' ? 'color-palette-horizontal' : 'color-palette';
const colors = [];
const colorName = `${english} / ${chinese}`;
for (let i = 1; i <= 10; i += 1) {
const colorText = `${name}-${i}`;
colors.push(
<CopyToClipboard
text={this.hexColors ? this.hexColors[colorText] : ''}
onCopy={() => message.success(`@${colorText} copied: ${this.hexColors[colorText]}`)}
key={colorText}
>
<div
key={i}
ref={(node) => { this.colorNodes[`${name}-${i}`] = node; }}
className={`main-color-item palatte-${name}-${i}`}
style={{
color: (name === 'yellow' ? i > 6 : i > 5) ? '#fff' : 'unset',
fontWeight: i === 6 ? 'bold' : 'normal',
}}
title="click to copy color"
>
<span className="main-color-text">{colorText}</span>
{this.hexColors
? <span className="main-color-value">{this.hexColors[colorText]}</span>
: null}
</div>
</CopyToClipboard>
);
}
return (
<div className={className}>
{showTitle && (
<div className="color-title">
{colorName}
<span className="color-description">{description}</span>
</div>
)}
<div className="main-color">{colors}</div>
</div>
);
}
}