Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugins/colors/.oxfmtrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"ignorePatterns": [],
"ignorePatterns": ["node_modules", "dist", "typed-router.d.ts"],
"sortImports": {
"newlinesBetween": false,
"groups": [
Expand Down
4 changes: 2 additions & 2 deletions plugins/colors/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/colors/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "colors",
"version": "1.2.2",
"version": "1.3.0",
"private": true,
"type": "module",
"scripts": {
Expand Down
Binary file modified plugins/colors/public/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion plugins/colors/public/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"title": "颜色助手",
"description": "这是一个快速选择生成颜色的插件,提供了常用的颜色选择和生成工具,帮助用户轻松获取所需的颜色值。",
"author": "mekefly",
"version": "1.2.2",
"version": "1.3.0",
"main": "index.html",
"preload": "preload/services.js",
"logo": "logo.png",
Expand Down
23 changes: 12 additions & 11 deletions plugins/colors/src/components/Card.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
<script setup lang="ts">
import { useCurrentColor } from "@/utils/current-color";

defineProps<{ title?: string }>();
const currentColorStore = useCurrentColor();
</script>
<template>
<div class="col-span-6 space-y-6">
<div
class="rounded-2xl p-6 shadow-lg"
:style="{
backgroundColor: currentColorStore.currentColor.toHex(),
color: currentColorStore.currentColor.isDark() ? '#FFFFFF' : '#000000',
}"
>
<div class="transition-colors duration-500 ease-in-out">
<slot></slot>
</div>
<div
class="flex h-full w-full flex-1 flex-col items-center justify-center rounded-2xl p-6 shadow-lg"
:style="{
backgroundColor: currentColorStore.currentColor.toHex(),
color: currentColorStore.currentColor.isDark() ? '#FFFFFF' : '#000000',
}"
>
<div class="w-full transition-[color] duration-500 ease-in-out">
Comment thread
mekefly marked this conversation as resolved.
<h3 v-if="title" class="mb-4 text-lg font-semibold">{{ title }}</h3>
<slot></slot>
</div>
</div>
</template>
8 changes: 6 additions & 2 deletions plugins/colors/src/components/ColorCard.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<script setup lang="ts">
import { colord } from "colord";
import { computed } from "vue";
import { useConfigStore } from "@/utils/config";
import { useTagsEditing, type ColorFavorite } from "@/utils/favorites";
import { copyColor } from "../utils/copy";
import { copyColor2 } from "../utils/copy";
import Tags from "./tags.vue";

const editing = useTagsEditing();
const config = useConfigStore();

interface Props {
favorite: ColorFavorite;
Expand All @@ -19,6 +22,7 @@ const props = defineProps<Props>();
const emit = defineEmits<Emits>();

const tags = computed(() => props.favorite.tags ?? []);
const handleCopy = () => copyColor2(colord(props.favorite.color), config);
</script>

<template>
Expand All @@ -27,7 +31,7 @@ const tags = computed(() => props.favorite.tags ?? []);
<div
class="relative aspect-square cursor-pointer p-2"
:style="{ backgroundColor: favorite.color }"
@click="copyColor(favorite.color)"
@click="handleCopy"
title="点击复制颜色值"
>
<!-- 标签 -->
Expand Down
40 changes: 7 additions & 33 deletions plugins/colors/src/components/ColorFormat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import xyzPlugin from "colord/plugins/xyz";
extend([hwbPlugin, cmykPlugin, labPlugin, lchPlugin, xyzPlugin]);
import { computed, ref, watch } from "vue";
import { colordToHsvString } from "@/utils/color";
import { useCounterStore } from "@/utils/config";
import { copyColor } from "@/utils/copy";
import { useConfigStore } from "@/utils/config";
import { copyColor2 } from "@/utils/copy";

interface Props {
flag: "hsl" | "hsv/hsb" | "hex" | "rgb" | "hwb" | "cmyk" | "lab" | "lch" | "xyz";
}

const { flag } = defineProps<Props>();
const config = useCounterStore();
const config = useConfigStore();
const color = defineModel<Colord>({ required: true });

// 用户正在输入的标志
Expand Down Expand Up @@ -181,40 +181,14 @@ function handleInputChange(index: number, value: string) {
}
}

/**
* 获取用于复制的字符串表示
*/
function getCopyString(): string {
switch (flag) {
case "hsl":
return color.value.toHslString();
case "hsv/hsb":
return colordToHsvString(color.value);
case "hex":
let hex = color.value.toHex();
return config.removeHash ? hex.substring(1) : hex;
case "rgb":
return color.value.toRgbString();
case "hwb":
return color.value.toHwbString();
case "cmyk":
return color.value.toCmykString();
case "lab":
const lab = color.value.toLab();
return `lab(${lab.l.toFixed(0)} ${lab.a.toFixed(0)} ${lab.b.toFixed(0)})`;
case "lch":
const lch = color.value.toLch();
return `lch(${lch.l.toFixed(0)} ${lch.c.toFixed(0)} ${lch.h.toFixed(0)})`;
case "xyz":
const xyz = color.value.toXyz();
return `xyz(${xyz.x.toFixed(2)} ${xyz.y.toFixed(2)} ${xyz.z.toFixed(2)})`;
}
}
function handleBlur() {
inputting.value = false;
// 当停止输入后,将本地值更新到合法值
updateLocalValues(displayValues.value);
}
function handleCopy() {
copyColor2(color.value, { ...config, format: flag });
}
</script>
<template>
<div class="flex items-center space-x-2">
Expand All @@ -229,7 +203,7 @@ function handleBlur() {
class="min-w-[0px] flex-1 rounded border border-gray-300 px-3 py-1 text-center text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
/>
<button
@click="copyColor(getCopyString())"
@click="handleCopy"
class="grow-0 p-1 transition-transform duration-200 hover:scale-105"
>
<svg
Expand Down
36 changes: 36 additions & 0 deletions plugins/colors/src/components/ColorFormatSelect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<script lang="ts" setup>
import { computed } from "vue";
import { useConfigStore } from "@/utils/config";
import { useCurrentColor } from "@/utils/current-color";
import Select from "./Select.vue";

const currentColorStore = useCurrentColor();
const config = useConfigStore();

// 定义颜色格式选项
const colorFormatOptions = [
{ value: "hex", label: "HEX (#RRGGBB)" },
{ value: "rgb", label: "RGB (rgb(r, g, b))" },
{ value: "hsv/hsb", label: "HSV/HSB" },
{ value: "hsl", label: "HSL (hsl(h, s%, l%))" },
{ value: "hwb", label: "HWB" },
{ value: "cmyk", label: "CMYK" },
{ value: "lab", label: "LAB" },
{ value: "lch", label: "LCH" },
{ value: "xyz", label: "XYZ" },
];

// 计算样式,保持原有的背景色功能
const selectStyle = computed(() => ({
background: currentColorStore.currentColor.toHex(),
}));
</script>

<template>
<Select
id="colorFormat"
v-model="config.format"
:options="colorFormatOptions"
:style="selectStyle"
/>
</template>
2 changes: 0 additions & 2 deletions plugins/colors/src/components/ColorFormats.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<script setup lang="ts">
import { Colord } from "colord";
import { computed } from "vue";
import { copyColor } from "@/utils/copy";
import { useMessage } from "@/utils/message";
import { useFavorites } from "../utils/favorites";
import ColorFormat from "./ColorFormat.vue";
Expand Down
2 changes: 1 addition & 1 deletion plugins/colors/src/components/ColorWheel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ useEventListener(window, "mousemove", handleMouseMove, { passive: true });
ref="canvasRef"
width="200"
height="200"
class="cursor-crosshair rounded-full outline-2 outline-[color:var(--color)]"
class="cursor-crosshair rounded-full outline-2 outline-[color:currentColor]"
@mousedown="handleMouseDown"
/>
<div
Expand Down
21 changes: 21 additions & 0 deletions plugins/colors/src/components/Config.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts" setup>
import { useConfigStore } from "@/utils/config";
import { useCurrentColor } from "@/utils/current-color";
import ColorFormatSelect from "./ColorFormatSelect.vue";
import SettingItem from "./SettingItem.vue";
import ToggleButton from "./ToggleButton.vue";

const config = useConfigStore();
const { currentColor } = useCurrentColor();
</script>
<template>
<div class="flex flex-col space-y-4">
<SettingItem label="色值去 #">
<ToggleButton v-model="config.removeHash" />
</SettingItem>

<SettingItem label="复制格式">
<ColorFormatSelect />
</SettingItem>
</div>
</template>
123 changes: 123 additions & 0 deletions plugins/colors/src/components/HSLSliders.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<script setup lang="ts">
import { Colord, colord } from "colord";
import { computed } from "vue";
import Slider from "@/components/Slider.vue";

interface Props {
modelValue: Colord;
}

const props = defineProps<Props>();
const emit = defineEmits(["update:modelValue"]);

// 计算色相值 (0-360)
const hue = computed({
get: () => {
const hsl = props.modelValue.toHsl();
return hsl.h;
},
set: (value: number) => {
const hsl = props.modelValue.toHsl();
const newColor = colord({ h: value, s: hsl.s, l: hsl.l });
emit("update:modelValue", newColor);
},
});

// 计算饱和度值 (0-100)
const saturation = computed({
get: () => {
const hsl = props.modelValue.toHsl();
return hsl.s;
},
set: (value: number) => {
const hsl = props.modelValue.toHsl();
const newColor = colord({ h: hsl.h, s: value, l: hsl.l });
emit("update:modelValue", newColor);
},
});

// 计算亮度值 (0-100)
const lightness = computed({
get: () => {
const hsl = props.modelValue.toHsl();
return hsl.l;
},
set: (value: number) => {
const hsl = props.modelValue.toHsl();
const newColor = colord({ h: hsl.h, s: hsl.s, l: value });
emit("update:modelValue", newColor);
},
});

// 计算渐变背景
const hueGradient = computed(() => {
const hsl = props.modelValue.toHsl();
const colors = [0, 60, 120, 180, 240, 300, 0].map((h) => colord({ ...hsl, h: h }).toHex());

return `linear-gradient(to right, ${colors.join(", ")})`;
});

const saturationGradient = computed(() => {
const hsl = props.modelValue.toHsl();
const colors = [0, 100].map((s) => colord({ ...hsl, s }).toHex());
return `linear-gradient(to right, ${colors.join(", ")})`;
});

const lightnessGradient = computed(() => {
const hsl = props.modelValue.toHsl();
const colors = [0, 100].map((l) => colord({ ...hsl, l }).toHex());
return `linear-gradient(to right, ${colors.join(", ")})`;
});
</script>

<template>
<div class="space-y-4">
<!-- Hue Slider -->
<div class="flex items-center space-x-3">
<span class="w-8 text-sm font-medium">H</span>
<div class="flex-1">
<Slider
v-model="hue"
:min="0"
:max="360"
:step="1"
:background="hueGradient"
enable-wheel
/>
</div>
<span class="w-10 text-right text-sm">{{ Math.round(hue) }}</span>
</div>

<!-- Saturation Slider -->
<div class="flex items-center space-x-3">
<span class="w-8 text-sm font-medium">S</span>
<div class="flex-1">
<Slider
v-model="saturation"
:min="0"
:max="100"
:step="1"
:background="saturationGradient"
enable-wheel
/>
</div>
<span class="w-10 text-right text-sm">{{ Math.round(saturation) }}%</span>
</div>

<!-- Lightness Slider -->
<div class="flex items-center space-x-3">
<span class="w-8 text-sm font-medium">L</span>
<div class="flex-1">
<Slider
v-model="lightness"
:min="0"
:max="100"
:step="1"
:background="lightnessGradient"
enable-wheel
/>
</div>
<span class="w-10 text-right text-sm">{{ Math.round(lightness) }}%</span>
</div>
</div>
</template>
Loading