有趣且重要的JS知识合集(16)图片颜色选择器

这属于有趣的小功能,其实很多站点都已经提供了此功能了噢,不过我这里还是写一写~

效果展示

图片上传后,任意点击图片提取点击处颜色的rgba格式和十六进制格式

页面结构

canvas:为图片上传后展示canvas使用

id为color:提取出来的颜色框

id为text:rgba和十六进制的颜色

          <div class="container">
            <canvas id="cvs"></canvas>
            <button @click="doInput">上传</button>
            <div class="container">
              <div id="color"></div>
              <div id="text"></div>
            </div>
          </div>

代码展示

<script>
export default {
        data() {
          return {
            cvs: null,
            ctx: null
          };
        },
      methods:{
        const _this = this
        pick(event) {
            // 获取鼠标坐标
            let x = event.layerX;
            let y = event.layerY;

            // 获取图片像素信息
            let pixel = this.ctx.getImageData(x, y, 1, 1);
            let data = pixel.data;

            // 获取rgba值
            let rgba = 'rgba(' + data[0] + ',' + data[1] +',' + data[2] + ',' + (data[3] / 255) + ')';

            // 设置小正方形的背景颜色
            color.style.background =rgba;

            // 把拼接的字符串设置为元素的文本内容
            text.textContent = `${rgba}; ${this.rgbaToHex(rgba)}`;
          },
          /**
           * 颜色字符串解析为颜色对象
           * @param color 颜色字符串
           * @returns IColorObj
           */
          parseColorString(color) {
            if (color.startsWith('rgb')) {
              return this.parseRgbaColor(color);
            }
            throw new Error(`color string error: ${color}`);
          },
          parseRgbaColor(rgba) {
            let values = rgba
              .replace(/rgba?\(/, '')
              .replace(/\)/, '')
              .replace(/[\s+]/g, '')
              .split(',');
              let a = parseFloat(values[3] || 1),
              r = Math.floor(a * parseInt(values[0]) + (1 - a) * 255),
              g = Math.floor(a * parseInt(values[1]) + (1 - a) * 255),
              b = Math.floor(a * parseInt(values[2]) + (1 - a) * 255);
            return "#" +
              ("0" + r.toString(16)).slice(-2) +
              ("0" + g.toString(16)).slice(-2) +
              ("0" + b.toString(16)).slice(-2);
          },
          /**
           * rgba颜色字符串转化为16进制颜色字符串
           * @param rgba rgba颜色字符串
           * @returns 16进制颜色字符串
           */
          rgbaToHex(rgba) {
            const colorObj = this.parseColorString(rgba);
            return colorObj
          },
          doInput(id) {
            const inputObj = document.createElement('input');
            inputObj.addEventListener('change', this.readFile, false);
            inputObj.type = 'file';
            inputObj.accept = 'image/*';
            inputObj.id = id;
            inputObj.click();
          },
          readFile() {
            const file = this.files[0]; // 获取input输入的图片
            if(!/image\/\w+/.test(file.type)){
                alert("请确保文件为图像类型");
                return false;
            } // 判断是否图片
            const reader = new FileReader();
            reader.readAsDataURL(file);//转化成base64数据类型
            reader.onload = function(e){
              _this.drawToCanvas(this.result); // _this指向当前组件实例
            }
          },
          drawToCanvas(imgData) {
            this.cvs = document.querySelector('#cvs');
            this.cvs.width = 300;
            this.cvs.height = 400;
            this.ctx = this.cvs.getContext('2d');
            const img = new Image;
            img.src = imgData;
            const _this = this
            img.onload = function() {//必须onload之后再画
              _this.cvs.height = img.height * _this.cvs.width / img.width
              _this.ctx.drawImage(img, 0, 0, _this.cvs.width, _this.cvs.height);
              _this.cvs.onmousedown = e => {
                _this.pick(e)
              }
            }
          }
    }
}
</script>

猜你喜欢

转载自blog.csdn.net/qq_39404437/article/details/128119403