js实现拾色器————color-picker
undefined
实现效果
react 版本示例
jsx部分
import "./styles.css";
import React, { useEffect, useRef, useState } from "react";
export default () => {
const can = useRef(null);
const cur = useRef(null);
const width = 256;
const curColor = "rgba(255,0,0,1)";
const [rgbValue, setRgbValue] = useState([]);
const colorBar = () => {
const ctx = can.current.getContext("2d");
const gradientBar = ctx.createLinearGradient(0, 0, 0, width);
gradientBar.addColorStop(0, "#f00");
gradientBar.addColorStop(1 / 6, "#f0f");
gradientBar.addColorStop(2 / 6, "#00f");
gradientBar.addColorStop(3 / 6, "#0ff");
gradientBar.addColorStop(4 / 6, "#0f0");
gradientBar.addColorStop(5 / 6, "#ff0");
gradientBar.addColorStop(1, "#f00");
ctx.fillStyle = gradientBar;
ctx.fillRect(0, 0, 20, width);
};
const colorBox = (color) => {
const ctx = can.current.getContext("2d");
// 底色填充,也就是(举例红色)到白色
const gradientBase = ctx.createLinearGradient(30, 0, width + 30, 0);
gradientBase.addColorStop(1, color);
gradientBase.addColorStop(0, "rgba(255,255,255,1)");
ctx.fillStyle = gradientBase;
ctx.fillRect(30, 0, width, width);
// 第二次填充,黑色到透明
const gradientScreen = ctx.createLinearGradient(0, 0, 0, width);
gradientScreen.addColorStop(0, "rgba(0,0,0,0)");
gradientScreen.addColorStop(1, "rgba(0,0,0,1)");
ctx.fillStyle = gradientScreen;
ctx.fillRect(30, 0, width, width);
};
useEffect(() => {
colorBar();
colorBox(curColor);
can.current.addEventListener("click", (e) => {
const coorX = e.offsetX || e.layerX;
const coorY = e.offsetY || e.layerY;
const ctx = can.current.getContext("2d");
const imgData = ctx.getImageData(coorX, coorY, 1, 1);
const { data } = imgData;
const rgbaStr = [data[0], data[1], data[2]];
setRgbValue(rgbaStr);
if (coorX && coorX < 20 && coorY >= 0 && coorY < width) {
colorBox(`rgba(${rgbaStr.join(",")})`);
}
// onChange(rgbaStr)
cur.current.style.left = `${coorX}px`;
cur.current.style.top = `${coorY}px`;
// 128===256/2 亮色边框用黑色, 暗色用白色
cur.current.style.outlineColor =
rgbaStr[0] > 128 || rgbaStr[1] > 128 || rgbaStr[2] > 128
? "#000"
: "#fff";
});
}, []);
return (
<div className="colorPicker">
<div className="wrapper">
<canvas className="canvas" width="300" height="300" ref={can} />
<em className="cur" ref={cur} />
</div>
<div>
预览颜色: rgb({rgbValue.join(",")})
{rgbValue.length === 3 && (
<div
style={{
height: 50,
width: 50,
background: `rgba(${rgbValue.join(",")})`
}}
/>
)}
</div>
</div>
);
};
css部分
.colorPicker {
width: 300px;
height: 300px;
background: #fff;
padding: 8px;
z-index: 10;
margin-bottom: 8px;
}
.canvas {
cursor: crosshair;
}
.cur {
width: 3px;
height: 3px;
margin-left: -1px;
margin-top: -1px;
outline: 2px solid rgba(0, 0, 0, 0);
position: absolute;
}
.wrapper {
position: relative;
}
html 原生版
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix