美文网首页
原生JS实现 color picker 颜色选择器(canvas

原生JS实现 color picker 颜色选择器(canvas

作者: Allan要做活神仙 | 来源:发表于2019-03-07 15:34 被阅读0次

    2019-03-07-15:32于公司:
    最近在搞TMS,碰到了颜色选择器,想了解下用原生JS如何实现。记录下:

    效果如下:


    image.png

    先上源码稍后来分析,到时候搞成react版本

    <!DOCTYPE html>
    <html lang="zh">
     
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>Document</title>
            <style>
                body {
                    background: #535353;
                    padding: 0;
                    margin: 0;
                }
                 
                canvas {
                    cursor: crosshair;
                }
                 
                #cur {
                    width: 3px;
                    height: 3px;
                    outline: 2px solid #535353;
                    margin-left: -1px;
                    margin-top: -1px;
                    position: absolute;
                }
                 
                .wrapper {
                    position: relative;
                }
                 
                #color_show {
                    width: 50px;
                    height: 50px;
                    background: #f00;
                }
                 
                .panel {
                    width: 200px;
                    height: 200px;
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background-color: #fff;
                    padding: 10px;
                    text-align: center;
                    line-height: 2em;
                }
            </style>
        </head>
     
        <body>
            <div class="wrapper">
                <canvas id="canvas" width="600" height="600"></canvas>
                <em id="cur"></em>
                <div class="panel">
                    <div id="color_show"></div>
                    <label>
                rgb <input type="text"  class="color_input" value="" id="rgb_value">
            </label><br>
                    <label>
                hex <input type="text"  class="color_input" value="" id="hex_value">
            </label>
                </div>
            </div>
            <script>
                (function() {
                    var width = 256;
                    var can = document.getElementById('canvas');
                    var ctx = can.getContext('2d');
                    var curColor = 'rgba(255,0,0,1)';
                    var cur = document.getElementById('cur');
                    var rgbValue = document.getElementById('rgb_value');
                    var hexValue = document.getElementById('hex_value');
                    var colorShow = document.getElementById('color_show');
     
                    var aColorInput = document.getElementsByClassName('color_input');
     
                    function colorBar() {
                        var 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);
                    }
     
                    function rgb2hex(rgb) {
                        var aRgb = rgb instanceof Array ? rgb : (rgb.split(',') || [0, 0, 0]);
                        var temp;
                        return [
                            (temp = Number(aRgb[0]).toString(16)).length == 1 ? ('0' + temp) : temp,
                            (temp = Number(aRgb[1]).toString(16)).length == 1 ? ('0' + temp) : temp,
                            (temp = Number(aRgb[2]).toString(16)).length == 1 ? ('0' + temp) : temp,
                        ].join('');
                    }
     
                    function hex2rgb(hex) {
                        if(hex.length == 3) {
                            hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
                        }
                        return [
                            parseInt(hex[0] + hex[1], 16),
                            parseInt(hex[2] + hex[3], 16),
                            parseInt(hex[4] + hex[5], 16),
                        ].join();
                    }
     
                    function putCurDom(color) {
                        if(/([0-9a-f]{3}|[0-9a-f]{6})/i.test(color)) {
                            // hex
                            color = hex2rgb(color);
                        } else if(color instanceof Array) {
                            color = color.join(',');
                        } else if(/\d{1,3}(\,\d{1,3}){2}/i.test(color)) {
     
                        } else {
                            return;
                        }
                    }
     
                    function colorBox(color) {
                        // 底色填充,也就是(举例红色)到白色
                        var 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);
                        // 第二次填充,黑色到透明
                        var my_gradient1 = ctx.createLinearGradient(0, 0, 0, width);
                        my_gradient1.addColorStop(0, 'rgba(0,0,0,0)');
                        my_gradient1.addColorStop(1, 'rgba(0,0,0,1)');
                        ctx.fillStyle = my_gradient1;
                        ctx.fillRect(30, 0, width, width);
                    }
     
                    function init() {
                        colorBar();
                        colorBox(curColor);
                        bind();
                    }
     
                    function bind() {
                        can.addEventListener('click', function(e) {
                            var ePos = {
                                x: e.offsetX || e.layerX,
                                y: e.offsetY || e.layerY
                            }
                            var rgbaStr = '#000';
                            if(ePos.x >= 0 && ePos.x < 20 && ePos.y >= 0 && ePos.y < width) {
                                // in
                                rgbaStr = getRgbaAtPoint(ePos, 'bar');
                                colorBox('rgba(' + rgbaStr + ')');
                            } else if(ePos.x >= 30 && ePos.x < 30 + width && ePos.y >= 0 && ePos.y < width) {
                                rgbaStr = getRgbaAtPoint(ePos, 'box');
                            } else {
                                return;
                            }
                            outColor(rgbaStr.slice(0, 3).join());
                            cur.style.left = ePos.x + 'px';
                            cur.style.top = ePos.y + 'px';
                            cur.style.outlineColor = (rgbaStr[0] > 256 / 2 || rgbaStr[1] > 256 / 2 || rgbaStr[2] > 256 / 2) ? '#000' : '#fff';
                        });
     
                        can.addEventListener('mousedown', function(e) {
                            var ePos = {
                                x: e.layerX || e.offsetX,
                                y: e.layerY || e.offsetY
                            }
                            if(ePos.x >= 30 && ePos.x < 30 + width && ePos.y >= 0 && ePos.y < width) {
                                document.onmousemove = function(e) {
                                    var pos = {
                                        x: e.clientX,
                                        y: e.clientY
                                    }
     
                                    pos.x = pos.x < 30 ? 30 : pos.x && (pos.x > (30 + width - 1) ? (30 + width - 1) : pos.x);
                                    pos.y = pos.y < 0 ? 0 : pos.y && (pos.y > (width - 1) ? (width - 1) : pos.y);
     
                                    rgbaStr = getRgbaAtPoint(pos, 'box');
                                    cur.style.left = pos.x + 'px';
                                    cur.style.top = pos.y + 'px';
                                    cur.style.outlineColor = (rgbaStr[0] > 256 / 2 || rgbaStr[1] > 256 / 2 || rgbaStr[2] > 256 / 2) ? '#000' : '#fff';
                                    outColor(rgbaStr.slice(0, 3).join());
                                };
                                document.onmouseup = function() {
                                    // outColor(rgbaStr.slice(0, 3).join());
                                    document.onmouseup = document.onmousemove = null;
                                }
                            }
     
                        });
                    }
     
                    function outColor(rgb) {
                        rgbValue.value = rgb;
                        hexValue.value = rgb2hex(rgb);
                        colorShow.style.backgroundColor = 'rgb(' + rgb + ')';
                    }
     
                    function getRgbaAtPoint(pos, area) {
                        if(area == 'bar') {
                            var imgData = ctx.getImageData(0, 0, 20, width);
                        } else {
                            var imgData = ctx.getImageData(0, 0, can.width, can.height);
                        }
     
                        var data = imgData.data;
                        var dataIndex = (pos.y * imgData.width + pos.x) * 4;
                        return [
                            data[dataIndex],
                            data[dataIndex + 1],
                            data[dataIndex + 2],
                            (data[dataIndex + 3] / 255).toFixed(2),
                        ];
                    }
     
                    init();
                })()
            </script>
        </body>
     
    </html>
    

    相关文章

      网友评论

          本文标题:原生JS实现 color picker 颜色选择器(canvas

          本文链接:https://www.haomeiwen.com/subject/awgcpqtx.html