UNPKG

@opentiny/vue-renderless

Version:

An enterprise-class UI component library, support both Vue.js 2 and Vue.js 3, as well as PC and mobile.

132 lines (131 loc) 3.65 kB
import "../../chunk-G2ADBYYC.js"; import { ColorPoint } from "../utils/color-points"; import { getClientXY } from "../utils/getClientXY"; import { Color } from "../utils/color"; import { draggable } from "../utils/use-drag"; import { isNullOrEmpty } from "@opentiny/utils"; const LINEAR_GRADIENT_BAR = "linearGradientBar"; const THUMB = "thumb"; const useLinearGradient = (state, hooks, utils, context) => { const { vm } = utils; const { nextTick } = hooks; const activePoint = context.activeColor; const addPoint = (point) => { context.colorPoints.value.push(point); }; const getPos = (event) => { if (!vm) { return 0; } const el = vm.$refs[LINEAR_GRADIENT_BAR]; const rect = el.getBoundingClientRect(); const { clientX } = getClientXY(event); return Math.min(Math.max(clientX - rect.left, 0), rect.width); }; const onDrag = (event) => { if (!vm) { return 0; } activePoint.value.cursorLeft = getPos(event); }; const getActivePoint = () => { return activePoint; }; const onClickBar = (event) => { const active = getActivePoint(); const newPoint = new ColorPoint( new Color({ enableAlpha: active.value.color.enableAlpha, format: active.value.color.format, value: active.value.color.value }), active.value.cursorLeft ); const left = getPos(event); newPoint.cursorLeft = left; addPoint(newPoint); setActivePoint(newPoint); nextTick(() => { const lastColorPointElement = vm.$refs[THUMB].at(-1); if (!lastColorPointElement) { return; } draggable(lastColorPointElement, { drag(event2) { onDrag(event2); }, end(event2) { onDrag(event2); } }); }); }; const setActivePoint = (point) => { activePoint.value = point; }; const onThumbMouseDown = (event, point) => { setActivePoint(point); const el = event.target; draggable(el, { drag(event2) { onDrag(event2); }, end(event2) { onDrag(event2); } }); }; const getRelativePos = (points) => { const bar = vm.$refs[LINEAR_GRADIENT_BAR]; if (!bar) { return 0; } const rect = bar.getBoundingClientRect(); return Number.parseInt((points.cursorLeft / rect.width * 100).toFixed(0)); }; const toString = () => { const colors = context.colorPoints.value.map((point) => { return [point.color.value, getRelativePos(point)]; }).sort((a, b) => a[1] - b[1]).map(([colorValue, pos]) => { return [colorValue, `${pos}%`].join(" "); }).join(","); return `linear-gradient(${context.deg.value}deg, ${colors})`; }; hooks.watchEffect(() => { if (isNullOrEmpty(context.deg.value)) { return; } context.linearGardientValue.value = toString(); state.linearGradientBarBackground = toString().replace(`${context.deg.value}deg`, "90deg"); }); hooks.onMounted(() => { const elements = vm.$refs[THUMB]; if (!elements || !elements.length) { return; } elements.forEach((el) => { draggable(el, { drag(event) { onDrag(event); }, end(event) { onDrag(event); } }); }); context.bar.value = vm.$refs[LINEAR_GRADIENT_BAR]; }); return { onClickBar, onThumbMouseDown, toString }; }; const initState = (hooks) => { const { ref, reactive } = hooks; const linearGradientBarBackground = ref(""); const state = reactive({ linearGradientBarBackground }); return state; }; export { LINEAR_GRADIENT_BAR, THUMB, initState, useLinearGradient };