Author: Rainbow lollipop

Repository: ColorTools

preface

As a front-end siege lion, it is hard to avoid writing CSS in daily work. When writing CSS, it must involve the choice of color. At this time, we generally look for color matching materials on some design websites. There are many websites or tools like this, but I have a bad temper. In my spare time, I developed a simple online color debugging tool using React.

preview

Experience address: Colortools

Tools include commonly used color swatches and gradient debugging tools. The color palette tool refers to the uTools color assistant tool, and the gradient color refers to the CSS gradient site. Thank you!

swatches

gradient

Code design

Project Structure:

The index.js file in the SRC directory is the entry file, and router.js is the route entry file. Pages is a page file, components stores common components, and Configs stores configuration information.

Routing the react – the router

The entire tool has only three pages, 1. Home page, 2. Color palette page, 3. Gradient page. Three pages, use the button in the lower right corner of the new navigation jump;

import React from 'react';
import './index.css';
import {HashRouter as Router,Route,Switch} from 'react-router-dom';
import config from './configs/config';
import Home from './pages/home';
import ColorPlate from './pages/colorPlate';
import ColorGradient from './pages/colorGradient'
import NavButtonGroup from './components/NavButtonGroup';
const {navbuttons} = config;

const BasicRoute = (a)= > (
  <Router>
    <div className="main-container">
      <NavButtonGroup
        navButtons={navbuttons.navButtons}
        mainButton={navbuttons.main}
      />
      <Switch>
        <Route exact path="/" component={Home} />
        <Route exact path="/colorplate" component={ColorPlate} />
        <Route exact path="/colorgradient" component={ColorGradient} />
      </Switch>
    </div>
  </Router>
);

export default BasicRoute;
Copy the code

The
component is the navigation component in the lower right corner; Because the component is relatively simple, and in order to avoid writing repetitive code, put the navigation component in the root of the route, on the home page, do some processing, so that it is not displayed;

swatches

Colorplate page is /pages/colorplate page component; The palette is divided into three sections,

Selecting the color on the slider below will display a large block of color in the preview area. The color value area will display the corresponding RGB value and HEX value, both of which are common front-end color formats. When selecting a color, the color hex value is copied to the clipboard. Copy content to clipboard using copy-to-clipboard;

import React , {useState} from 'react';
import {Tabs} from 'antd';
import ColorSlider from './ColorSlider';
import ColorValue from './ColorValue';
import ColorCard from './ColorCard';
import colorplateConfig from '.. /.. /configs/colorplate.config';
import {HexToRGB} from '.. /.. /utils/utils'
import './index.css';
const { TabPane } = Tabs;
export default props => {
    const [color,setColor] = useState('#69c0ff');
    const [rgb,setRGB] = useState(HexToRGB(color).format);
		
  	// The color setting function
    const handleSetColor = color= >{
        setColor(color);
        let rgb = HexToRGB(color); //hex converts the RGB function to hex to get the RGB color
        setRGB(rgb.format)
    }
    return (
        <div className='colorplate-wrapper'>
            <div className='color-showing' style={{backgroundColor:color}}></div>
            <div className='colorplate'>
                <div className='color-value'>
                    <ColorValue value={color} />
                    <ColorValue value={rgb} />
                </div>
                <div className='colorslider'>
                    <Tabs defaultActiveKey='ant' >
                        <TabPane tab='Ant' key='ant'>
                            {colorplateConfig.ant.map((item,index)=>(
                                <ColorSlider 
                              		key={index} 
                            			slider={item} 
																	setColor={handleSetColor} 
																/>
                            ))}
                        </TabPane>
                        <TabPane tab='ColorTale' key='colortale'>
                            <div className='colorcard-contianer'>
                                {colorplateConfig.colortable.map((item,index)=>(
                                    <ColorCard 
                                  	  key={index} 
                                		  colorTable={item} 
																		  setColor={handleSetColor} />
                                ))}
                            </div>
                        </TabPane>
                    </Tabs>
                </div>
            </div>
        </div>
    )
}
Copy the code

