vue-devui
Version:
DevUI components based on Vite and Vue3
187 lines (186 loc) • 6.56 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
const DEFAULT_PLUGIN_OPTIONS = {
directive: "ripple",
color: "currentColor",
initialOpacity: 0.2,
finalOpacity: 0.1,
duration: 400,
easing: "ease-out",
delay: 75,
disabled: false
};
const createContainer = ({
borderTopLeftRadius,
borderTopRightRadius,
borderBottomLeftRadius,
borderBottomRightRadius
}) => {
const rippleContainer = document.createElement("div");
rippleContainer.style.top = "0";
rippleContainer.style.left = "0";
rippleContainer.style.width = "100%";
rippleContainer.style.height = "100%";
rippleContainer.style.position = "absolute";
rippleContainer.style.borderRadius = `${borderTopLeftRadius} ${borderTopRightRadius} ${borderBottomRightRadius} ${borderBottomLeftRadius}`;
rippleContainer.style.overflow = "hidden";
rippleContainer.style.pointerEvents = "none";
rippleContainer.style.webkitMaskImage = "-webkit-radial-gradient(white, black)";
return rippleContainer;
};
const createrippleElement = (x, y, size, options) => {
const rippleElement = document.createElement("div");
rippleElement.style.position = "absolute";
rippleElement.style.width = `${size}px`;
rippleElement.style.height = `${size}px`;
rippleElement.style.top = `${y}px`;
rippleElement.style.left = `${x}px`;
rippleElement.style.background = options.color;
rippleElement.style.borderRadius = "50%";
rippleElement.style.opacity = `${options.initialOpacity}`;
rippleElement.style.transform = `translate(-50%,-50%) scale(0)`;
rippleElement.style.transition = `transform ${options.duration / 1e3}s ${options.easing}, opacity ${options.duration / 1e3}s ${options.easing}`;
return rippleElement;
};
function magnitude(x1, y1, x2, y2) {
const deltaX = x1 - x2;
const deltaY = y1 - y2;
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
}
function getDistanceToFurthestCorner(x, y, { width, height }) {
const topLeft = magnitude(x, y, 0, 0);
const topRight = magnitude(x, y, width, 0);
const bottomLeft = magnitude(x, y, 0, height);
const bottomRight = magnitude(x, y, width, height);
return Math.max(topLeft, topRight, bottomLeft, bottomRight);
}
const getRelativePointer = ({ x, y }, { top, left }) => ({
x: x - left,
y: y - top
});
const RIPPLE_COUNT = "vRippleCountInternal";
function setRippleCount(el, count) {
el.dataset[RIPPLE_COUNT] = count.toString();
}
function getRippleCount(el) {
var _a;
return parseInt((_a = el.dataset[RIPPLE_COUNT]) != null ? _a : "0", 10);
}
function incrementRippleCount(el) {
const count = getRippleCount(el);
setRippleCount(el, count + 1);
}
function decrementRippleCount(el) {
const count = getRippleCount(el);
setRippleCount(el, count - 1);
}
function deleteRippleCount(el) {
delete el.dataset[RIPPLE_COUNT];
}
const MULTIPLE_NUMBER = 2.05;
const ripple = (event, el, options) => {
const rect = el.getBoundingClientRect();
const computedStyles = window.getComputedStyle(el);
const { x, y } = getRelativePointer(event, rect);
const size = MULTIPLE_NUMBER * getDistanceToFurthestCorner(x, y, rect);
const rippleContainer = createContainer(computedStyles);
const rippleEl = createrippleElement(x, y, size, options);
let originalPositionValue = "";
let shouldDissolveripple = false;
let token = null;
function dissolveripple() {
rippleEl.style.transition = "opacity 150ms linear";
rippleEl.style.opacity = "0";
setTimeout(() => {
rippleContainer.remove();
decrementRippleCount(el);
if (getRippleCount(el) === 0) {
deleteRippleCount(el);
el.style.position = originalPositionValue;
}
}, 150);
}
function releaseripple(e) {
if (typeof e !== "undefined") {
document.removeEventListener("pointerup", releaseripple);
document.removeEventListener("pointercancel", releaseripple);
}
if (shouldDissolveripple) {
dissolveripple();
} else {
shouldDissolveripple = true;
}
}
function cancelripple() {
clearTimeout(token);
rippleContainer.remove();
document.removeEventListener("pointerup", releaseripple);
document.removeEventListener("pointercancel", releaseripple);
document.removeEventListener("pointercancel", cancelripple);
}
incrementRippleCount(el);
if (computedStyles.position === "static") {
if (el.style.position) {
originalPositionValue = el.style.position;
}
el.style.position = "relative";
}
rippleContainer.appendChild(rippleEl);
el.appendChild(rippleContainer);
document.addEventListener("pointerup", releaseripple);
document.addEventListener("pointercancel", releaseripple);
token = setTimeout(() => {
document.removeEventListener("pointercancel", cancelripple);
requestAnimationFrame(() => {
rippleEl.style.transform = `translate(-50%,-50%) scale(1)`;
rippleEl.style.opacity = `${options.finalOpacity}`;
setTimeout(() => releaseripple(), options.duration);
});
}, options.delay);
document.addEventListener("pointercancel", cancelripple);
};
const optionMap = /* @__PURE__ */ new WeakMap();
const globalOptions = __spreadValues({}, DEFAULT_PLUGIN_OPTIONS);
var RippleDirective = {
mounted(el, binding) {
var _a;
optionMap.set(el, (_a = binding.value) != null ? _a : {});
el.addEventListener("pointerdown", (event) => {
const options = optionMap.get(el);
if (binding.value && binding.value.disabled) {
return;
}
if (options === false) {
return;
}
ripple(event, el, __spreadValues(__spreadValues({}, globalOptions), options));
});
},
updated(el, binding) {
var _a;
optionMap.set(el, (_a = binding.value) != null ? _a : {});
}
};
var index = {
title: "Ripple \u6C34\u6CE2\u7EB9",
category: "\u901A\u7528",
status: "100%",
install(app) {
app.directive("Ripple", RippleDirective);
}
};
export { RippleDirective, index as default };