color-picker完整版

前面发过一版,漏了个最重要的代码文件color.js,现在补上。

以下是整个color-picker的完整版

由于UI需求,需要使用直接取色的取色器面板,有点类似于element-plus里的el-color-pick,但是不需要有展开的操作。于是模仿element-plus写了该组件。技术栈vue3.js + javascript

该组件包含三个部分:

  1. 一个饱和度 - 明度(SV)面板,用于调整颜色的饱和度和明度;
  2. 用于调整颜色色相(hue 值)的滑块;
  3. 用于调整颜色透明度(alpha 值)的滑块。

代码实现包含:index.vue、SvPanel.vue、HueSlider.vue、AlphaSlider.vue、utils.js、color.js(新增)

目录

入口代码:index.vue

饱和度 - 明度(SV)面板代码:SvPanel.vue

调整颜色色相(hue 值)的滑块代码:HueSlider.vue

调整颜色透明度(alpha 值)的滑块代码:AlphaSlider.vue

工具代码:utils.js

使用示例:


入口代码:index.vue

<template>
    <div class="color-dropdown__main-wrapper">
        <SvPanel ref="svPanel" :color="state.color"></SvPanel>
        <HueSlider ref="hueSlider" :color="state.color"></HueSlider>
    </div>
    <AlphaSlider ref="alphaSlider" :color="state.color"></AlphaSlider>
</template>

<script setup>
import {
    reactive,
    onBeforeUnmount,
    onMounted,
    watch,
    ref,
    computed,
} from "vue";
import SvPanel from "./SvPanel.vue";
import HueSlider from "./HueSlider.vue";
import AlphaSlider from "./AlphaSlider.vue";
import Color from "/public/native/core/color.js";
const state = reactive({
    color: new Color(),
});
const emits = defineEmits({
    change: null,
});
const alphaSlider = ref(null);
let colorValue = computed(() => {
    const hue = state.color.get("hue");
    const value = state.color.get("value");
    const saturation = state.color.get("saturation");
    const alpha = state.color.get("alpha");

    return { hue, value, saturation, alpha };
});
let props = defineProps({
    modelValue: {
        type: String,
        required: false,
        default: "#ffffff",
    },
});
watch(
    () => colorValue,
    (colorValue) => {
        alphaSlider.value.update();
        let alpha = colorValue.value.alpha
            ? colorValue.value.alpha / 101
            : 0.99;

        emits("change", {
            color: state.color.tohex(),
            alpha,
        });
    },
    { deep: true }
);
watch(
    () => props.modelValue,
    (modelValue) => {
        console.log("modelValue-change:", modelValue);
        state.color.fromHex(modelValue);
    }
);
onMounted(() => {
    state.color.fromHex(props.modelValue);
});
onBeforeUnmount(() => {
    //console.log('onBeforeUnmount')
});
</script>
<style scoped lang="less">
.color-dropdown__main-wrapper {
    margin-bottom: 3px;
    display: flex;
    &:after {
        content: "";
        display: table;
        clear: both;
    }
}
</style>
饱和度 - 明度(SV)面板代码:SvPanel.vue
<template>
    <div
        class="color-svpanel"
        :style="{
            backgroundColor: state.background,
        }"
    >
        <div class="color-svpanel__white"></div>
        <div class="color-svpanel__black"></div>
        <div
            class="color-svpanel__cursor"
            :style="{
                top: state.cursorTop + 'px',
                left: state.cursorLeft + 'px',
            }"
        >
            <div></div>
        </div>
    </div>
</template>

<script setup>
import {
    reactive,
    onBeforeUnmount,
    onMounted,
    getCurrentInstance,
    computed,
    watch,
} from "vue";
import { draggable, getClientXY } from "./utils.js";
let { vnode } = getCurrentInstance();
let props = defineProps({
    color: {
        type: Object,
        required: true,
    },
});
const state = reactive({
    cursorTop: 0,
    cursorLeft: 0,
    background: "hsl(0, 100%, 50%)",
});
let colorValue = computed(() => {
    const hue = props.color.get("hue");
    const value = props.color.get("value");
    return { hue, value };
});
watch(
    () => colorValue.value,
    () => {
        update();
    }
);
onMounted(() => {
    draggable(vnode.el, {
        drag: (event) => {
            handleDrag(event);
        },
        end: (event) => {
            handleDrag(event);
        },
    });
    update();
});
onBeforeUnmount(() => {
    //console.log('onBeforeUnmount')
});
function update() {
    const saturation = props.color.get("saturation");
    const value = props.color.get("value");

    const el = vnode.el;
    const { clientWidth, clientHeight } = el;

    state.cursorLeft = (saturation * clientWidth) / 100;
    state.cursorTop = ((100 - value) * clientHeight) / 100;

    state.background = `hsl(${props.color.get("hue")}, 100%, 50%)`;
}
function handleDrag(event) {
    const el = vnode.el;
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值