@hzy1123581324/z-view-ui
Version:
z-view-ui是使用vue3开发的组件,开发中,有部分组件功能未实现,慎用
224 lines (206 loc) • 7.47 kB
JavaScript
import {isElement} from "test.js";
/**
* 求两个颜色之间的渐变值
* @param {string} startColor 开始的颜色
* @param {string} endColor 结束的颜色
* @param {number} step 颜色等分的份额
* */
export function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) {
let startRGB = hexToRgb(startColor, false); //转换为rgb数组模式
let startR = startRGB[0];
let startG = startRGB[1];
let startB = startRGB[2];
let endRGB = hexToRgb(endColor, false);
let endR = endRGB[0];
let endG = endRGB[1];
let endB = endRGB[2];
let sR = (endR - startR) / step; //总差值
let sG = (endG - startG) / step;
let sB = (endB - startB) / step;
let colorArr = [];
for (let i = 0; i < step; i++) {
//计算每一步的hex值
let hex = rgbToHex('rgb(' + Math.round((sR * i + startR)) + ',' + Math.round((sG * i + startG)) + ',' + Math.round((sB *
i + startB)) + ')');
colorArr.push(hex);
}
return colorArr;
}
// 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
export function hexToRgb(sColor, str = true) {
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
sColor = sColor.toLowerCase();
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
let sColorNew = "#";
for (let i = 1; i < 4; i += 1) {
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
}
sColor = sColorNew;
}
//处理六位的颜色值
let sColorChange = [];
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2)));
}
if(!str) {
return sColorChange;
} else {
return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`;
}
} else if (/^(rgb|RGB)/.test(sColor)) {
let arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",")
return arr.map(val => Number(val));
} else {
return sColor;
}
};
// 将rgb表示方式转换为hex表示方式
export function rgbToHex(rgb) {
let _this = rgb;
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
if (/^(rgb|RGB)/.test(_this)) {
let aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
let strHex = "#";
for (let i = 0; i < aColor.length; i++) {
let hex = Number(aColor[i]).toString(16);
hex = String(hex).length == 1 ? 0 + '' + hex : hex; // 保证每个rgb的值为2位
if (hex === "0") {
hex += hex;
}
strHex += hex;
}
if (strHex.length !== 7) {
strHex = _this;
}
return strHex;
} else if (reg.test(_this)) {
let aNum = _this.replace(/#/, "").split("");
if (aNum.length === 6) {
return _this;
} else if (aNum.length === 3) {
let numHex = "#";
for (let i = 0; i < aNum.length; i += 1) {
numHex += (aNum[i] + aNum[i]);
}
return numHex;
}
} else {
return _this;
}
}
// 借助 canvas 提取图片主要 rgb 色值
export async function getImageColor(img) {
var canvas = document.createElement('canvas');
if(!isElement(img)){
let url = img;
img = document.createElement("img");
img.url = url;
await img.onload()
return getImageColor(img)
}
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext("2d");
img.crossOrigin = "Anonymous"
context.drawImage(img, 0, 0, canvas.width, canvas.height);
// 获取像素数据
var data = context.getImageData(0, 0, img.width, img.height).data;
console.log(data)
var r = 1,
g = 1,
b = 1;
// 取所有像素的平均值
for (var row = 0; row < img.height; row++) {
for (var col = 0; col < img.width; col++) {
// console.log(data[((img.width * row) + col) * 4])
if (row == 0) {
r += data[((img.width * row) + col)];
g += data[((img.width * row) + col) + 1];
b += data[((img.width * row) + col) + 2];
} else {
r += data[((img.width * row) + col) * 4];
g += data[((img.width * row) + col) * 4 + 1];
b += data[((img.width * row) + col) * 4 + 2];
}
}
}
console.log(r, g, b)
// 求取平均值
r /= (img.width * img.height);
g /= (img.width * img.height);
b /= (img.width * img.height);
// 将最终的值取整
r = Math.round(r);
g = Math.round(g);
b = Math.round(b);
console.log(r, g, b)
return [r, g, b]
}
// 将rgb色转位hsl色并增强 s,l值
export function rgbtohsl(rgb) {
let r = rgb[0] / 255;
let g = rgb[1] / 255;
let b = rgb[2] / 255;
var min = Math.min(r, g, b);
var max = Math.max(r, g, b);
var l = (min + max) / 2;
var difference = max - min;
var h, s, l;
if (max == min) {
h = 0;
s = 0;
} else {
s = l > 0.5 ? difference / (2.0 - max - min) : difference / (max + min);
switch (max) {
case r:
h = (g - b) / difference + (g < b ? 6 : 0);
break;
case g:
h = 2.0 + (b - r) / difference;
break;
case b:
h = 4.0 + (r - g) / difference;
break;
}
h = Math.round(h * 60);
}
s = Math.round(s * 100 * 1.5)+ '%'; //转换成百分比的形式
l = Math.round(l * 100 * 0.8)+ '%';
const str = "hsl(" + h + "," + s + "," + l + ")";
console.log('str', str)
return str
}
// r,g,b的值作为互补色调
export function getRevertColor(r, g, b) {
return {
r: 255 - r,
g: 255 - g,
b: 255 - b
};
}
// 一个比较通用也比较简单的办法就是将图片每一个像素点的r,g,b通道的值分别累加,然后分别用累加的r,g,b的值除以图片总像素点的个数,分别得到一个平均的r,g,b值并作为图片主色调的rgb值,下面是代码:当然这种方法其实还是有缺陷的,因为这里计算主色调的时候并没有考虑alpha通道的值,有兴趣的朋友可以在此基础上实现更完美的主色调和互补色提取。
// const img = new Image();
// img.onload = function() {
// const { width, height } = img;
// const scaleRect = width * height;
// let sum_r = 0, sum_g = 0, sum_b = 0;
// canvas.width = width;
// canvas.height = height;
// ctx.drawImage(img, 0, 0);
// const imgData = ctx.getImageData(0,0, canvas.width, canvas.height);
// for (let i=0; i<imgData.data.length; i+=4) {
// const r = imgData.data[i];
// const g = imgData.data[i+1];
// const b = imgData.data[i+2];
// sum_r += r;
// sum_g += g;
// sum_b += b;
// }
// const avg_r = Math.round(sum_r / scaleRect);
// const avg_g = Math.round(sum_g / scaleRect);
// const avg_b = Math.round(sum_b / scaleRect);
// // 主色调
// const mainColor = `rgb(${avg_r}, ${avg_g}, ${avg_b})`;
// }
// img.src = 'xx.png';