@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
JavaScript
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
};