@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.
159 lines (158 loc) • 5.49 kB
JavaScript
import "../chunk-G2ADBYYC.js";
import { isServer } from "@opentiny/utils";
const DEFAULT_DURATION = 200;
const INERTIA_TIME = 300;
const INERTIA_DISTANCE = 15;
const preventDefault = (event, isStopPropagation) => {
if (typeof event.cancelable !== "boolean" || event.cancelable) {
event.preventDefault();
}
if (isStopPropagation) {
event.stopPropagation();
}
};
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
const pxCheck = (value) => {
return isNaN(Number(value)) ? String(value) : `${value}px`;
};
const stopMomentum = ({ state, api }) => () => {
state.moving = false;
state.touchTime = 0;
api.setChooseValue();
};
const setRollerStyle = ({ state }) => (index) => {
return `transform: rotate3d(1, 0, 0, ${-state.rotation * index}deg) translate3d(0px, 0px, 104px)`;
};
const onTouchStart = ({ state, props, touch, vm }) => (event) => {
if (isServer)
return;
touch.start(event);
if (state.moving) {
const dom = vm.$refs.roller;
const { transform } = window.getComputedStyle(dom);
if (props.threeDimensional) {
const circle = Math.floor(parseInt(state.touchDeg) / 360);
const cos = +transform.split(", ")[5];
const sin = +transform.split(", ")[6] < 0 ? 180 : 0;
const endDeg = circle * 360 + Math.acos(cos) / Math.PI * 180 + sin;
state.scrollDistance = -Math.abs((endDeg / state.rotation - 1) * +props.optionHeight);
} else {
state.scrollDistance = +transform.slice(7, transform.length - 1).split(", ")[5];
}
}
preventDefault(event, true);
state.touchParams.startY = touch.deltaY.value;
state.touchParams.startTime = Date.now();
state.transformY = state.scrollDistance;
};
const onTouchMove = ({ state, api, touch }) => (event) => {
touch.move(event);
if (touch.isVertical()) {
state.moving = true;
preventDefault(event, true);
}
state.touchParams.lastY = touch.deltaY.value;
let move = state.touchParams.lastY - state.touchParams.startY;
api.setMove(move);
};
const onTouchEnd = ({ state, props, api, touch }) => () => {
state.touchParams.lastY = touch.deltaY.value;
state.touchParams.lastTime = Date.now();
let move = state.touchParams.lastY - state.touchParams.startY;
let moveTime = state.touchParams.lastTime - state.touchParams.startTime;
if (moveTime <= INERTIA_TIME && Math.abs(move) > INERTIA_DISTANCE) {
const distance = api.momentum(move, moveTime);
api.setMove(distance, "end", +props.swipeDuration);
return;
} else {
api.setMove(move, "end");
}
setTimeout(() => {
touch.reset();
state.moving = false;
}, 0);
};
const momentum = (distance, duration) => {
const speed = Math.abs(distance / duration);
distance = speed / 3e-3 * (distance < 0 ? -1 : 1);
return distance;
};
const isHidden = ({ state }) => (index) => {
if (index >= state.currIndex + 8 || index <= state.currIndex - 8) {
return true;
} else {
return false;
}
};
const setTransform = ({ state }) => (type, deg, translateY = 0, time = DEFAULT_DURATION) => {
if (type === "end") {
state.touchTime = time;
} else {
state.touchTime = 0;
}
state.touchDeg = deg;
state.scrollDistance = translateY;
};
const setMove = ({ state, props, api }) => (move, type, time) => {
const { optionHeight } = props;
let updateMove = move + state.transformY;
if (type === "end") {
if (updateMove > 0) {
updateMove = 0;
}
if (updateMove < -(props.column.length - 1) * +optionHeight) {
updateMove = -(props.column.length - 1) * +optionHeight;
}
let endMove = Math.round(updateMove / +optionHeight) * +optionHeight;
let deg = `${(Math.abs(Math.round(endMove / +optionHeight)) + 1) * state.rotation}deg`;
api.setTransform(type, deg, endMove, time);
state.currIndex = state.defaultIndex = Math.abs(Math.round(endMove / +optionHeight)) + 1;
} else {
let deg = 0;
let currentDeg = (-updateMove / +optionHeight + 1) * state.rotation;
const maxDeg = (props.column.length + 1) * state.rotation;
const minDeg = 0;
deg = clamp(currentDeg, minDeg, maxDeg);
if (minDeg < deg && deg < maxDeg) {
api.setTransform(null, deg + "deg", updateMove, void 0);
state.currIndex = state.defaultIndex = Math.abs(Math.round(updateMove / +optionHeight)) + 1;
}
}
};
const setChooseValue = ({ props, state, emit }) => () => {
emit("change", props.column[state.currIndex - 1]);
};
const modifyStatus = ({ state, props, api }) => (type) => {
const { column } = props;
const value = isEffectVal(props.value) ? props.value : props.defaultValue;
const currentIndex = isEffectVal(props.value) ? "currIndex" : "defaultIndex";
let index = column.findIndex((columnItem) => columnItem[props.fieldNames.value] === value);
state[currentIndex] = index === -1 ? 1 : index + 1;
let move = index === -1 ? 0 : index * +props.optionHeight;
type && api.setChooseValue();
api.setMove(-move);
};
const OptionStyle = ({ props, state }) => (option, column, offset) => {
const currentIndex = isEffectVal(props.value) ? state.currIndex - 1 : state.defaultIndex - 1;
return option === column[currentIndex + offset] || option === column[currentIndex - offset];
};
const isEffectVal = (val) => {
return val || val === 0;
};
export {
OptionStyle,
clamp,
isHidden,
modifyStatus,
momentum,
onTouchEnd,
onTouchMove,
onTouchStart,
preventDefault,
pxCheck,
setChooseValue,
setMove,
setRollerStyle,
setTransform,
stopMomentum
};