react实现hsl颜色选择器调节效果代码

代码语言:html

所属分类:选择器

代码描述:react实现hsl颜色选择器调节效果代码

代码标签: react hsl 颜色 选择器 调节

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">

<style>
    @import url("https://fonts.googleapis.com/css?family=Roboto:300,400");
html {
  background-color: #020202;
  font-family: "Roboto", sans-serif;
}

#container {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}

#footer {
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

#footer div {
  color: #aaa;
  padding: 20px;
  font-size: 15px;
  box-sizing: border-box;
  font-weight: 300;
  text-align: center;
  width: 360px;
}

@media only screen and (min-width: 1080px) and (min-height: 500px) {
  #footer {
    position: fixed;
    bottom: 50px;
    left: 10%;
    right: 10%;
    flex-direction: row;
  }

  #footer div {
    width: auto;
  }
}
svg {
  fill: none;
  stroke-width: 20px;
}

.marker {
  stroke-width: 40px;
}

text {
  font-size: 90px;
  stroke-width: 5px;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

.label {
  font-size: 25px;
  stroke-width: 0;
}
</style>
</head>
<body>
<!-- partial:index.partial.html -->
<div id="app">Loading...</div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react.15.4.2.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react-dom.15.4.2.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/rx.all.2.3.22.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/redux.3.6.0.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/react-redux.5.0.2.js"></script><script >
    /*********
Display: React,
Event handling: Reactive JS
Status handling: Redux
**********/

/*********
* REACT
**********/
const Container = ({ hue, saturation, lightness, red, green, blue, hex, setHue, setSaturation, setLightness }) => {
  return /*#__PURE__*/React.createElement("div", { id: "container" }, /*#__PURE__*/
  React.createElement(Hue, { hue: hue, saturation: saturation, lightness: lightness, setHue: setHue }), /*#__PURE__*/
  React.createElement(Saturation, { hue: hue, saturation: saturation, lightness: lightness, setSaturation: setSaturation }), /*#__PURE__*/
  React.createElement(Lightness, { hue: hue, saturation: saturation, lightness: lightness, setLightness: setLightness }), /*#__PURE__*/
  React.createElement("div", { id: "footer" }, /*#__PURE__*/
  React.createElement("div", null,
  `hsl(${hue}, ${saturation}%, ${lightness}%)`), /*#__PURE__*/

  React.createElement("div", null,
  `rgb(${red}, ${green}, ${blue})`), /*#__PURE__*/

  React.createElement("div", null,
  hex)));



};

class Hue extends React.Component {
  constructor({ hue, saturation, lightness, setHue }) {
    super({ hue, saturation, lightness, setHue });

    const padding = 60;
    const innerSize = 300;
    this.radius = innerSize / 2;
    this.outterSize = innerSize + padding;
    this.centerOffset = this.outterSize / 2;

    this.state = {
      dragging: false };


    // These are set in the render method
    this.canvas = null;
    this.selector = null;
  }

  render() {
    return /*#__PURE__*/(
      React.createElement("svg", { ref: canvas => {this.canvas = canvas;},
        width: this.outterSize, height: this.outterSize,
        viewBox: `0 0 ${this.outterSize} ${this.outterSize}`,
        xmlns: "http://www.w3.org/2000/svg", version: "1.1" }, /*#__PURE__*/
      React.createElement("g", { transform: `translate(${this.centerOffset},${this.centerOffset})` },
      Array.from({ length: 360 }, (value, key) => /*#__PURE__*/
      React.createElement(HueSlice, {
        degree: key,
        radius: this.radius,
        color: `hsl(${key}, ${this.props.saturation}%, ${this.props.lightness}%)`,
        marker: false })), /*#__PURE__*/

      React.createElement("g", { ref: selector => {this.selector = selector;} }, /*#__PURE__*/
      React.createElement(HueSlice, {
        degree: this.props.hue,
        radius: this.radius,
        color: this.state.dragging ? `hsl(${this.props.hue}, ${this.props.saturation}%, ${this.props.lightness}%)` : "white",
        marker: true })), /*#__PURE__*/

      React.createElement("text", {
        x: "10",
        y: "30",
        textAnchor: "middle",
        fill: `hsl(${this.props.hue}, ${this.props.saturation}%, ${this.props.lightness}%)`,
        stroke: `hsl(${this.props.hue}, ${this.props.saturation}%, ${this.props.lightness}%)` },
      this.props.hue, "\xB0"), /*#__PURE__*/

      React.createElement("text", {
        className: "label",
        x: "0",
        y: "60",
        textAnchor: "middle",
        fill: `hsl(${this.props.hue}, ${this.props.saturation}%, ${this.props.lightness}%)`,
        stroke: `hsl(${this.props.hue}, ${this.props.saturation}%, ${this.props.lightness}%)` }, "Hue"))));






  }

  componentDidMount() {
    // Event handling using Reactive JS
    let mouseDowns = Rx.Observable.fromEvent(this.selector, "mousedown");
    let mouseMoves = Rx.Observable.fromEvent(this.canvas, "mousemove");
    let mouseUps = Rx.Observable.fromEvent(this.canvas, "mouseup");
    let mouseLeaves = Rx.Observable.fromEvent(this.canvas, "mouseleave");

    let touchStarts = Rx.Observable.fromEvent(this.selector, "touchstart");
    let touchMoves = Rx.Observable.fromEvent(this.selector, "touchmove");
    let touchEnds = Rx.Observable.fromEvent(this.canvas, "touchend");

    let mouseDrags = mouseDowns.concatMap(clickEvent => {
      const xMouseShouldBe = Math.sin(this.props.hue / 180 * Math.PI) * this.radius;
      const yMouseShouldBe = -Math.cos(this.props.hue / 180 * Math.PI) * this.radius;
      const xMouseIs = clickEvent.clientX;
      const yMouseIs = clickEvent.clientY;
      const xMouseDelta = xMouseIs - xMouseShouldBe;
      const yMouseDelta = yMouseIs - yMouseShouldBe;
      return mouseMoves.takeUntil(mouseUps.merge(mouseLeaves)).map(moveEvent => {
        const xRelativeToCenter = moveEvent.clientX - xMouseDelta;
        const yRelativeToCenter = moveEvent.clientY - yMouseDelta;
        const degree = Math.atan(yRelativeToCenter / xRelativeToCenter) * 180 / Math.PI + 90 + (xRelativeToCenter >= 0 ? 0 : 180);
        return parseInt(degree);
      });
    });

    let touchDrags = touchStarts.concatMap(startEvent => {
      startEvent.preventDefault();
      const xTouchShouldBe = Math.sin(this.props.hue / 180 * Math.PI) * this.radius;
      const yTouchShouldBe = -Math.cos(this.props.hue / 180 * Math.PI) * this.radius;
      const xTouchIs = startEvent.touches[0].clientX;
      const yTouchIs = startEvent.touches[0].clientY;
      const xTouchDelta = xTouchIs - xTouchShouldBe;
      const yTouchDelta = yTouchIs - yTouchShouldBe;
      return touchMoves.takeUntil(touchEnds).map(moveEvent => {
        moveEvent.preventDefault();
        const xRelativeToCenter = moveEvent.touches[0].clientX - xTouchDelta;
        const yRelativeToCenter = moveEvent.touches[0].clientY - yTouchDelta;
        const degree = Math.atan(yRelativeToCenter / xRelativeToCenter) * 180 / Math.PI + 90 + (xRelativeToCenter >= 0 ? 0 : 180);
        return parseInt(degree);
      });
    });

    let dragStarts = mouseDowns.merge(touchStarts);
    let drags = mouseDrags.merge(touchDrags);
    let dragEnds = mouseUps.merge(mouseLeaves).merge(touchEnds);

    dragStarts.forEach(() => {
      this.setState({ dragging: true });
    });

    drags.forEach(degree => {
      this.props.setHue(degree);
    });

    dragEnds.forEach(() => {
      this.setState({ dragging: false });
    });
  }}


const HueSlice = ({ degree, color, radius, marker }) => {
  const thickness = marker ? 5 : 1;
  const startX = Math.sin((degree - thickness) / 180 * Math.PI) * radius;
  const startY = -Math.cos((degree - thickness) / 180 * Math.PI) * radius;
  const endX = Math.sin((degree + thickness) / 180 * Math.PI) * radius;
  const endY = -Math.cos((degree + thickness) / 180 * Math.PI) * radius;
  return /*#__PURE__*/React.createElement("path", {
    className: marker && 'marker',
    d: `M ${startX} ${startY} A ${radius} ${radius} 0 0 1 ${endX} ${endY}`,
    stroke: color });
};

const Saturation = ({ hue, saturation, lightness, setSaturation }) => {
  const gradient = /*#__PURE__*/React.createElement("linearGradient", { id: "Saturation", x1: "0", x2: "0", y1: "0", y2: "1" }, /*#__PURE__*/
  React.createElement("stop", { offset: "0%", stopColor: `hsl(${hue}, 100%, ${lightness}%)` }), /*#__PURE__*/
  React.createElement("stop", { offset: "100%", stopColor: `hsl(${hue}, 0%, ${lightness}%.........完整代码请登录后点击上方下载按钮下载查看

网友评论0