|
|
|
@@ -31,42 +31,21 @@
|
|
|
|
></div>
|
|
|
|
></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="show-con cluster" ref="clusterCon">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="color-group"
|
|
|
|
|
|
|
|
v-for="(item, index) in clusters"
|
|
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<div class="header">
|
|
|
|
|
|
|
|
<div class="span" :style="rennderHeaderCss(item)"></div>
|
|
|
|
|
|
|
|
{{ item.name }} Group
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="color-span"
|
|
|
|
|
|
|
|
v-for="(item, index) in item.colors"
|
|
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
|
|
:style="rennderCssHex(item)"
|
|
|
|
|
|
|
|
></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="btn-groups">
|
|
|
|
<div class="btn-groups">
|
|
|
|
<!-- <div class="btn" @click="sortColor">颜色归类</div> -->
|
|
|
|
<div class="p">根据Hue色调分组</div>
|
|
|
|
<div class="first">
|
|
|
|
<div class="ios-checkbox">
|
|
|
|
<div class="p">根据Hue色调分组</div>
|
|
|
|
<input
|
|
|
|
<div class="ios-checkbox">
|
|
|
|
type="checkbox"
|
|
|
|
<input
|
|
|
|
id="ios-checkbox"
|
|
|
|
type="checkbox"
|
|
|
|
name="emulate-ios-button"
|
|
|
|
id="ios-checkbox"
|
|
|
|
class="raw-checkbox"
|
|
|
|
name="emulate-ios-button"
|
|
|
|
v-model="hideOrigin"
|
|
|
|
class="raw-checkbox"
|
|
|
|
@change="showGroup"
|
|
|
|
v-model="hideOrigin"
|
|
|
|
hidden
|
|
|
|
@change="showGroup"
|
|
|
|
/>
|
|
|
|
hidden
|
|
|
|
<label for="ios-checkbox" class="emulate-ios-button"></label>
|
|
|
|
/>
|
|
|
|
|
|
|
|
<label for="ios-checkbox" class="emulate-ios-button"></label>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- <div class="p">根据固定颜色分组</div>
|
|
|
|
<!-- <div class="p">根据固定颜色分组</div>
|
|
|
|
<div class="ios-checkbox">
|
|
|
|
<div class="ios-checkbox">
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
@@ -80,29 +59,13 @@
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<label for="ios-checkbox2" class="emulate-ios-button"></label>
|
|
|
|
<label for="ios-checkbox2" class="emulate-ios-button"></label>
|
|
|
|
</div> -->
|
|
|
|
</div> -->
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="btn"
|
|
|
|
|
|
|
|
@click="sortColorSaturation"
|
|
|
|
|
|
|
|
:class="{ active: active1 }"
|
|
|
|
|
|
|
|
ref="btn1"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
根据饱和度排序
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
<div
|
|
|
|
class="btn"
|
|
|
|
class="btn"
|
|
|
|
@click="sortColorLight"
|
|
|
|
@click="sortColorLight"
|
|
|
|
:class="{ active: active2 }"
|
|
|
|
:class="{ active: active2 }"
|
|
|
|
ref="btn2"
|
|
|
|
ref="btn2"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
根据明度排序
|
|
|
|
排序
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="show-color" ref="showColor">
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
|
|
|
class="color-span"
|
|
|
|
|
|
|
|
v-for="(item, index) in clusters"
|
|
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
|
|
:style="rennderHeaderCss(item)"
|
|
|
|
|
|
|
|
></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@@ -111,6 +74,7 @@
|
|
|
|
// @ is an alias to /src
|
|
|
|
// @ is an alias to /src
|
|
|
|
import colorUtil from "color-util";
|
|
|
|
import colorUtil from "color-util";
|
|
|
|
import colors from "@/data/color.json";
|
|
|
|
import colors from "@/data/color.json";
|
|
|
|
|
|
|
|
import Snap from "snapsvg-cjs";
|
|
|
|
import gsap from "gsap";
|
|
|
|
import gsap from "gsap";
|
|
|
|
export default {
|
|
|
|
export default {
|
|
|
|
name: "ColorSort",
|
|
|
|
name: "ColorSort",
|
|
|
|
@@ -118,38 +82,23 @@ export default {
|
|
|
|
data() {
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
hideOrigin: false,
|
|
|
|
hideOrigin: false,
|
|
|
|
hideOrigin2: false,
|
|
|
|
|
|
|
|
colorArr: colors,
|
|
|
|
colorArr: colors,
|
|
|
|
active1: false,
|
|
|
|
active1: false,
|
|
|
|
active2: false,
|
|
|
|
active2: false,
|
|
|
|
hlsColorArr: [],
|
|
|
|
hlsColorArr: [],
|
|
|
|
clustersColorArr: [],
|
|
|
|
newColorArr: [[], [], [], [], [], [], [], [], [], [], [], []],
|
|
|
|
newColorArr: [[], [], [], [], [], [], [], [], [], [], [], [], [], [], []],
|
|
|
|
sortedColorArr: [],
|
|
|
|
// 1-12 对应 hue 每30度 | 13 - 黑 | 14 - 白 | 15 - 灰
|
|
|
|
// 1-12 对应 hue 每30度 | 13 - 黑 | 14 - 白 | 15 - 灰
|
|
|
|
clusters: [
|
|
|
|
balance: [0.9, 0, 0.01],
|
|
|
|
//指定颜色分类
|
|
|
|
balance2: [0.3, 0, 0],
|
|
|
|
{ name: "red", leadColor: [255, 0, 0], colors: [] },
|
|
|
|
balance3: [0.5, 0.2, 0.1],
|
|
|
|
{ name: "orange", leadColor: [255, 128, 0], colors: [] },
|
|
|
|
caclulTime: 0,
|
|
|
|
{ name: "yellow", leadColor: [255, 255, 0], colors: [] },
|
|
|
|
|
|
|
|
{ name: "chartreuse", leadColor: [128, 255, 0], colors: [] },
|
|
|
|
|
|
|
|
{ name: "green", leadColor: [0, 255, 0], colors: [] },
|
|
|
|
|
|
|
|
{ name: "spring green", leadColor: [0, 255, 128], colors: [] },
|
|
|
|
|
|
|
|
{ name: "cyan", leadColor: [0, 255, 255], colors: [] },
|
|
|
|
|
|
|
|
{ name: "azure", leadColor: [0, 127, 255], colors: [] },
|
|
|
|
|
|
|
|
{ name: "blue", leadColor: [0, 0, 255], colors: [] },
|
|
|
|
|
|
|
|
{ name: "violet", leadColor: [127, 0, 255], colors: [] },
|
|
|
|
|
|
|
|
{ name: "magenta", leadColor: [255, 0, 255], colors: [] },
|
|
|
|
|
|
|
|
{ name: "rose", leadColor: [255, 0, 128], colors: [] },
|
|
|
|
|
|
|
|
{ name: "black", leadColor: [0, 0, 0], colors: [] },
|
|
|
|
|
|
|
|
{ name: "grey", leadColor: [235, 235, 235], colors: [] },
|
|
|
|
|
|
|
|
// { name: "white", leadColor: [255, 255, 255], colors: [] },
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
computed: {
|
|
|
|
rennderCssHSL() {
|
|
|
|
rennderCssHSL() {
|
|
|
|
return function (item) {
|
|
|
|
return function (item) {
|
|
|
|
return `background-color: ${colorUtil.hsl.to.csshsl(item)};`;
|
|
|
|
return `background-color: ${item.csshsl};`;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
rennderCssHex() {
|
|
|
|
rennderCssHex() {
|
|
|
|
@@ -159,130 +108,89 @@ export default {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
rennderHeaderCss() {
|
|
|
|
rennderHeaderCss() {
|
|
|
|
return function (item) {
|
|
|
|
return function (item) {
|
|
|
|
return `background-color: ${colorUtil.rgb.to.cssrgb({
|
|
|
|
return `background-color: ${item.csshsl};`;
|
|
|
|
r: item.leadColor[0],
|
|
|
|
|
|
|
|
g: item.leadColor[1],
|
|
|
|
|
|
|
|
b: item.leadColor[2],
|
|
|
|
|
|
|
|
a: 255,
|
|
|
|
|
|
|
|
})};`;
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
mounted() {
|
|
|
|
// console.log(this.newColorArr);
|
|
|
|
|
|
|
|
this.reHandleColor();
|
|
|
|
this.reHandleColor();
|
|
|
|
},
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
methods: {
|
|
|
|
// 显示隐藏分组
|
|
|
|
// 显示隐藏分组
|
|
|
|
showGroup(index) {
|
|
|
|
showGroup(index) {
|
|
|
|
let target = this.$refs.sortCon;
|
|
|
|
gsap.to(this.$refs.sortCon, {
|
|
|
|
gsap.to(target, {
|
|
|
|
|
|
|
|
autoAlpha: 1,
|
|
|
|
autoAlpha: 1,
|
|
|
|
x: this.hideOrigin ? 0 : "100%",
|
|
|
|
x: this.hideOrigin ? 0 : "100%",
|
|
|
|
zIndex: this.hideOrigin ? 2 : 10,
|
|
|
|
zIndex: this.hideOrigin ? 2 : 10,
|
|
|
|
onStart: () => {
|
|
|
|
onStart: () => {
|
|
|
|
if (this.active1) {
|
|
|
|
this.active2 = false;
|
|
|
|
this.sortColorSaturation();
|
|
|
|
// if (this.active1) {
|
|
|
|
}
|
|
|
|
// this.sortColorSaturation();
|
|
|
|
if (this.active2) {
|
|
|
|
// }
|
|
|
|
this.sortColorLight();
|
|
|
|
// if (this.active2) {
|
|
|
|
}
|
|
|
|
// this.sortColorLight();
|
|
|
|
|
|
|
|
// }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (this.hideOrigin) {
|
|
|
|
|
|
|
|
this.hideOrigin2 = false;
|
|
|
|
|
|
|
|
gsap.to(this.$refs.clusterCon, {
|
|
|
|
|
|
|
|
autoAlpha: 0,
|
|
|
|
|
|
|
|
zIndex: 2,
|
|
|
|
|
|
|
|
x: 0,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
gsap.to([this.$refs.btn1, this.$refs.btn2], { autoAlpha: 1 });
|
|
|
|
|
|
|
|
// gsap.to(this.$refs.showColor, { autoAlpha: 0 });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
// 显示隐藏分组2
|
|
|
|
|
|
|
|
showGroup2(index) {
|
|
|
|
|
|
|
|
let target = this.$refs.clusterCon;
|
|
|
|
|
|
|
|
gsap.to(target, {
|
|
|
|
|
|
|
|
autoAlpha: 1,
|
|
|
|
|
|
|
|
zIndex: this.hideOrigin2 ? 2 : 10,
|
|
|
|
|
|
|
|
x: this.hideOrigin2 ? 0 : "100%",
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this.hideOrigin2) {
|
|
|
|
|
|
|
|
this.hideOrigin = false;
|
|
|
|
|
|
|
|
gsap.to(this.$refs.sortCon, {
|
|
|
|
|
|
|
|
autoAlpha: 0,
|
|
|
|
|
|
|
|
zIndex: 2,
|
|
|
|
|
|
|
|
x: 0,
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
gsap.to(this.$refs.showColor, { autoAlpha: 1 });
|
|
|
|
|
|
|
|
gsap.to([this.$refs.btn1, this.$refs.btn2], { autoAlpha: 0 });
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
gsap.to(this.$refs.showColor, { autoAlpha: 0 });
|
|
|
|
|
|
|
|
gsap.to([this.$refs.btn1, this.$refs.btn2], { autoAlpha: 1 });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// 颜色数据转换为hsl
|
|
|
|
// 颜色数据转换为hsl
|
|
|
|
reHandleColor() {
|
|
|
|
reHandleColor() {
|
|
|
|
|
|
|
|
// this.colorArr
|
|
|
|
this.colorArr.forEach((item, index) => {
|
|
|
|
this.colorArr.forEach((item, index) => {
|
|
|
|
if (item.R && item.G && item.B) {
|
|
|
|
this.hlsColorArr.push(
|
|
|
|
this.hlsColorArr.push(
|
|
|
|
colorUtil.color(item.HEX) //item.HEX
|
|
|
|
// this.rgbToHsl(item.R, item.G, item.B)
|
|
|
|
);
|
|
|
|
colorUtil.rgb.to.hsl({
|
|
|
|
|
|
|
|
r: item.R,
|
|
|
|
|
|
|
|
g: item.G,
|
|
|
|
|
|
|
|
b: item.B,
|
|
|
|
|
|
|
|
a: 255,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
console.log(this.hlsColorArr);
|
|
|
|
// console.log(this.hexColorArr);
|
|
|
|
//根据hue分组
|
|
|
|
//根据hue分组
|
|
|
|
this.sortColorByHue();
|
|
|
|
this.sortColorByHue();
|
|
|
|
// 按照预定颜色分组
|
|
|
|
|
|
|
|
// this.sortColorByClusters();
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// 按照色环分组
|
|
|
|
// 按照色环分组
|
|
|
|
sortColorByHue() {
|
|
|
|
sortColorByHue() {
|
|
|
|
this.hlsColorArr.forEach((item, index) => {
|
|
|
|
this.hlsColorArr.forEach((item, index) => {
|
|
|
|
if (item.h) {
|
|
|
|
let color = item.hsl;
|
|
|
|
let _index = 11 - Math.floor((item.h * 360) / 30); //将360度色盘区分为12个维度
|
|
|
|
if (color.h) {
|
|
|
|
|
|
|
|
let _index = 8 - Math.floor((color.h * 360) / 40); //将360度色盘区分为12个维度
|
|
|
|
|
|
|
|
// // 灰
|
|
|
|
|
|
|
|
// if (
|
|
|
|
|
|
|
|
// // 当饱和度为0时
|
|
|
|
|
|
|
|
// color.s <= 0.3 &&
|
|
|
|
|
|
|
|
// color.l <= 0.7 &&
|
|
|
|
|
|
|
|
// color.l >= 0.1
|
|
|
|
|
|
|
|
// ) {
|
|
|
|
|
|
|
|
// _index = 11;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // 黑色
|
|
|
|
|
|
|
|
// if (color.l < 0.4 && color.s < 0.4) {
|
|
|
|
|
|
|
|
// _index = 9;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // 白色
|
|
|
|
|
|
|
|
// if (color.l > 0.7 && color.s < 0.3) {
|
|
|
|
|
|
|
|
// _index = 10;
|
|
|
|
|
|
|
|
// }
|
|
|
|
// 灰
|
|
|
|
// 灰
|
|
|
|
if (
|
|
|
|
if (
|
|
|
|
// 当饱和度为0时
|
|
|
|
// 当饱和度为0时
|
|
|
|
item.s <= 0.15 && item.l <= 0.75 && item.l >= 0.2
|
|
|
|
color.s <= 0.15 &&
|
|
|
|
|
|
|
|
color.l <= 0.75 &&
|
|
|
|
|
|
|
|
color.l >= 0.2
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
_index = 14;
|
|
|
|
_index = 11;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 黑色
|
|
|
|
// 黑色
|
|
|
|
if (item.l < 0.2 && item.s < 0.18) {
|
|
|
|
if (color.l < 0.2 && color.s < 0.18) {
|
|
|
|
_index = 12;
|
|
|
|
_index = 9;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 白色
|
|
|
|
// 白色
|
|
|
|
if (item.l > 0.75 && item.s < 0.15) {
|
|
|
|
if (color.l > 0.75 && color.s < 0.15) {
|
|
|
|
_index = 13;
|
|
|
|
_index = 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.newColorArr[_index].push(item);
|
|
|
|
this.newColorArr[_index].push(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// console.log(this.newColorArr);
|
|
|
|
// console.log(this.newColorArr);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// 按照预定颜色分组
|
|
|
|
|
|
|
|
sortColorByClusters() {
|
|
|
|
|
|
|
|
const sortedClusters = this.sortWithClusters(this.hlsColorArr);
|
|
|
|
|
|
|
|
const sortedColors = sortedClusters.reduce((acc, curr) => {
|
|
|
|
|
|
|
|
const colors = curr.colors.map((color) => color.hex);
|
|
|
|
|
|
|
|
return [...acc, ...colors];
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.clustersColorArr = sortedColors;
|
|
|
|
|
|
|
|
console.log(this.clustersColorArr);
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
// 根据饱和度排序
|
|
|
|
// 根据饱和度排序
|
|
|
|
sortColorSaturation() {
|
|
|
|
sortColorSaturation() {
|
|
|
|
this.active1 = true;
|
|
|
|
this.active1 = true;
|
|
|
|
@@ -291,12 +199,12 @@ export default {
|
|
|
|
// 分组
|
|
|
|
// 分组
|
|
|
|
this.newColorArr.forEach((item, index) => {
|
|
|
|
this.newColorArr.forEach((item, index) => {
|
|
|
|
item.sort((a, b) => {
|
|
|
|
item.sort((a, b) => {
|
|
|
|
return b.s - a.s;
|
|
|
|
return b.hsl.s - a.hsl.s;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
this.hlsColorArr.sort((a, b) => {
|
|
|
|
this.hlsColorArr.sort((a, b) => {
|
|
|
|
return b.s - a.s;
|
|
|
|
return b.hsl.s - a.hsl.s;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -304,156 +212,166 @@ export default {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// 根据亮度
|
|
|
|
// 根据亮度
|
|
|
|
sortColorLight() {
|
|
|
|
sortColorLight() {
|
|
|
|
this.active1 = false;
|
|
|
|
|
|
|
|
this.active2 = true;
|
|
|
|
this.active2 = true;
|
|
|
|
if (this.hideOrigin) {
|
|
|
|
this.caclulTime++;
|
|
|
|
// 分组
|
|
|
|
this.$Utils.showTips({
|
|
|
|
this.newColorArr.forEach((item, index) => {
|
|
|
|
message: `正在第${this.caclulTime}次计算,请稍等...<br/>再次点击排序按钮<br/>可重复计算优化排序`,
|
|
|
|
// item = this.sortColor(item);
|
|
|
|
});
|
|
|
|
// console.log(item)
|
|
|
|
|
|
|
|
item.sort((a, b) => {
|
|
|
|
setTimeout(() => {
|
|
|
|
// let deltaH = b.h - a.h;
|
|
|
|
if (this.hideOrigin) {
|
|
|
|
// let deltaS = b.s - a.s;
|
|
|
|
// 分组
|
|
|
|
let deltaL = b.l - a.l;
|
|
|
|
this.newColorArr.forEach((item, index) => {
|
|
|
|
// let aRgb = colorUtil.hsl.to.rgb({h: a.h, s: a.s, l: a.l, a: 1});
|
|
|
|
// 灰度区分
|
|
|
|
// let bRgb = colorUtil.hsl.to.rgb({h: b.h, s: b.s, l: b.l, a: 1});
|
|
|
|
// item = this.sortColor(item);
|
|
|
|
// let distance = this.colorDistance(aRgb,bRgb);
|
|
|
|
// console.log(item)
|
|
|
|
return (
|
|
|
|
// item.forEach((t, i) => {
|
|
|
|
// Math.random() > 0.5 ? 1 : -1
|
|
|
|
// let rgb = t.rgb;
|
|
|
|
deltaL
|
|
|
|
// t.grey = rgb.r * 0.299 + rgb.g * 0.587 + rgb.b * 0.114;
|
|
|
|
);
|
|
|
|
// });
|
|
|
|
|
|
|
|
// item.sort((a, b) => {
|
|
|
|
|
|
|
|
// let deltaGrey = b.grey - a.grey;
|
|
|
|
|
|
|
|
// let result = deltaGrey;
|
|
|
|
|
|
|
|
// return (
|
|
|
|
|
|
|
|
// // Math.random() > 0.5 ? 1 : -1
|
|
|
|
|
|
|
|
// result
|
|
|
|
|
|
|
|
// );
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.newColorArr[index] = [];
|
|
|
|
|
|
|
|
let sortedArr = this.sortColors(item);
|
|
|
|
|
|
|
|
this.newColorArr[index].push(...sortedArr);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// this.hlsColorArr.sort((a, b) => {
|
|
|
|
this.hlsColorArr.sort((a, b) => {
|
|
|
|
// return b.hsl.l - a.hsl.l;
|
|
|
|
return b.l - a.l;
|
|
|
|
// });
|
|
|
|
});
|
|
|
|
this.hlsColorArr = this.sortColors(this.hlsColorArr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.active2 = false;
|
|
|
|
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
|
|
|
|
// console.log(this.newColorArr);
|
|
|
|
// console.log(this.newColorArr);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// 计算颜色距离
|
|
|
|
// 计算hsl颜色距离
|
|
|
|
colorDistance(color1, color2) {
|
|
|
|
colorDistanceHsl(_color1, _color2) {
|
|
|
|
const x =
|
|
|
|
let color1 = _color1;
|
|
|
|
Math.pow(color1.r - color2.r, 2) +
|
|
|
|
let color2 = _color2;
|
|
|
|
Math.pow(color1.g - color2.g, 2) +
|
|
|
|
let result = 0;
|
|
|
|
Math.pow(color1.b - color2.b, 2);
|
|
|
|
color1 = color1.hsl;
|
|
|
|
return x; //Math.sqrt(x)
|
|
|
|
color2 = color2.hsl;
|
|
|
|
},
|
|
|
|
Object.keys(color1).forEach((key, index) => {
|
|
|
|
// 一维排序
|
|
|
|
if (key != "a") {
|
|
|
|
oneDimensionSorting(colors, dim) {
|
|
|
|
result +=
|
|
|
|
return colors.sort((colorA, colorB) => {
|
|
|
|
(color1[key] - color2[key]) *
|
|
|
|
if (colorA.hsl[dim] < colorB.hsl[dim]) {
|
|
|
|
(color1[key] - color2[key]) *
|
|
|
|
return -1;
|
|
|
|
this.balance2[index];
|
|
|
|
} else if (colorA.hsl[dim] > colorB.hsl[dim]) {
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
if (Math.floor(color1.r / 30) !== Math.floor(color2.r / 30)) {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// 根据明度
|
|
|
|
// 计算rgb颜色距离
|
|
|
|
blendRgbaWithWhite(rgba) {
|
|
|
|
colorDistanceRgb(_color1, _color2) {
|
|
|
|
const color = colorUtil.color(rgba);
|
|
|
|
let color1 = _color1;
|
|
|
|
const a = color.rgb.a / 255;
|
|
|
|
let color2 = _color2;
|
|
|
|
const r = Math.floor(color.rgb.r * a + 0xff * (1 - a));
|
|
|
|
let result = 0;
|
|
|
|
const g = Math.floor(color.rgb.g * a + 0xff * (1 - a));
|
|
|
|
color1 = color1.rgb;
|
|
|
|
const b = Math.floor(color.rgb.b * a + 0xff * (1 - a));
|
|
|
|
color2 = color2.rgb;
|
|
|
|
return "#" + ((r << 16) | (g << 8) | b).toString(16);
|
|
|
|
Object.keys(color1).forEach((key, index) => {
|
|
|
|
},
|
|
|
|
if (key != "a") {
|
|
|
|
sortWithClusters(colorsToSort) {
|
|
|
|
result +=
|
|
|
|
const mappedColors = colorsToSort
|
|
|
|
(color1[key] - color2[key]) *
|
|
|
|
// .map((color) => {
|
|
|
|
(color1[key] - color2[key]) *
|
|
|
|
// console.log(color);
|
|
|
|
this.balance3[index];
|
|
|
|
// const isRgba = color.includes("rgba");
|
|
|
|
}
|
|
|
|
// if (isRgba) {
|
|
|
|
|
|
|
|
// return blendRgbaWithWhite(color);
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// return color;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
.map(colorUtil.color);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mappedColors.forEach((color) => {
|
|
|
|
|
|
|
|
let minDistance;
|
|
|
|
|
|
|
|
let minDistanceClusterIndex;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.clusters.forEach((cluster, clusterIndex) => {
|
|
|
|
|
|
|
|
const colorRgbArr = [color.rgb.r, color.rgb.g, color.rgb.b];
|
|
|
|
|
|
|
|
const distance = this.colorDistance(
|
|
|
|
|
|
|
|
colorRgbArr,
|
|
|
|
|
|
|
|
cluster.leadColor
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
|
|
|
typeof minDistance === "undefined" ||
|
|
|
|
|
|
|
|
minDistance > distance
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
minDistance = distance;
|
|
|
|
|
|
|
|
minDistanceClusterIndex = clusterIndex;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.clusters[minDistanceClusterIndex].colors.push(color);
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
this.clusters.forEach((cluster) => {
|
|
|
|
|
|
|
|
const dim = ["white", "grey", "black"].includes(cluster.name)
|
|
|
|
|
|
|
|
? "l"
|
|
|
|
|
|
|
|
: "s";
|
|
|
|
|
|
|
|
cluster.colors = this.oneDimensionSorting(cluster.colors, dim);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return this.clusters;
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
sortColor(colors){
|
|
|
|
// 计算hsv颜色距离 然后和rgb 以及 hsl 距离相加
|
|
|
|
|
|
|
|
colorDistance(_color1, _color2) {
|
|
|
|
|
|
|
|
let color1 = _color1;
|
|
|
|
|
|
|
|
let color2 = _color2;
|
|
|
|
|
|
|
|
let result = 0;
|
|
|
|
|
|
|
|
result += this.colorDistanceRgb(color1, color2);
|
|
|
|
|
|
|
|
result += this.colorDistanceHsl(color1, color2);
|
|
|
|
|
|
|
|
color1 = color1.hsv;
|
|
|
|
|
|
|
|
color2 = color2.hsv;
|
|
|
|
|
|
|
|
Object.keys(color1).forEach((key, index) => {
|
|
|
|
|
|
|
|
if (key != "a") {
|
|
|
|
|
|
|
|
result +=
|
|
|
|
|
|
|
|
(color1[key] - color2[key]) *
|
|
|
|
|
|
|
|
(color1[key] - color2[key]) *
|
|
|
|
|
|
|
|
this.balance[index];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
// 根据根据颜色距离排序
|
|
|
|
|
|
|
|
sortColors(colors) {
|
|
|
|
// Calculate distance between each color
|
|
|
|
// Calculate distance between each color
|
|
|
|
var distances = [];
|
|
|
|
console.log("origin length =", colors.length);
|
|
|
|
for (var i = 0; i < colors.length; i++) {
|
|
|
|
if (colors.length === 0) return colors;
|
|
|
|
|
|
|
|
const distances = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < colors.length; i++) {
|
|
|
|
distances[i] = [];
|
|
|
|
distances[i] = [];
|
|
|
|
for (var j = 0; j < i; j++){
|
|
|
|
for (let j = 0; j < i; j++) {
|
|
|
|
let aRgb = colorUtil.hsl.to.rgb({h: colors[i].h, s: colors[i].s, l: colors[i].l, a: 1});
|
|
|
|
distances.push([
|
|
|
|
let bRgb = colorUtil.hsl.to.rgb({h: colors[j].h, s: colors[j].s, l: colors[j].l, a: 1});
|
|
|
|
colors[i],
|
|
|
|
distances.push([colors[i], colors[j], this.colorDistance(aRgb, bRgb)]);
|
|
|
|
colors[j],
|
|
|
|
|
|
|
|
this.colorDistance(colors[i], colors[j]),
|
|
|
|
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
distances.sort(function(a, b) {
|
|
|
|
distances.sort((a, b) => a[2] - b[2]);
|
|
|
|
return a[2] - b[2];
|
|
|
|
|
|
|
|
});
|
|
|
|
// console.log(distances.length);
|
|
|
|
|
|
|
|
|
|
|
|
// Put each color into separate cluster initially
|
|
|
|
// Put each color into separate cluster initially
|
|
|
|
var colorToCluster = {};
|
|
|
|
const colorToCluster = {};
|
|
|
|
for (var i = 0; i < colors.length; i++)
|
|
|
|
for (let i = 0; i < colors.length; i++) {
|
|
|
|
colorToCluster[colors[i]] = [colors[i]];
|
|
|
|
colorToCluster[colors[i].int] = [colors[i]];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Merge clusters, starting with lowest distances
|
|
|
|
// Merge clusters, starting with lowest distances
|
|
|
|
var lastCluster=[];
|
|
|
|
let lastCluster;
|
|
|
|
for (var i = 0; i < distances.length; i++) {
|
|
|
|
for (let i = 0; i < distances.length; i++) {
|
|
|
|
var color1 = distances[i][0];
|
|
|
|
const color1 = distances[i][0];
|
|
|
|
var color2 = distances[i][1];
|
|
|
|
const color2 = distances[i][1];
|
|
|
|
var cluster1 = colorToCluster[color1];
|
|
|
|
|
|
|
|
var cluster2 = colorToCluster[color2];
|
|
|
|
const cluster1 = colorToCluster[color1 && color1.int];
|
|
|
|
if (!cluster1 || !cluster2 || cluster1 == cluster2)
|
|
|
|
const cluster2 = colorToCluster[color2 && color2.int];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!cluster1 || !cluster2 || cluster1 === cluster2) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure color1 is at the end of its cluster and
|
|
|
|
// Make sure color1 is at the end of its cluster and
|
|
|
|
// color2 at the beginning.
|
|
|
|
// color2 at the beginning.
|
|
|
|
if (color1 != cluster1[cluster1.length - 1])
|
|
|
|
if (color1 !== cluster1[cluster1.length - 1]) {
|
|
|
|
|
|
|
|
// cluster1 = this.colorReverse(cluster1);
|
|
|
|
cluster1.reverse();
|
|
|
|
cluster1.reverse();
|
|
|
|
if (color2 != cluster2[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
if (color2 !== cluster2[0]) {
|
|
|
|
cluster2.reverse();
|
|
|
|
cluster2.reverse();
|
|
|
|
|
|
|
|
// cluster2 = this.colorReverse(cluster2);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Merge cluster2 into cluster1
|
|
|
|
// Merge cluster2 into cluster1
|
|
|
|
cluster1.push.apply(cluster1, cluster2);
|
|
|
|
cluster1.push(...cluster2);
|
|
|
|
delete colorToCluster[color1];
|
|
|
|
delete colorToCluster[color1.int];
|
|
|
|
delete colorToCluster[color2];
|
|
|
|
delete colorToCluster[color2.int];
|
|
|
|
colorToCluster[cluster1[0]] = cluster1;
|
|
|
|
colorToCluster[cluster1[0].int] = cluster1;
|
|
|
|
colorToCluster[cluster1[cluster1.length - 1]] = cluster1;
|
|
|
|
colorToCluster[cluster1[cluster1.length - 1].int] = cluster1;
|
|
|
|
lastCluster = cluster1;
|
|
|
|
lastCluster = cluster1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
console.log(lastCluster)
|
|
|
|
console.log("sorted length =", lastCluster.length);
|
|
|
|
// By now all colors should be in one cluster
|
|
|
|
// By now all colors should be in one cluster
|
|
|
|
return lastCluster;
|
|
|
|
return lastCluster;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
@@ -509,8 +427,8 @@ export default {
|
|
|
|
.prLayout(30px,30px);
|
|
|
|
.prLayout(30px,30px);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
&::nth-first{
|
|
|
|
&::nth-first {
|
|
|
|
.header{
|
|
|
|
.header {
|
|
|
|
margin-top: 0;
|
|
|
|
margin-top: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -527,7 +445,7 @@ export default {
|
|
|
|
align-items: center;
|
|
|
|
align-items: center;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
flex-wrap: wrap;
|
|
|
|
color: rgba(0, 0, 0, 0.8);
|
|
|
|
color: rgba(0, 0, 0, 0.8);
|
|
|
|
.first{
|
|
|
|
.first {
|
|
|
|
width: 100%;
|
|
|
|
width: 100%;
|
|
|
|
display: flex;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
flex-direction: row;
|
|
|
|
@@ -545,9 +463,10 @@ export default {
|
|
|
|
text-align: center;
|
|
|
|
text-align: center;
|
|
|
|
border-radius: 20px;
|
|
|
|
border-radius: 20px;
|
|
|
|
padding: 0 20px;
|
|
|
|
padding: 0 20px;
|
|
|
|
margin: 10px;
|
|
|
|
margin: 40px;
|
|
|
|
background: linear-gradient(315deg, #ec7070, #c75f5f);
|
|
|
|
background: linear-gradient(315deg, #ec7070, #c75f5f);
|
|
|
|
box-shadow: -14px -14px 28px #b15454, 14px 14px 28px #ff7e7e;
|
|
|
|
box-shadow: -14px -14px 28px #b15454, 14px 14px 28px #ff7e7e;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
&.active {
|
|
|
|
&.active {
|
|
|
|
color: rgba(255, 255, 255, 1);
|
|
|
|
color: rgba(255, 255, 255, 1);
|
|
|
|
background: linear-gradient(315deg, #c75f5f, #ec7070);
|
|
|
|
background: linear-gradient(315deg, #c75f5f, #ec7070);
|
|
|
|
|