Here we divide the color block into a component
, exposing the color parameter slider and the color linkage function setColor; ColorCard /> similarly, it classifies colors with themes;
is used to display ColorValue components and also provides copy-to-clipboard functionality;

React react uses a key as a display key and does not modify the component. React uses a key as a display key and does not modify the component.

Gradient tool

First above:

Gradient tool, adjust the property of linear gradient linear gradient (linear gradient is used more in practice); The tool provides four functions: add or subtract colors, adjust gradient angles, adjust color ratios, reset and copy gradient color values;

Plus button, you can add color, the default is white, can add up to 5 colors; The second Angle button can adjust the Angle of the color, the gear button can adjust the proportion of each color;

To change the current color value, click the small circle of the color. Here we use the React-color component.

The gradient value is a string, such as: ‘Linear-gradient (120deg,# A1C4FD 0%,# C2e9FB 100%)’, which has the advantage that the data can be directly used to render the component without processing. When processing the color, the string needs to be converted into the form of an object for easy processing.

Two core functions:

// Resolve gradients as objects
const exactGradientToObj = (gradient) = >{
    let gradientArray = gradient.
    replace('linear-gradient'.' ').replace(/[(|)]/g.' ').split(', ');
  	// Separate the color array, the color includes the color value and the percentage
    let colors = gradientArray.filter((item,index) = >index).map(color= >{
        color = color.split(' ');
        return {color:color[0].percent:color[1]}});return {
        angle:gradientArray[0].// Angle is the whole parameter, listed separately
        colors
    }
};

// Parse the gradient to a string
const exactGradientToStr = gradientObj= >{
    let colorsArray = gradientObj.colors.map(item= >`${item.color} ${item.percent}`);
    return 'linear-gradient(' + [gradientObj.angle,...colorsArray].join(', ') + ') ';
}
Copy the code

The resolution to the object is for the subsequent modification of related color operations. At the same time, the binding value of the button is resolved from the object, so when the object is modified, the corresponding value of the button will also be linked to change; The reverse solution object is a string, so that the color can be preview in real time, because the preview circle style is bound to the gradient string. So these two functions, in the subsequent color related modification, will be used, which solves the real-time preview and data linkage problem; For example, to modify a gradient (click on the small circle to modify it) :

    // Change the color
    const changeColor = (color,index) = >{
        let _color = ' ';
        const {hex,rgb} = color;
        if(rgb.a < 1){
            _color = `rgba(${rgb.r}.${rgb.g}.${rgb.b}.${rgb.a}) `;
        }
        else{_color = hex; } gradientObj.colors[index].color = _color; handleChangeGradientObj(gradientObj); setGradient(exactGradientToStr(gradientObj)); }Copy the code

The value of the RGB field in the react-color return value is less than 1. If the value is less than 1, the transparency has been adjusted. The hex color cannot reflect the transparency information. So I’m going to use RGBA;

Because you can add up to 5 colors (in fact, you can add at will, but I am a little lazy to calculate the problem of increasing the color ratio), yes, it is 5, who has nothing to add so many colors. . So solidify the proportions of each color:

const GRADIENT_RULE = {
    2: ['0%'.'100%'].3: ['0%'.'50%'.'100%'].4: ['0%'.'25%'.'50%'.'100%'].5: ['0%'.'13%'.'25%'.'50%'.'100%']};// Set the color percentage
const setColorPercent = (colors) = >{
    let percentArray = GRADIENT_RULE[colors.length];
    if(! percentArray){return false;
    }
    return colors.map((item,index) = >{
        item.percent = percentArray[index];
        returnitem; })}Copy the code

When adding or subtracting colors, the configuration table will be searched according to the length of the color array, and the corresponding scale array will be returned when matching.

summary

The code is not complex, but I deliberately used hooks(only a little 😜) to keep myself learning.

Welcome to experience: ColorTools