jy-vue3-photo-preview
Version:
1,529 lines (1,413 loc) • 83.5 kB
JavaScript
import { ref, defineComponent, openBlock, createElementBlock, createElementVNode, watch, onBeforeUnmount, toRefs, resolveComponent, normalizeStyle, normalizeClass, withModifiers, createBlock, computed, Teleport, toDisplayString, createVNode, createCommentVNode, Fragment, renderList, provide, renderSlot, inject, onMounted, onUnmounted } from 'vue';
var updateItemKey = Symbol();
var removeItemKey = Symbol();
var handleShowKey = Symbol();
function useItems(index) {
var items = ref([]);
var getElementIndex = function (children, child) {
return child ? Array.prototype.indexOf.call(children, child) : -1;
};
var sortItems = function (items) {
var _a, _b;
var children = (_b = (_a = items[0].originRef) === null || _a === void 0 ? void 0 : _a.parentNode) === null || _b === void 0 ? void 0 : _b.children;
if (children && children.length) {
items.sort(function (cur, next) { return getElementIndex(children, cur.originRef) - getElementIndex(children, next.originRef); });
}
};
var updateItem = function (item) {
var index = items.value.findIndex(function (_a) {
var key = _a.key;
return item.key === key;
});
if (index > -1) {
items.value.splice(index, 1, item);
}
else {
items.value.push(item);
sortItems(items.value);
}
};
var removeItem = function (key) {
var nextItems = items.value.filter(function (item) { return item.key !== key; });
var nextEndIndex = nextItems.length - 1;
items.value = nextItems;
index.value = Math.max(Math.min(index.value, nextEndIndex), 0);
};
return {
items: items,
updateItem: updateItem,
removeItem: removeItem,
};
}
function useVisible(items, index, onVisibleChange) {
var visible = ref(false);
var handleHide = function () {
visible.value = false;
onVisibleChange();
};
var handleShow = function (key) {
var itemIndex = items.value.findIndex(function (item) { return item.key === key; });
if (itemIndex > -1) {
index.value = itemIndex;
visible.value = true;
onVisibleChange();
}
};
return {
visible: visible,
handleHide: handleHide,
handleShow: handleShow,
};
}
function useIndex(onIndexChange) {
var index = ref(0);
var updateIndex = function (newIndex) {
index.value = newIndex;
onIndexChange();
};
return {
index: index,
updateIndex: updateIndex,
};
}
var script$c = defineComponent({});
const _hoisted_1$a = { class: "PhotoView__Spinner" };
const _hoisted_2$9 = /*#__PURE__*/createElementVNode("svg", {
xmlns: "http://www.w3.org/2000/svg",
viewBox: "0 0 32 32",
width: "36",
height: "36",
fill: "white"
}, [
/*#__PURE__*/createElementVNode("path", {
opacity: ".25",
d: "M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4"
}),
/*#__PURE__*/createElementVNode("path", { d: "M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z" })
], -1 /* HOISTED */);
const _hoisted_3$9 = [
_hoisted_2$9
];
function render$c(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("div", _hoisted_1$a, _hoisted_3$9))
}
script$c.render = render$c;
script$c.__file = "src/PhotoView/Spinner.vue";
function getSuitableImageSize(naturalWidth, naturalHeight, rotate) {
var _a;
var innerWidth = window.innerWidth, innerHeight = window.innerHeight;
// 如果图片不是水平,则调换宽高
var isVertical = rotate % 180 !== 0;
if (isVertical) {
_a = [innerHeight, innerWidth], innerWidth = _a[0], innerHeight = _a[1];
}
var width;
var height;
// 缩放到和窗口一样所需要的比例
var scaleWidth = innerWidth / naturalWidth;
var scaleHeight = innerHeight / naturalHeight;
if (naturalWidth < innerWidth && naturalHeight < innerHeight) {
// 如果图片原始宽度未超过容器尺寸,则使用原始尺寸
width = naturalWidth;
height = naturalHeight;
}
else {
// 否则缩放图片使之恰好放入
if (scaleWidth < scaleHeight) {
width = innerWidth;
height = innerWidth * (naturalHeight / naturalWidth);
}
else {
width = innerHeight * (naturalWidth / naturalHeight);
height = innerHeight;
}
}
return {
width: width,
height: height
};
}
function useLoadImage(src) {
var naturalWidth = ref(0);
var naturalHeight = ref(0);
var width = ref(0);
var height = ref(0);
var loaded = ref(false);
function setSuitableImageSize(actualWidth, actualHeight, rotate) {
var imageSize = getSuitableImageSize(actualWidth, actualHeight, rotate);
width.value = imageSize.width;
height.value = imageSize.height;
}
var loadImage = function (src) {
loaded.value = false;
var img = new Image();
img.onload = function () {
naturalWidth.value = img.naturalWidth;
naturalHeight.value = img.naturalHeight;
setSuitableImageSize(naturalWidth.value, naturalHeight.value, 0);
loaded.value = true;
};
img.src = src;
};
loadImage(src.value);
watch(src, function () {
loadImage(src.value);
});
return {
width: width,
height: height,
loaded: loaded,
naturalWidth: naturalWidth,
naturalHeight: naturalHeight,
setSuitableImageSize: setSuitableImageSize
};
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
var freeGlobal$1 = freeGlobal;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal$1 || freeSelf || Function('return this')();
var root$1 = root;
/**
* Gets the timestamp of the number of milliseconds that have elapsed since
* the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @since 2.4.0
* @category Date
* @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => Logs the number of milliseconds it took for the deferred invocation.
*/
var now = function() {
return root$1.Date.now();
};
var now$1 = now;
/** Used to match a single whitespace character. */
var reWhitespace = /\s/;
/**
* Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
* character of `string`.
*
* @private
* @param {string} string The string to inspect.
* @returns {number} Returns the index of the last non-whitespace character.
*/
function trimmedEndIndex(string) {
var index = string.length;
while (index-- && reWhitespace.test(string.charAt(index))) {}
return index;
}
/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;
/**
* The base implementation of `_.trim`.
*
* @private
* @param {string} string The string to trim.
* @returns {string} Returns the trimmed string.
*/
function baseTrim(string) {
return string
? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
: string;
}
/** Built-in value references. */
var Symbol$1 = root$1.Symbol;
var Symbol$2 = Symbol$1;
/** Used for built-in method references. */
var objectProto$1 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto$1.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString$1 = objectProto$1.toString;
/** Built-in value references. */
var symToStringTag$1 = Symbol$2 ? Symbol$2.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag$1),
tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString$1.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol$2 ? Symbol$2.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = baseTrim(value);
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
/** Error message constants. */
var FUNC_ERROR_TEXT$1 = 'Expected a function';
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // Avoid costly calculations while the window size is in flux.
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
* jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT$1);
}
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
timeWaiting = wait - timeSinceLastCall;
return maxing
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
var time = now$1();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now$1());
}
function debounced() {
var time = now$1(),
isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime);
}
if (maxing) {
// Handle invocations in a tight loop.
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* Creates a throttled function that only invokes `func` at most once per
* every `wait` milliseconds. The throttled function comes with a `cancel`
* method to cancel delayed `func` invocations and a `flush` method to
* immediately invoke them. Provide `options` to indicate whether `func`
* should be invoked on the leading and/or trailing edge of the `wait`
* timeout. The `func` is invoked with the last arguments provided to the
* throttled function. Subsequent calls to the throttled function return the
* result of the last `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the throttled function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.throttle` and `_.debounce`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to throttle.
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=true]
* Specify invoking on the leading edge of the timeout.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new throttled function.
* @example
*
* // Avoid excessively updating the position while scrolling.
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
*
* // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
* jQuery(element).on('click', throttled);
*
* // Cancel the trailing throttled invocation.
* jQuery(window).on('popstate', throttled.cancel);
*/
function throttle(func, wait, options) {
var leading = true,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
if (isObject(options)) {
leading = 'leading' in options ? !!options.leading : leading;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
return debounce(func, wait, {
'leading': leading,
'maxWait': wait,
'trailing': trailing
});
}
function useWindowResize(naturalWidth, naturalHeight, rotate, setSuitableImageSize) {
var handleResize = throttle(function () {
setSuitableImageSize(naturalWidth.value, naturalHeight.value, rotate.value);
}, 8);
window.addEventListener('resize', handleResize);
onBeforeUnmount(function () {
window.removeEventListener('resize', handleResize);
});
}
// 动画类型
var ShowAnimateEnum;
(function (ShowAnimateEnum) {
ShowAnimateEnum[ShowAnimateEnum["None"] = 0] = "None";
ShowAnimateEnum[ShowAnimateEnum["In"] = 1] = "In";
ShowAnimateEnum[ShowAnimateEnum["Out"] = 2] = "Out";
})(ShowAnimateEnum || (ShowAnimateEnum = {}));
// 触摸状态
var TouchTypeEnum;
(function (TouchTypeEnum) {
TouchTypeEnum[TouchTypeEnum["Normal"] = 0] = "Normal";
TouchTypeEnum[TouchTypeEnum["X"] = 1] = "X";
TouchTypeEnum[TouchTypeEnum["Y"] = 2] = "Y";
TouchTypeEnum[TouchTypeEnum["Scale"] = 3] = "Scale";
})(TouchTypeEnum || (TouchTypeEnum = {}));
// 边缘状态
var EdgeTypeEnum;
(function (EdgeTypeEnum) {
EdgeTypeEnum[EdgeTypeEnum["Left"] = 0] = "Left";
EdgeTypeEnum[EdgeTypeEnum["Right"] = 1] = "Right";
EdgeTypeEnum[EdgeTypeEnum["Top"] = 2] = "Top";
EdgeTypeEnum[EdgeTypeEnum["Bottom"] = 3] = "Bottom";
})(EdgeTypeEnum || (EdgeTypeEnum = {}));
function getAnimateOrigin(originRect) {
if (originRect) {
var innerWidth_1 = window.innerWidth, innerHeight_1 = window.innerHeight;
// 动画的元素宽高为 0,计算触发的点的中心到中点的距离即是 AnimateOrigin(粗略计算)
var xOrigin = originRect.left + originRect.width / 2 - innerWidth_1 / 2;
var yOrigin = originRect.top + originRect.height / 2 - innerHeight_1 / 2;
return "".concat(xOrigin, "px ").concat(yOrigin, "px");
}
return null;
}
/**
* 当前设备是否支持触摸事件
*/
var isTouchDevice = typeof document !== 'undefined' && 'ontouchstart' in document.documentElement;
/**
* 图片间隔
*/
var horizontalOffset = 20;
/**
* 最小初始响应距离
*/
var minStartTouchOffset = 10;
/**
* 最小切换图片距离
*/
var minSwitchImageOffset = 40;
/**
* 最大缩放度(若图片足够大,则会超出该值)
*/
var maxScale = 6;
function withContinuousTap(singleTap, doubleTap) {
// 当前连续点击次数
var continuousCount = 0;
var withSingleTap = debounce(function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
continuousCount = 0;
singleTap.apply(void 0, args);
}, 300);
return function invokeTap() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
continuousCount += 1;
withSingleTap.apply(void 0, args);
if (continuousCount >= 2) {
withSingleTap.cancel();
continuousCount = 0;
doubleTap.apply(void 0, args);
}
};
}
/**
* 获取移动或缩放之后的中心点
*/
function getPositionOnMoveOrScale(_a) {
var x = _a.x, y = _a.y, clientX = _a.clientX, clientY = _a.clientY, fromScale = _a.fromScale, toScale = _a.toScale;
var innerWidth = window.innerWidth, innerHeight = window.innerHeight;
// 缩放前的图片的中心坐标
var imageCenterClientX = innerWidth / 2 + x;
var imageCenterClientY = innerHeight / 2 + y;
// 放大偏移量
var offsetScale = toScale / fromScale;
// 缩放后的偏移量(为保证点击的点相对于视图位置不变,需要将缩放多出来的尺寸通过 translate 平衡掉)
var originX = -(clientX - imageCenterClientX) * (offsetScale - 1);
var originY = -(clientY - imageCenterClientY) * (offsetScale - 1);
return {
x: originX + x,
y: originY + y,
scale: toScale,
};
}
/**
* 获取图片拖拽到边缘需要的值
*/
function getEdgeInfo(_a) {
var _b;
var width = _a.width, height = _a.height, scale = _a.scale, rotate = _a.rotate;
// 如果图片不是水平,则调换宽高
var isVertical = rotate % 180 !== 0;
if (isVertical) {
_b = [height, width], width = _b[0], height = _b[1];
}
var innerWidth = window.innerWidth, innerHeight = window.innerHeight;
var currentWidth = width * scale;
var currentHeight = height * scale;
var edgeLeft, edgeRight, edgeTop, edgeBottom;
if (currentWidth > innerWidth) {
edgeLeft = (currentWidth - innerWidth) / 2;
edgeRight = -(currentWidth - innerWidth) / 2;
}
else {
edgeLeft = 0;
edgeRight = 0;
}
if (currentHeight > innerHeight) {
edgeTop = (currentHeight - innerHeight) / 2;
edgeBottom = -(currentHeight - innerHeight) / 2;
}
else {
edgeTop = 0;
edgeBottom = 0;
}
return {
edgeLeft: edgeLeft,
edgeRight: edgeRight,
edgeTop: edgeTop,
edgeBottom: edgeBottom,
};
}
/**
* 获取边缘类型
*/
function getEdgeTypes(_a) {
var width = _a.width, height = _a.height, scale = _a.scale, rotate = _a.rotate, x = _a.x, y = _a.y;
var position = getEdgeInfo({ width: width, height: height, scale: scale, rotate: rotate });
var edgeTypes = [];
if (x === position.edgeLeft) {
edgeTypes.push(EdgeTypeEnum.Left);
}
if (x === position.edgeRight) {
edgeTypes.push(EdgeTypeEnum.Right);
}
if (y === position.edgeTop) {
edgeTypes.push(EdgeTypeEnum.Top);
}
if (y === position.edgeBottom) {
edgeTypes.push(EdgeTypeEnum.Bottom);
}
return edgeTypes;
}
/**
* 获取标准值
*/
function getStandardPosition(_a) {
var width = _a.width, height = _a.height, scale = _a.scale, rotate = _a.rotate, x = _a.x, y = _a.y;
var _b = getEdgeInfo({ width: width, height: height, scale: scale, rotate: rotate }), edgeLeft = _b.edgeLeft, edgeRight = _b.edgeRight, edgeTop = _b.edgeTop, edgeBottom = _b.edgeBottom;
if (x > edgeLeft) {
x = edgeLeft;
}
if (x < edgeRight) {
x = edgeRight;
}
if (y > edgeTop) {
y = edgeTop;
}
if (y < edgeBottom) {
y = edgeBottom;
}
return { x: x, y: y, scale: scale };
}
/**
* 从 Touch 事件中获取两个触控中心的位置
* @param e TouchEvent
*/
function getMultipleTouchPosition(e) {
var _a = e.touches[0], clientX = _a.clientX, clientY = _a.clientY;
if (e.touches.length >= 2) {
var _b = e.touches[1], nextClientX = _b.clientX, nextClientY = _b.clientY;
return {
clientX: (clientX + nextClientX) / 2,
clientY: (clientY + nextClientY) / 2,
touchLength: Math.sqrt(Math.pow(nextClientX - clientX, 2) + Math.pow(nextClientY - clientY, 2)),
};
}
return { clientX: clientX, clientY: clientY, touchLength: 0 };
}
function useMoveImage(width, height, naturalWidth, naturalHeight, setSuitableImageSize, onTouchStart, onTouchMove, onTouchEnd, onSingleTap) {
// 图片 x 偏移量
var x = ref(0);
// 图片 y 偏移量
var y = ref(0);
// 图片缩放程度
var scale = ref(1);
// 图片旋转角度
var rotate = ref(0);
// 图片是否处于触摸状态
var touched = ref(false);
// 触摸开始时 x 的坐标
var clientX = ref(0);
// 触摸开始时 y 的坐标
var clientY = ref(0);
// 初始触摸状态
var touchType = ref(TouchTypeEnum.Normal);
// 上一次图片的 x 偏移量
var lastX = ref(0);
// 上一次图片的 y 偏移量
var lastY = ref(0);
// 上一次 touch 的长度
var lastTouchLength = ref(0);
// 上一次的图片缩放程度
var lastScale = ref(1);
// 边缘状态(用于缩放图片判断)
var edgeTypes = [];
var handleMouseDown = function (e) {
if (isTouchDevice)
return;
handleDown(e.clientX, e.clientY, 0);
window.addEventListener('mousemove', handleMouseMove);
window.addEventListener('mouseup', handleMouseUp);
};
var handleTouchStart = function (e) {
if (!isTouchDevice)
return;
var touch = getMultipleTouchPosition(e);
handleDown(touch.clientX, touch.clientY, touch.touchLength);
window.addEventListener('touchmove', handleTouchMove);
window.addEventListener('touchend', handleTouchEnd);
};
var handleDown = function (newClientX, newClientY, touchLength) {
touched.value = true;
clientX.value = newClientX;
clientY.value = newClientY;
lastTouchLength.value = touchLength;
lastScale.value = scale.value;
edgeTypes = getEdgeTypes({
width: width.value,
height: height.value,
scale: scale.value,
rotate: rotate.value,
x: lastX.value,
y: lastY.value
});
onTouchStart(newClientX, newClientY);
};
var handleMouseMove = function (e) {
if (isTouchDevice || !touched.value)
return;
handleMove(e.clientX, e.clientY, 0);
};
var handleTouchMove = function (e) {
if (!isTouchDevice || !touched.value)
return;
var touch = getMultipleTouchPosition(e);
handleMove(touch.clientX, touch.clientY, touch.touchLength);
};
var handleMove = throttle(function (newClientX, newClientY, touchLength) {
// 初始化触摸状态
if (touchType.value === TouchTypeEnum.Normal) {
if (scale.value !== 1 || touchLength) {
touchType.value = TouchTypeEnum.Scale;
}
else {
var isMoveX = Math.abs(newClientX - clientX.value) > minStartTouchOffset;
var isMoveY = Math.abs(newClientY - clientY.value) > minStartTouchOffset;
if (!isMoveX && !isMoveY)
return;
// 水平方向优先
touchType.value = isMoveX ? TouchTypeEnum.X : TouchTypeEnum.Y;
}
}
onTouchMove(touchType.value, newClientX, newClientY, lastScale.value, edgeTypes);
var newX = newClientX - clientX.value;
var newY = newClientY - clientY.value;
if (touchType.value === TouchTypeEnum.Y) {
x.value = newX + lastX.value;
y.value = newY + lastY.value;
}
if (touchType.value === TouchTypeEnum.Scale) {
if (touchLength) {
var endScale = scale.value + ((touchLength - lastTouchLength.value) / 100 / 2) * scale.value;
var toScale = Math.max(Math.min(endScale, Math.max(maxScale, naturalWidth.value / width.value)), 1);
handleToScale(toScale, newClientX, newClientY);
lastTouchLength.value = touchLength;
}
else {
// 处于左边缘情况,右划交给父级处理,处于右边缘情况,左划交给父级处理
if (!(newX > 0 && edgeTypes.includes(EdgeTypeEnum.Left)) &&
!(newX < 0 && edgeTypes.includes(EdgeTypeEnum.Right))) {
x.value = newX + lastX.value;
}
y.value = newY + lastY.value;
}
}
}, 8, { trailing: false });
var handleMouseUp = function (e) {
if (isTouchDevice)
return;
handleUp(e.clientX, e.clientY, e);
window.removeEventListener('mousemove', handleMouseMove);
window.removeEventListener('mouseup', handleMouseUp);
};
var handleTouchEnd = function (e) {
if (!isTouchDevice)
return;
var touch = e.changedTouches[0];
handleUp(touch.clientX, touch.clientY, e);
window.removeEventListener('touchmove', handleTouchMove);
window.removeEventListener('touchend', handleTouchEnd);
};
var onDoubleTap = function (newClientX, newClientY) {
if (touchType.value !== TouchTypeEnum.Normal)
return;
if (scale.value === 1) {
var toScale = Math.max(2, naturalWidth.value / width.value);
var position = getPositionOnMoveOrScale({
x: x.value,
y: y.value,
clientX: newClientX,
clientY: newClientY,
fromScale: scale.value,
toScale: toScale,
});
x.value = position.x;
y.value = position.y;
scale.value = position.scale;
}
else {
x.value = 0;
y.value = 0;
scale.value = 1;
}
};
var onTap = withContinuousTap(onSingleTap, onDoubleTap);
var handleUp = function (newClientX, newClientY, e) {
if (clientX.value === newClientX && clientY.value === newClientY) {
onTap(newClientX, newClientY, e);
}
onTouchEnd(touchType.value, newClientX, newClientY, lastScale.value, edgeTypes);
if (touchType.value === TouchTypeEnum.Y) {
x.value = 0;
y.value = 0;
}
if (touchType.value === TouchTypeEnum.Scale) {
setStandardPosition({
width: width.value,
height: height.value,
scale: scale.value,
rotate: rotate.value,
x: x.value,
y: y.value
});
}
touched.value = false;
touchType.value = TouchTypeEnum.Normal;
clientX.value = 0;
clientY.value = 0;
lastX.value = x.value;
lastY.value = y.value;
};
var handleWheel = function (e) {
var endScale = scale.value - e.deltaY / 100 / 2;
var toScale = Math.max(Math.min(endScale, Math.max(maxScale, naturalWidth.value / width.value)), 1);
handleToScale(toScale, e.clientX, e.clientY);
};
var handleToScale = function (newScale, newClientX, newClientY) {
var position = getPositionOnMoveOrScale({
x: x.value,
y: y.value,
clientX: newClientX,
clientY: newClientY,
fromScale: scale.value,
toScale: newScale,
});
setStandardPosition({
width: width.value,
height: height.value,
scale: position.scale,
rotate: rotate.value,
x: position.x,
y: position.y
});
};
var setStandardPosition = function (position) {
var standardPosition = getStandardPosition(position);
x.value = standardPosition.x;
y.value = standardPosition.y;
lastX.value = standardPosition.x;
lastY.value = standardPosition.y;
scale.value = standardPosition.scale;
};
var handleRotateLeft = function () {
rotate.value = rotate.value - 90;
setSuitableImageSize(naturalWidth.value, naturalHeight.value, rotate.value);
setStandardPosition({
width: width.value,
height: height.value,
scale: scale.value,
rotate: rotate.value,
x: x.value,
y: y.value
});
};
var handleRotateRight = function () {
rotate.value = rotate.value + 90;
setSuitableImageSize(naturalWidth.value, naturalHeight.value, rotate.value);
setStandardPosition({
width: width.value,
height: height.value,
scale: scale.value,
rotate: rotate.value,
x: x.value,
y: y.value
});
};
return {
x: x,
y: y,
scale: scale,
touched: touched,
handleMouseDown: handleMouseDown,
handleTouchStart: handleTouchStart,
handleWheel: handleWheel,
rotate: rotate,
handleRotateLeft: handleRotateLeft,
handleRotateRight: handleRotateRight
};
}
var script$b = defineComponent({
name: 'PhotoView',
components: {
Spinner: script$c
},
props: {
/**
* 图片地址
*/
src: {
type: String,
required: true,
},
/**
* 触发打开模态框的位置信息
*/
originRect: {
type: Object,
default: null,
},
/**
* 动画类型
*/
showAnimateType: {
type: Number,
default: null,
}
},
emits: ['touchStart', 'touchMove', 'touchEnd', 'singleTap'],
setup: function (props, _a) {
var emit = _a.emit;
var src = toRefs(props).src;
var _b = useLoadImage(src), width = _b.width, height = _b.height, loaded = _b.loaded, naturalWidth = _b.naturalWidth, naturalHeight = _b.naturalHeight, setSuitableImageSize = _b.setSuitableImageSize;
var onTouchStart = function (clientX, clientY) {
emit('touchStart', clientX, clientY);
};
var onTouchMove = function (touchType, clientX, clientY, lastScale, edgeTypes) {
emit('touchMove', touchType, clientX, clientY, lastScale, edgeTypes);
};
var onTouchEnd = function (touchType, clientX, clientY, lastScale, edgeTypes) {
emit('touchEnd', touchType, clientX, clientY, lastScale, edgeTypes);
};
var onSingleTap = function (clientX, clientY, e) {
emit('singleTap', clientX, clientY, e);
};
var _c = useMoveImage(width, height, naturalWidth, naturalHeight, setSuitableImageSize, onTouchStart, onTouchMove, onTouchEnd, onSingleTap), x = _c.x, y = _c.y, scale = _c.scale, rotate = _c.rotate, touched = _c.touched, handleMouseDown = _c.handleMouseDown, handleTouchStart = _c.handleTouchStart, handleWheel = _c.handleWheel, handleRotateLeft = _c.handleRotateLeft, handleRotateRight = _c.handleRotateRight;
useWindowResize(naturalWidth, naturalHeight, rotate, setSuitableImageSize);
return {
width: width,
height: height,
loaded: loaded,
x: x,
y: y,
scale: scale,
touched: touched,
handleMouseDown: handleMouseDown,
handleTouchStart: handleTouchStart,
handleWheel: handleWheel,
rotate: rotate,
handleRotateLeft: handleRotateLeft,
handleRotateRight: handleRotateRight
};
},
data: function () {
return {
ShowAnimateEnum: ShowAnimateEnum,
// 翻转
isFlipHorizontal: false,
isFlipVertical: false,
};
},
methods: {
getAnimateOrigin: getAnimateOrigin,
toggleFlipHorizontal: function () {
this.isFlipHorizontal = !this.isFlipHorizontal;
},
toggleFlipVertical: function () {
this.isFlipVertical = !this.isFlipVertical;
},
getTransform: function () {
var scaleX = "".concat(this.isFlipHorizontal ? '-' : '').concat(this.scale);
var scaleY = "".concat(this.isFlipVertical ? '-' : '').concat(this.scale);
var transform = {
matrix: "".concat(scaleX, ", 0, 0, ").concat(scaleY, ", ").concat(this.x, ", ").concat(this.y),
};
if (this.rotate) {
transform.rotate = "".concat(this.rotate, "deg");
}
var str = '';
Object.keys(transform).forEach(function (name) {
str += "".concat(name, "(").concat(transform[name], ")");
});
return str;
}
}
});
const _hoisted_1$9 = ["src"];
function render$b(_ctx, _cache, $props, $setup, $data, $options) {
const _component_spinner = resolveComponent("spinner");
return (_ctx.loaded)
? (openBlock(), createElementBlock("div", {
key: 0,
class: "PhotoView__PhotoWrap",
style: normalizeStyle({
width: `${_ctx.width}px`,
height: `${_ctx.height}px`
})
}, [
createElementVNode("div", {
class: normalizeClass(["PhotoView__PhotoBox", {
'PhotoView__animateIn': _ctx.showAnimateType === _ctx.ShowAnimateEnum.In,
'PhotoView__animateOut': _ctx.showAnimateType === _ctx.ShowAnimateEnum.Out,
}]),
style: normalizeStyle({
transformOrigin: _ctx.getAnimateOrigin(_ctx.originRect) || 'center',
width: _ctx.showAnimateType === _ctx.ShowAnimateEnum.In || _ctx.showAnimateType === _ctx.ShowAnimateEnum.Out ? '0' : '100%'
})
}, [
createElementVNode("img", {
class: "PhotoView__Photo",
src: _ctx.src,
style: normalizeStyle({
width: `${_ctx.width}px`,
height: `${_ctx.height}px`,
transform: _ctx.getTransform(),
transition: _ctx.touched ? undefined : 'transform 0.5s cubic-bezier(0.25, 0.8, 0.25, 1)',
}),
onMousedown: _cache[0] || (_cache[0] = withModifiers((...args) => (_ctx.handleMouseDown && _ctx.handleMouseDown(...args)), ["prevent"])),
onTouchstart: _cache[1] || (_cache[1] = withModifiers((...args) => (_ctx.handleTouchStart && _ctx.handleTouchStart(...args)), ["prevent"])),
onWheel: _cache[2] || (_cache[2] = (...args) => (_ctx.handleWheel && _ctx.handleWheel(...args)))
}, null, 44 /* STYLE, PROPS, HYDRATE_EVENTS */, _hoisted_1$9)
], 6 /* CLASS, STYLE */)
], 4 /* STYLE */))
: (openBlock(), createBlock(_component_spinner, { key: 1 }))
}
script$b.render = render$b;
script$b.__file = "src/PhotoView/index.vue";
function useBodyEffect(visible) {
var style = document.body.style;
var originalOverflow = style.overflow;
watch(visible, function () {
if (visible.value) {
style.overflow = 'hidden';
}
else {
style.overflow = originalOverflow;
}
});
}
function useInnerWidth() {
var innerWidth = ref(window.innerWidth);
var handleResize = throttle(function () {
innerWidth.value = window.innerWidth;
}, 8);
window.addEventListener('resize', handleResize);
onBeforeUnmount(function () {
window.removeEventListener('resize', handleResize);
});
return {
innerWidth: innerWidth
};
}
var script$a = defineComponent({});
const _hoisted_1$8 = {
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44",
viewBox: "0 0 768 768"
};
const _hoisted_2$8 = /*#__PURE__*/createElementVNode("path", {
fill: "#FFF",
d: "M607.5 205.5l-178.5 178.5 178.5 178.5-45 45-178.5-178.5-178.5 178.5-45-45 178.5-178.5-178.5-178.5 45-45 178.5 178.5 178.5-178.5z"
}, null, -1 /* HOISTED */);
const _hoisted_3$8 = [
_hoisted_2$8
];
function render$a(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$8, _hoisted_3$8))
}
script$a.render = render$a;
script$a.__file = "src/PhotoSlider/Close.vue";
var script$9 = defineComponent({});
const _hoisted_1$7 = {
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44",
viewBox: "0 0 768 768"
};
const _hoisted_2$7 = /*#__PURE__*/createElementVNode("path", { d: "M640.5 352.5v63h-390l178.5 180-45 45-256.5-256.5 256.5-256.5 45 45-178.5 180h390z" }, null, -1 /* HOISTED */);
const _hoisted_3$7 = [
_hoisted_2$7
];
function render$9(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$7, _hoisted_3$7))
}
script$9.render = render$9;
script$9.__file = "src/PhotoSlider/ArrowLeft.vue";
var script$8 = defineComponent({});
const _hoisted_1$6 = {
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44",
viewBox: "0 0 768 768"
};
const _hoisted_2$6 = /*#__PURE__*/createElementVNode("path", { d: "M384 127.5l256.5 256.5-256.5 256.5-45-45 178.5-180h-390v-63h390l-178.5-180z" }, null, -1 /* HOISTED */);
const _hoisted_3$6 = [
_hoisted_2$6
];
function render$8(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$6, _hoisted_3$6))
}
script$8.render = render$8;
script$8.__file = "src/PhotoSlider/ArrowRight.vue";
var script$7 = defineComponent({});
const _hoisted_1$5 = {
viewBox: "0 0 1024 1024",
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44"
};
const _hoisted_2$5 = /*#__PURE__*/createElementVNode("path", {
fill: "#FFF",
d: "M744.81 959.5c99.37-180.1 116.14-454.76-274.34-445.6v221.85L134.82 400.12 470.46 64.5v217.1c467.59-12.2 519.68 412.74 274.35 677.9z"
}, null, -1 /* HOISTED */);
const _hoisted_3$5 = [
_hoisted_2$5
];
function render$7(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$5, _hoisted_3$5))
}
script$7.render = render$7;
script$7.__file = "src/PhotoSlider/RotateLeft.vue";
var script$6 = defineComponent({});
const _hoisted_1$4 = {
viewBox: "0 0 1000 1000",
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44"
};
const _hoisted_2$4 = /*#__PURE__*/createElementVNode("path", {
fill: "#FFF",
d: "M555.668 258.9754V47.24496791175579l327.3385 327.3241L555.668 701.8941V485.52881146582615c-380.8294-8.9369-364.4728 258.9334-267.5596 434.5814C48.8389 661.5105 99.6385 247.0815 555.668 258.9754z"
}, null, -1 /* HOISTED */);
const _hoisted_3$4 = [
_hoisted_2$4
];
function render$6(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$4, _hoisted_3$4))
}
script$6.render = render$6;
script$6.__file = "src/PhotoSlider/RotateRight.vue";
var script$5 = defineComponent({});
const _hoisted_1$3 = {
viewBox: "0 0 1024 1024",
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44"
};
const _hoisted_2$3 = /*#__PURE__*/createElementVNode("path", {
fill: "#FFF",
d: "M978.432 492.832l-153.696-116.896c-17.504-13.312-31.968-6.208-32.096 15.776L792.032 480H231.968l-0.608-88.288c-0.16-22.016-14.592-29.088-32.096-15.776l-153.696 116.896c-17.504 13.312-17.12 34.592 0.864 47.264l154.144 108.608c17.984 12.672 32.576 5.056 32.416-16.96L232.384 544h559.2l-0.576 87.712c-0.16 22.016 14.432 29.632 32.416 16.96l154.144-108.608c17.984-12.672 18.4-33.92 0.864-47.232z"
}, null, -1 /* HOISTED */);
const _hoisted_3$3 = [
_hoisted_2$3
];
function render$5(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$3, _hoisted_3$3))
}
script$5.render = render$5;
script$5.__file = "src/PhotoSlider/FlipHorizontal.vue";
var script$4 = defineComponent({});
const _hoisted_1$2 = {
viewBox: "0 0 1024 1024",
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
width: "44",
height: "44"
};
const _hoisted_2$2 = /*#__PURE__*/createElementVNode("path", {
fill: "#FFF",
d: "M494.03 74.72l-109.59 144.09c-12.48 16.41-5.82 29.97 14.79000001 30.09L482 249.47 482 774.53l-82.77 0.54c-20.64 0.15-27.27 13.68-14.79 30.09l109.59 144.09c12.48 16.41 32.43 16.05 44.31000001-0.81l101.81999999-144.51c11.88-16.86 4.74-30.54-15.9-30.39L542.00000001 774.14l-1e-8-524.25 82.23 0.54c20.64 0.15 27.78-13.53 15.9-30.39l-101.82-144.51c-11.88-16.86-31.8-17.25-44.28-0.81z"
}, null, -1 /* HOISTED */);
const _hoisted_3$2 = [
_hoisted_2$2
];
function render$4(_ctx, _cache, $props, $setup, $data, $options) {
return (openBlock(), createElementBlock("svg", _hoisted_1$2, _hoisted_3$2))
}
script$4.render = render$4;
script$4.__file = "src/PhotoSlider/FlipVertical.vue";
var script$3 = defineComponent({});
const _hoisted_1$1 = {
viewBox: "0 0 1068 1024",
version: "1.1",
xmlns: "http://www.w3.org/2000/svg",
"p-id": "2740",
width: "44",
height: "44"
};
const _hoisted_2$1 = /*#__PURE__*/createElementVNode("path", {
d: "M252.622237 809.004596a252.614304 252.614304 0 0 1-31.486765-503.2587v-4.352863a301.406611 301.406611 0 0 1 594.880633-68.660847 288.877568 288.877568 0 0 1-36.146765 575.488683 31.529129 31.529129 0 0 1 0-63.047667 225.819311 225.819311 0 0 0 8.472726-451.479758l-26.244267-0.974363-3.812726-25.990085a238.358944 238.358944 0 0 0-474.176071 34.664037 243.040125 243.040125 0 0 0 1.874591 30.035812l4.501135 35.786673-37.163491-0.3495h-0.730773c-104.521657 0-189.577228 85.034389-189.577228 189.577228s85.034389 189.577228 189.577228 189.577228a31.529129 31.529129 0 0 1 0 63.047667z",
fill: "#FFF"
}, null, -1 /* HOISTED */);
const _hoisted_3$1 = /*#__PURE__*/createElementVNode("path", {
d: "M500.417679 442.421546m10.590906 0l46.599989 0q10.590907 0 10.590907 10.590906l0 528.878103q0 10.590907-10.590907