react实现hsl颜色选择器调节效果代码
代码语言:html
所属分类:选择器
代码描述: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