diff --git a/package.json b/package.json index 4c2c80e..ba7f675 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue3-colorpicker", - "version": "2.1.4", + "version": "2.1.5", "main": "dist/index.es.js", "types": "dist/types/index.d.ts", "author": "aesoper", @@ -37,8 +37,7 @@ "lodash-es": "^4.17.21", "tinycolor2": "^1.4.2", "vue": "^3.3.4", - "vue-types": "^4.1.0", - "vue3-angle": "^0.1.6" + "vue-types": "^4.1.0" }, "devDependencies": { "@babel/core": "^7.16.0", diff --git a/packages/ColorPicker.vue b/packages/ColorPicker.vue index 35e1f9e..04e1a18 100644 --- a/packages/ColorPicker.vue +++ b/packages/ColorPicker.vue @@ -43,17 +43,19 @@ reactive, ref, } from "vue"; + import { onClickOutside, tryOnMounted, whenever, useDebounceFn } from "@vueuse/core"; + import tinycolor, { ColorInputWithoutInstance } from "tinycolor2"; + import { GradientNode, parse, stringify } from "gradient-parser"; + import { createPopper, Instance } from "@popperjs/core"; + import propTypes from "vue-types"; + import FkColorPicker from "./fk/FkColorPicker.vue"; import ChromeColorPicker from "./chrome/ChromeColorPicker.vue"; import GradientColorPicker from "./gradient/GradientColorPicker.vue"; import WrapContainer from "./common/WrapContainer.vue"; - import tinycolor, { ColorInputWithoutInstance } from "tinycolor2"; - import propTypes from "vue-types"; - import { Color, ColorFormat } from "./utils/color"; - import { onClickOutside, tryOnMounted, whenever, useDebounceFn } from "@vueuse/core"; - import { createPopper, Instance } from "@popperjs/core"; - import { GradientNode, parse, stringify } from "gradient-parser"; + import { ColorPickerProvider, ColorPickerProviderKey, SupportLang } from "./utils/type"; + import { Color, ColorFormat } from "./utils/color"; const colorPickerProps = { isWidget: propTypes.bool.def(false), diff --git a/packages/angle/Angle.tsx b/packages/angle/Angle.tsx new file mode 100644 index 0000000..94e2c02 --- /dev/null +++ b/packages/angle/Angle.tsx @@ -0,0 +1,97 @@ +import { computed, ref, watch, onMounted, defineComponent } from "vue"; +import { calcAngle, triggerDragEvent, DragEventOption } from "./utils"; + +import "./index.scss"; + +const angleProps = { + angle: { + type: Number, + default: 0, + }, + size: { + type: Number, + default: 16, + validator: (value: number) => { + return value >= 16; + }, + }, + borderWidth: { + type: Number, + default: 1, + validator: (value: number) => { + return value >= 1; + }, + }, + borderColor: { + type: String, + default: "#666", + }, +}; + +export default defineComponent({ + name: "Angle", + props: angleProps, + emits: ["update:angle", "change"], + setup(props, { emit }) { + const angleRef = ref(null); + + const rotate = ref(0); + + watch( + () => props.angle, + (angle: number) => { + rotate.value = angle; + } + ); + + const updateAngle = (): void => { + let value = Number(rotate.value); + if (!isNaN(value)) { + value = value > 360 || value < 0 ? props.angle : value; + rotate.value = value === 360 ? 0 : value; + emit("update:angle", rotate.value); + emit("change", rotate.value); + } + }; + + const getStyle = computed(() => { + return { + width: props.size + "px", + height: props.size + "px", + borderWidth: props.borderWidth + "px", + borderColor: props.borderColor, + transform: `rotate(${rotate.value}deg)`, + }; + }); + + const handleDrag = (event: MouseEvent) => { + if (angleRef.value) { + rotate.value = calcAngle(angleRef.value, event) % 360; + updateAngle(); + } + }; + + onMounted(() => { + const dragConfig: DragEventOption = { + drag: (event: Event) => { + handleDrag(event as MouseEvent); + }, + end: (event: Event) => { + handleDrag(event as MouseEvent); + }, + }; + + if (angleRef.value) { + triggerDragEvent(angleRef.value, dragConfig); + } + }); + + return () => { + return ( +
+
+
+ ); + }; + }, +}); diff --git a/packages/angle/index.scss b/packages/angle/index.scss new file mode 100644 index 0000000..79b7cf7 --- /dev/null +++ b/packages/angle/index.scss @@ -0,0 +1,39 @@ +.bee-angle { + transform: rotate(90deg); + + > * { + display: inline-block; + vertical-align: middle; + } + + &.zero-right { + transform: rotate(180deg); + } + + &.zero-bottom { + transform: rotate(270deg); + } + + &__round { + position: relative; + margin-left: 8px; + width: 16px; + height: 16px; + border: 1px solid #666; + border-radius: 50%; + cursor: pointer; + display: inline-block; + vertical-align: middle; + + &::before { + content: ""; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + width: 50%; + height: 1px; + background-color: #666; + } + } +} diff --git a/packages/angle/utils.ts b/packages/angle/utils.ts new file mode 100644 index 0000000..560b995 --- /dev/null +++ b/packages/angle/utils.ts @@ -0,0 +1,86 @@ +export const calcAngle = (element: HTMLElement, event: MouseEvent): number => { + const rect = element.getBoundingClientRect(); + + const originX = rect.left + rect.width / 2; + const originY = rect.top + rect.height / 2; + + //获得中心点和鼠标坐标连线,与y轴正半轴之间的夹角 + const x = Math.abs(originX - event.clientX); + const y = Math.abs(originY - event.clientY); + const z = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + const cos = y / z; + const rad = Math.acos(cos); //用反三角函数求弧度 + let angle = Math.floor(180 / (Math.PI / rad)); //将弧度转换成角度 + + if (event.clientX > originX && event.clientY > originY) { + //鼠标在第四象限 + angle = 180 - angle; + } + + if (event.clientX == originX && event.clientY > originY) { + //鼠标在y轴负方向上 + angle = 180; + } + + if (event.clientX > originX && event.clientY == originY) { + //鼠标在x轴正方向上 + angle = 90; + } + + if (event.clientX < originX && event.clientY > originY) { + //鼠标在第三象限 + angle = 180 + angle; + } + + if (event.clientX < originX && event.clientY == originY) { + //鼠标在x轴负方向 + angle = 270; + } + + if (event.clientX < originX && event.clientY < originY) { + //鼠标在第二象限 + angle = 360 - angle; + } + + return angle; +}; + +let isDragging = false; + +export interface DragEventOption { + drag?: (event: Event) => void; + start?: (event: Event) => void; + end?: (event: Event) => void; +} + +export const triggerDragEvent = (element: HTMLElement, options: DragEventOption): void => { + const moveFn = function (event: Event) { + options.drag?.(event); + }; + + const upFn = function (event: Event) { + document.removeEventListener("mousemove", moveFn, false); + document.removeEventListener("mouseup", upFn, false); + document.onselectstart = null; + document.ondragstart = null; + + isDragging = false; + + options.end?.(event); + }; + + if (element) { + element.addEventListener("mousedown", (event: Event) => { + if (isDragging) return; + document.onselectstart = () => false; + document.ondragstart = () => false; + document.addEventListener("mousemove", moveFn, false); + document.addEventListener("mouseup", upFn, false); + isDragging = true; + + options.start?.(event); + }); + } + + return; +}; diff --git a/packages/common/Hue.vue b/packages/common/Hue.vue index 0458f56..de9e156 100644 --- a/packages/common/Hue.vue +++ b/packages/common/Hue.vue @@ -142,7 +142,7 @@ height: 100%; border-radius: 15px; background: linear-gradient( - to left, + to right, rgb(255, 0, 0) 0%, rgb(255, 255, 0) 16.66%, rgb(0, 255, 0) 33.33%, diff --git a/packages/common/Lightness.vue b/packages/common/Lightness.vue index 9c55692..fe5c9b9 100644 --- a/packages/common/Lightness.vue +++ b/packages/common/Lightness.vue @@ -85,7 +85,7 @@ }).toPercentageRgbString(); return { background: [ - `linear-gradient(to left, rgb(255, 255, 255), ${color1}, ${color2}, ${color3}, ${color4}, rgb(0, 0, 0))`, + `linear-gradient(to right, rgb(255, 255, 255), ${color1}, ${color2}, ${color3}, ${color4}, rgb(0, 0, 0))`, `-webkit-linear-gradient(left, rgb(255, 255, 255), ${color1}, ${color2}, ${color3}, ${color4}, rgb(0, 0, 0))`, `-moz-linear-gradient(left, rgb(255, 255, 255), ${color1}, ${color2}, ${color3}, ${color4}, rgb(0, 0, 0))`, `-ms-linear-gradient(left, rgb(255, 255, 255), ${color1}, ${color2}, ${color3}, ${color4}, rgb(0, 0, 0))`, diff --git a/packages/gradient/GradientColorPicker.vue b/packages/gradient/GradientColorPicker.vue index 759af70..5e3ab11 100644 --- a/packages/gradient/GradientColorPicker.vue +++ b/packages/gradient/GradientColorPicker.vue @@ -37,7 +37,7 @@
- + deg
@@ -64,21 +64,20 @@