前端如何在30秒内实现吸管拾色器?_前端框架

⭐前言

大家好,我是yma16,本文分享 前端react——实现浏览器页面的吸管拾色器功能。

背景

在chrome web端快速实现一个页面的取色器功能, 分为两个场景

  1. 固定区域小范围取色
  2. 当前页面取色

⭐canvas 实现区域范围的取色器

  1. 原理使用canvas的createLinearGradient绘制渐变区域
  2. 监听点击坐标值,使用canvas的getImageData获取像素颜色值
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="style.css" rel="stylesheet" type="text/css" />
    <title>InsCode</title>
</head>

<body>
    <div class="container">
        <img src="src/assets/logo.svg" alt="InsCode">
        <div>欢迎来到 InsCode</div>

        <p>Choose your monster's colors:</p>

    </div>

    <div>
        demo1  固定区域的颜色范围
        <div class="color-picker">
            <canvas id="colorCanvas" width="300" height="300"></canvas>
            <p id="colorValue">#000000</p>
        </div>

    </div>

    <script src="script.js"></script>
</body>

</html>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

js逻辑部分

const demoOne=()=>{
    const canvas = document.getElementById('colorCanvas');
    const ctx = canvas.getContext('2d');
    const colorValue = document.getElementById('colorValue');

    // 创建渐变颜色盘
    const createGradient = () => {
        const width = canvas.width;
        const height = canvas.height;

        // 创建水平渐变
        const gradientH = ctx.createLinearGradient(0, 0, width, 0);
        gradientH.addColorStop(0, 'red');
        gradientH.addColorStop(0.16, 'yellow');
        gradientH.addColorStop(0.33, 'green');
        gradientH.addColorStop(0.5, 'cyan');
        gradientH.addColorStop(0.66, 'blue');
        gradientH.addColorStop(0.83, 'magenta');
        gradientH.addColorStop(1, 'red');
        ctx.fillStyle = gradientH;
        ctx.fillRect(0, 0, width, height);

        // 创建垂直渐变
        const gradientV = ctx.createLinearGradient(0, 0, 0, height);
        gradientV.addColorStop(0, 'rgba(255,255,255,1)');
        gradientV.addColorStop(0.5, 'rgba(255,255,255,0)');
        gradientV.addColorStop(0.5, 'rgba(0,0,0,0)');
        gradientV.addColorStop(1, 'rgba(0,0,0,1)');
        ctx.fillStyle = gradientV;
        ctx.fillRect(0, 0, width, height);
    };

    // 获取选中的颜色
    const pickColor = (event) => {
        const x = event.offsetX;
        const y = event.offsetY;
        const imageData = ctx.getImageData(x, y, 1, 1).data;
        const r = imageData[0];
        const g = imageData[1];
        const b = imageData[2];
        const hex = `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase()}`

        colorValue.textContent = hex;
        document.body.style.backgroundColor = hex;
    };

    // 初始化颜色盘
    createGradient();

    // 添加事件监听器
    canvas.addEventListener('click', pickColor);
}

const demoTwo=()=>{
    const canvas = document.getElementById('colorPickerCanvas');
    const ctx = canvas.getContext('2d');
    
    let isMouseDown = false;
    let colorValueInput = document.getElementById('colorValue');
    
    // 初始化画布
    function initCanvas() {
        // 填充画布背景为白色
        ctx.fillStyle = '#fff';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    }
    
    // 鼠标按下事件
    canvas.addEventListener('mousedown', function(event) {
        isMouseDown = true;
        handleColorPick(event);
    });
    
    // 鼠标移动事件
    canvas.addEventListener('mousemove', function(event) {
        if (isMouseDown) {
            handleColorPick(event);
        }
    });
    
    // 鼠标抬起事件
    canvas.addEventListener('mouseup', function() {
        isMouseDown = false;
    });
    
    // 取色函数
    function handleColorPick(event) {
        let rect = canvas.getBoundingClientRect();
        let x = event.clientX - rect.left;
        let y = event.clientY - rect.top;
    
        let imageData = ctx.getImageData(x, y, 1, 1).data;
        let color = `rgb(${imageData[0]}, ${imageData[1]}, ${imageData[2]})`;
        colorValueInput.value = color;
    }
    
    // 重置画布
    function resetCanvas() {
        initCanvas();
        colorValueInput.value = '';
    }
    
    initCanvas();
}

const demoCanvas=()=>{

    // 点击吸管工具
    document.getElementById('color-pick-button').addEventListener('click',(e)=>{
        console.log('color-pick-button',e)
        const canvas = document.getElementById("colorPickerCanvas");
        config.cavansDom = canvas
        if (canvas.getContext) {
            const ctx = canvas.getContext("2d");
            // background
            ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
            ctx.globalAlpha = 1
            ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height)
            const img = new Image();
            img.onload = function () {
                ctx.drawImage(img, 35, 0);
            };
            img.src = "/src/assets/csdn.png";
    
        }
        else {
            console.log('不支持canvas')
        }
    })

}

window.onload = () => {
    demoOne()
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.

效果如下:

前端如何在30秒内实现吸管拾色器?_Data_02

⭐30秒快速实现浏览器页面的吸管拾色器

原生的 color 输入自带 拾色器
标签用法

<input type="color">
  • 1.

效果如下

前端如何在30秒内实现吸管拾色器?_性能监控_03

💖原色color输入如何调用的拾色器

color输入使用了浏览器的EyeDropper apiEyeDropper api
文档: https://developer.mozilla.org/zh-CN/docs/Web/API/EyeDropper react 简单调用

// @ts-ignore
import { Button ,message} from "tdesign-react";
import {useRef} from 'react'
const ColorDemo=()=>{

  const divRef=useRef(null)
  const openColorPicker=()=>{
    //@ts-ignore
    if (!window.EyeDropper) {
      message.warning("你的浏览器不支持 EyeDropper API")
      return;
    }
    //@ts-ignore
    const eyeDropper = new EyeDropper();

    eyeDropper
      .open()
      .then((result:any) => {
        console.log('result.sRGBHex',result.sRGBHex)
        //@ts-ignore
        divRef.current.style.background=result.sRGBHex
      })
      .catch((e:any) => {
        console.error(e)
      });
  };
  return <>
  color picker
<div>

  <div ref={divRef} style={{width:'200px',height:'200px',background:'blue',border:'1px solid #dcdcdc',margin:'0 auto'}}>

  </div>
<br/>
  <Button onClick={openColorPicker}>打开拾色器</Button>
</div>
  </>
}
export default ColorDemo;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.

效果如下:

前端如何在30秒内实现吸管拾色器?_性能监控_04

兼容性: 仅仅支持chrome 和 edge

前端如何在30秒内实现吸管拾色器?_前端_05

⭐结束

本文分享到这结束,如有错误或者不足之处欢迎指出!

前端如何在30秒内实现吸管拾色器?_性能监控_06

👍 点赞,是我创作的动力!

⭐️ 收藏,是我努力的方向!

✏️ 评论,是我进步的财富!

💖 最后,感谢你的阅读!