vant 4.3.0 → 4.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/vant.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { unref, ref, reactive, inject, watch, onMounted, nextTick, createVNode, defineComponent, getCurrentInstance, computed, onActivated, onDeactivated, onBeforeUnmount, provide, watchEffect, mergeProps, Transition, withDirectives, vShow, Teleport, Fragment, onBeforeUpdate, createTextVNode, onUnmounted, createApp, resolveDirective, withKeys, onUpdated, Comment, Text, h } from "vue";
2
- import { useWindowSize, useRect, useChildren, useParent, onMountedOrActivated, getScrollParent, useEventListener, raf, useScrollParent, usePageVisibility, doubleRaf, CUSTOM_FIELD_INJECTION_KEY, useCustomFieldValue, inBrowser as inBrowser$1, useToggle, cancelRaf, useCountDown, useClickAway } from "@vant/use";
2
+ import { useWindowSize, useRect, useChildren, useParent, onMountedOrActivated, getScrollParent, useEventListener, cancelRaf, raf, useScrollParent, usePageVisibility, doubleRaf, CUSTOM_FIELD_INJECTION_KEY, useCustomFieldValue, inBrowser as inBrowser$1, useToggle, useCountDown, useClickAway } from "@vant/use";
3
3
  import { offsetModifier, createPopper } from "@vant/popperjs";
4
4
  const isDef = (val) => val !== void 0 && val !== null;
5
5
  const isFunction = (val) => typeof val === "function";
@@ -1861,23 +1861,46 @@ var stdin_default$1B = defineComponent({
1861
1861
  }, [slots.toolbar ? slots.toolbar() : [renderCancel(), renderTitle(), renderConfirm()]]);
1862
1862
  }
1863
1863
  });
1864
+ const useSyncPropRef = (getProp, setProp) => {
1865
+ const propRef = ref(getProp());
1866
+ watch(getProp, (value) => {
1867
+ if (value !== propRef.value) {
1868
+ propRef.value = value;
1869
+ }
1870
+ });
1871
+ watch(propRef, (value) => {
1872
+ if (value !== getProp()) {
1873
+ setProp(value);
1874
+ }
1875
+ });
1876
+ return propRef;
1877
+ };
1864
1878
  function scrollLeftTo(scroller, to, duration) {
1879
+ let rafId;
1865
1880
  let count = 0;
1866
1881
  const from = scroller.scrollLeft;
1867
1882
  const frames = duration === 0 ? 1 : Math.round(duration * 1e3 / 16);
1883
+ function cancel() {
1884
+ cancelRaf(rafId);
1885
+ }
1868
1886
  function animate() {
1869
1887
  scroller.scrollLeft += (to - from) / frames;
1870
1888
  if (++count < frames) {
1871
- raf(animate);
1889
+ rafId = raf(animate);
1872
1890
  }
1873
1891
  }
1874
1892
  animate();
1893
+ return cancel;
1875
1894
  }
1876
1895
  function scrollTopTo(scroller, to, duration, callback) {
1896
+ let rafId;
1877
1897
  let current2 = getScrollTop(scroller);
1878
1898
  const isDown = current2 < to;
1879
1899
  const frames = duration === 0 ? 1 : Math.round(duration * 1e3 / 16);
1880
1900
  const step = (to - current2) / frames;
1901
+ function cancel() {
1902
+ cancelRaf(rafId);
1903
+ }
1881
1904
  function animate() {
1882
1905
  current2 += step;
1883
1906
  if (isDown && current2 > to || !isDown && current2 < to) {
@@ -1885,12 +1908,13 @@ function scrollTopTo(scroller, to, duration, callback) {
1885
1908
  }
1886
1909
  setScrollTop(scroller, current2);
1887
1910
  if (isDown && current2 < to || !isDown && current2 > to) {
1888
- raf(animate);
1911
+ rafId = raf(animate);
1889
1912
  } else if (callback) {
1890
- raf(callback);
1913
+ rafId = raf(callback);
1891
1914
  }
1892
1915
  }
1893
1916
  animate();
1917
+ return cancel;
1894
1918
  }
1895
1919
  let current = 0;
1896
1920
  function useId() {
@@ -2533,6 +2557,8 @@ var stdin_default$1x = defineComponent({
2533
2557
  let tabHeight;
2534
2558
  let lockScroll;
2535
2559
  let stickyFixed;
2560
+ let cancelScrollLeftToRaf;
2561
+ let cancelScrollTopToRaf;
2536
2562
  const root = ref();
2537
2563
  const navRef = ref();
2538
2564
  const wrapRef = ref();
@@ -2580,7 +2606,9 @@ var stdin_default$1x = defineComponent({
2580
2606
  }
2581
2607
  const title = titles[state.currentIndex].$el;
2582
2608
  const to = title.offsetLeft - (nav.offsetWidth - title.offsetWidth) / 2;
2583
- scrollLeftTo(nav, to, immediate ? 0 : +props.duration);
2609
+ if (cancelScrollLeftToRaf)
2610
+ cancelScrollLeftToRaf();
2611
+ cancelScrollLeftToRaf = scrollLeftTo(nav, to, immediate ? 0 : +props.duration);
2584
2612
  };
2585
2613
  const setLine = () => {
2586
2614
  const shouldAnimate = state.inited;
@@ -2656,7 +2684,9 @@ var stdin_default$1x = defineComponent({
2656
2684
  if (target && scroller.value) {
2657
2685
  const to = getElementTop(target, scroller.value) - scrollOffset.value;
2658
2686
  lockScroll = true;
2659
- scrollTopTo(scroller.value, to, immediate ? 0 : +props.duration, () => {
2687
+ if (cancelScrollTopToRaf)
2688
+ cancelScrollTopToRaf();
2689
+ cancelScrollTopToRaf = scrollTopTo(scroller.value, to, immediate ? 0 : +props.duration, () => {
2660
2690
  lockScroll = false;
2661
2691
  });
2662
2692
  }
@@ -3125,26 +3155,27 @@ const [name$1j, bem$1f] = createNamespace("picker-group");
3125
3155
  const PICKER_GROUP_KEY = Symbol(name$1j);
3126
3156
  const pickerGroupProps = extend({
3127
3157
  tabs: makeArrayProp(),
3158
+ activeTab: makeNumericProp(0),
3128
3159
  nextStepText: String
3129
3160
  }, pickerToolbarProps);
3130
3161
  var stdin_default$1u = defineComponent({
3131
3162
  name: name$1j,
3132
3163
  props: pickerGroupProps,
3133
- emits: ["confirm", "cancel"],
3164
+ emits: ["confirm", "cancel", "update:activeTab"],
3134
3165
  setup(props, {
3135
3166
  emit,
3136
3167
  slots
3137
3168
  }) {
3138
- const activeTab = ref(0);
3169
+ const activeTab = useSyncPropRef(() => props.activeTab, (value) => emit("update:activeTab", value));
3139
3170
  const {
3140
3171
  children,
3141
3172
  linkChildren
3142
3173
  } = useChildren(PICKER_GROUP_KEY);
3143
3174
  linkChildren();
3144
- const showNextButton = () => activeTab.value < props.tabs.length - 1 && props.nextStepText;
3175
+ const showNextButton = () => +activeTab.value < props.tabs.length - 1 && props.nextStepText;
3145
3176
  const onConfirm = () => {
3146
3177
  if (showNextButton()) {
3147
- activeTab.value++;
3178
+ activeTab.value = +activeTab.value + 1;
3148
3179
  } else {
3149
3180
  emit("confirm", children.map((item) => item.confirm()));
3150
3181
  }
@@ -4312,6 +4343,10 @@ var stdin_default$1p = defineComponent({
4312
4343
  return createVNode("label", {
4313
4344
  "id": `${id}-label`,
4314
4345
  "for": getInputId(),
4346
+ "onClick": (event) => {
4347
+ preventDefault(event);
4348
+ focus();
4349
+ },
4315
4350
  "style": labelAlign === "top" && labelWidth ? {
4316
4351
  width: addUnit(labelWidth)
4317
4352
  } : void 0
@@ -5240,7 +5275,19 @@ var stdin_default$1i = defineComponent({
5240
5275
  return props.parent.props[name2];
5241
5276
  }
5242
5277
  };
5243
- const disabled = computed(() => getParentProp("disabled") || props.disabled);
5278
+ const disabled = computed(() => {
5279
+ if (props.parent && props.bindGroup) {
5280
+ const disabled2 = getParentProp("disabled") || props.disabled;
5281
+ if (props.role === "checkbox") {
5282
+ const checkedCount = getParentProp("modelValue").length;
5283
+ const max = getParentProp("max");
5284
+ const overlimit = max && checkedCount >= +max;
5285
+ return disabled2 || overlimit && !props.checked;
5286
+ }
5287
+ return disabled2;
5288
+ }
5289
+ return props.disabled;
5290
+ });
5244
5291
  const direction = computed(() => getParentProp("direction"));
5245
5292
  const iconStyle = computed(() => {
5246
5293
  const checkedColor = props.checkedColor || getParentProp("checkedColor");
@@ -9604,6 +9651,10 @@ var stdin_default$M = defineComponent({
9604
9651
  });
9605
9652
  const GridItem = withInstall(stdin_default$M);
9606
9653
  const getDistance = (touches) => Math.sqrt((touches[0].clientX - touches[1].clientX) ** 2 + (touches[0].clientY - touches[1].clientY) ** 2);
9654
+ const getCenter = (touches) => ({
9655
+ x: (touches[0].clientX + touches[1].clientX) / 2,
9656
+ y: (touches[0].clientY + touches[1].clientY) / 2
9657
+ });
9607
9658
  const bem$C = createNamespace("image-preview")[1];
9608
9659
  var stdin_default$L = defineComponent({
9609
9660
  props: {
@@ -9632,6 +9683,7 @@ var stdin_default$L = defineComponent({
9632
9683
  displayHeight: 0
9633
9684
  });
9634
9685
  const touch = useTouch();
9686
+ const imageRef = ref();
9635
9687
  const swipeItem = ref();
9636
9688
  const vertical = computed(() => {
9637
9689
  const {
@@ -9653,9 +9705,7 @@ var stdin_default$L = defineComponent({
9653
9705
  transitionDuration: zooming || moving ? "0s" : ".3s"
9654
9706
  };
9655
9707
  if (scale !== 1) {
9656
- const offsetX = moveX / scale;
9657
- const offsetY = moveY / scale;
9658
- style.transform = `scale(${scale}, ${scale}) translate(${offsetX}px, ${offsetY}px)`;
9708
+ style.transform = `matrix(${scale}, 0, 0, ${scale}, ${moveX}, ${moveY})`;
9659
9709
  }
9660
9710
  return style;
9661
9711
  });
@@ -9681,10 +9731,26 @@ var stdin_default$L = defineComponent({
9681
9731
  }
9682
9732
  return 0;
9683
9733
  });
9684
- const setScale = (scale) => {
9734
+ const setScale = (scale, center) => {
9735
+ var _a;
9685
9736
  scale = clamp(scale, +props.minZoom, +props.maxZoom + 1);
9686
9737
  if (scale !== state.scale) {
9738
+ const ratio = scale / state.scale;
9687
9739
  state.scale = scale;
9740
+ if (center) {
9741
+ const imageRect = useRect((_a = imageRef.value) == null ? void 0 : _a.$el);
9742
+ const origin = {
9743
+ x: imageRect.width * 0.5,
9744
+ y: imageRect.height * 0.5
9745
+ };
9746
+ const moveX = state.moveX - (center.x - imageRect.left - origin.x) * (ratio - 1);
9747
+ const moveY = state.moveY - (center.y - imageRect.top - origin.y) * (ratio - 1);
9748
+ state.moveX = clamp(moveX, -maxMoveX.value, maxMoveX.value);
9749
+ state.moveY = clamp(moveY, -maxMoveY.value, maxMoveY.value);
9750
+ } else {
9751
+ state.moveX = 0;
9752
+ state.moveY = 0;
9753
+ }
9688
9754
  emit("scale", {
9689
9755
  scale,
9690
9756
  index: props.active
@@ -9693,20 +9759,20 @@ var stdin_default$L = defineComponent({
9693
9759
  };
9694
9760
  const resetScale = () => {
9695
9761
  setScale(1);
9696
- state.moveX = 0;
9697
- state.moveY = 0;
9698
9762
  };
9699
9763
  const toggleScale = () => {
9700
9764
  const scale = state.scale > 1 ? 1 : 2;
9701
- setScale(scale);
9702
- state.moveX = 0;
9703
- state.moveY = 0;
9765
+ setScale(scale, scale === 2 ? {
9766
+ x: touch.startX.value,
9767
+ y: touch.startY.value
9768
+ } : void 0);
9704
9769
  };
9705
9770
  let fingerNum;
9706
9771
  let startMoveX;
9707
9772
  let startMoveY;
9708
9773
  let startScale;
9709
9774
  let startDistance;
9775
+ let lastCenter;
9710
9776
  let doubleTapTimer;
9711
9777
  let touchStartTime;
9712
9778
  let isImageMoved = false;
@@ -9730,7 +9796,7 @@ var stdin_default$L = defineComponent({
9730
9796
  state.zooming = fingerNum === 2 && !offsetX.value;
9731
9797
  if (state.zooming) {
9732
9798
  startScale = state.scale;
9733
- startDistance = getDistance(event.touches);
9799
+ startDistance = getDistance(touches);
9734
9800
  }
9735
9801
  };
9736
9802
  const onTouchMove = (event) => {
@@ -9759,7 +9825,8 @@ var stdin_default$L = defineComponent({
9759
9825
  if (touches.length === 2) {
9760
9826
  const distance = getDistance(touches);
9761
9827
  const scale = startScale * distance / startDistance;
9762
- setScale(scale);
9828
+ lastCenter = getCenter(touches);
9829
+ setScale(scale, lastCenter);
9763
9830
  }
9764
9831
  }
9765
9832
  };
@@ -9813,7 +9880,7 @@ var stdin_default$L = defineComponent({
9813
9880
  }
9814
9881
  const maxZoom = +props.maxZoom;
9815
9882
  if (state.scale > maxZoom) {
9816
- state.scale = maxZoom;
9883
+ setScale(maxZoom, lastCenter);
9817
9884
  }
9818
9885
  }
9819
9886
  }
@@ -9858,6 +9925,7 @@ var stdin_default$L = defineComponent({
9858
9925
  }, [slots.image({
9859
9926
  src: props.src
9860
9927
  })]) : createVNode(Image$1, {
9928
+ "ref": imageRef,
9861
9929
  "src": props.src,
9862
9930
  "fit": "contain",
9863
9931
  "class": bem$C("image", {
@@ -11388,20 +11456,6 @@ var stdin_default$A = defineComponent({
11388
11456
  });
11389
11457
  const PasswordInput = withInstall(stdin_default$A);
11390
11458
  const PickerGroup = withInstall(stdin_default$1u);
11391
- const useSyncPropRef = (getProp, setProp) => {
11392
- const propRef = ref(getProp());
11393
- watch(getProp, (value) => {
11394
- if (value !== propRef.value) {
11395
- propRef.value = value;
11396
- }
11397
- });
11398
- watch(propRef, (value) => {
11399
- if (value !== getProp()) {
11400
- setProp(value);
11401
- }
11402
- });
11403
- return propRef;
11404
- };
11405
11459
  const [name$r, bem$q] = createNamespace("popover");
11406
11460
  const popupProps = ["overlay", "duration", "teleport", "overlayStyle", "overlayClass", "closeOnClickOverlay"];
11407
11461
  const popoverProps = {
@@ -15523,7 +15577,7 @@ const Lazyload = {
15523
15577
  });
15524
15578
  }
15525
15579
  };
15526
- const version = "4.3.0";
15580
+ const version = "4.3.2";
15527
15581
  function install(app) {
15528
15582
  const components = [
15529
15583
  ActionBar,
package/lib/vant.js CHANGED
@@ -2252,23 +2252,46 @@
2252
2252
  }, [slots.toolbar ? slots.toolbar() : [renderCancel(), renderTitle(), renderConfirm()]]);
2253
2253
  }
2254
2254
  });
2255
+ const useSyncPropRef = (getProp, setProp) => {
2256
+ const propRef = vue.ref(getProp());
2257
+ vue.watch(getProp, (value) => {
2258
+ if (value !== propRef.value) {
2259
+ propRef.value = value;
2260
+ }
2261
+ });
2262
+ vue.watch(propRef, (value) => {
2263
+ if (value !== getProp()) {
2264
+ setProp(value);
2265
+ }
2266
+ });
2267
+ return propRef;
2268
+ };
2255
2269
  function scrollLeftTo(scroller, to, duration) {
2270
+ let rafId;
2256
2271
  let count = 0;
2257
2272
  const from = scroller.scrollLeft;
2258
2273
  const frames = duration === 0 ? 1 : Math.round(duration * 1e3 / 16);
2274
+ function cancel() {
2275
+ cancelRaf(rafId);
2276
+ }
2259
2277
  function animate() {
2260
2278
  scroller.scrollLeft += (to - from) / frames;
2261
2279
  if (++count < frames) {
2262
- raf(animate);
2280
+ rafId = raf(animate);
2263
2281
  }
2264
2282
  }
2265
2283
  animate();
2284
+ return cancel;
2266
2285
  }
2267
2286
  function scrollTopTo(scroller, to, duration, callback) {
2287
+ let rafId;
2268
2288
  let current2 = getScrollTop(scroller);
2269
2289
  const isDown = current2 < to;
2270
2290
  const frames = duration === 0 ? 1 : Math.round(duration * 1e3 / 16);
2271
2291
  const step = (to - current2) / frames;
2292
+ function cancel() {
2293
+ cancelRaf(rafId);
2294
+ }
2272
2295
  function animate() {
2273
2296
  current2 += step;
2274
2297
  if (isDown && current2 > to || !isDown && current2 < to) {
@@ -2276,12 +2299,13 @@
2276
2299
  }
2277
2300
  setScrollTop(scroller, current2);
2278
2301
  if (isDown && current2 < to || !isDown && current2 > to) {
2279
- raf(animate);
2302
+ rafId = raf(animate);
2280
2303
  } else if (callback) {
2281
- raf(callback);
2304
+ rafId = raf(callback);
2282
2305
  }
2283
2306
  }
2284
2307
  animate();
2308
+ return cancel;
2285
2309
  }
2286
2310
  let current = 0;
2287
2311
  function useId() {
@@ -2921,6 +2945,8 @@
2921
2945
  let tabHeight;
2922
2946
  let lockScroll;
2923
2947
  let stickyFixed;
2948
+ let cancelScrollLeftToRaf;
2949
+ let cancelScrollTopToRaf;
2924
2950
  const root = vue.ref();
2925
2951
  const navRef = vue.ref();
2926
2952
  const wrapRef = vue.ref();
@@ -2968,7 +2994,9 @@
2968
2994
  }
2969
2995
  const title = titles[state.currentIndex].$el;
2970
2996
  const to = title.offsetLeft - (nav.offsetWidth - title.offsetWidth) / 2;
2971
- scrollLeftTo(nav, to, immediate ? 0 : +props.duration);
2997
+ if (cancelScrollLeftToRaf)
2998
+ cancelScrollLeftToRaf();
2999
+ cancelScrollLeftToRaf = scrollLeftTo(nav, to, immediate ? 0 : +props.duration);
2972
3000
  };
2973
3001
  const setLine = () => {
2974
3002
  const shouldAnimate = state.inited;
@@ -3044,7 +3072,9 @@
3044
3072
  if (target && scroller.value) {
3045
3073
  const to = getElementTop(target, scroller.value) - scrollOffset.value;
3046
3074
  lockScroll = true;
3047
- scrollTopTo(scroller.value, to, immediate ? 0 : +props.duration, () => {
3075
+ if (cancelScrollTopToRaf)
3076
+ cancelScrollTopToRaf();
3077
+ cancelScrollTopToRaf = scrollTopTo(scroller.value, to, immediate ? 0 : +props.duration, () => {
3048
3078
  lockScroll = false;
3049
3079
  });
3050
3080
  }
@@ -3507,26 +3537,27 @@
3507
3537
  const PICKER_GROUP_KEY = Symbol(name$1j);
3508
3538
  const pickerGroupProps = extend({
3509
3539
  tabs: makeArrayProp(),
3540
+ activeTab: makeNumericProp(0),
3510
3541
  nextStepText: String
3511
3542
  }, pickerToolbarProps);
3512
3543
  var stdin_default$1u = vue.defineComponent({
3513
3544
  name: name$1j,
3514
3545
  props: pickerGroupProps,
3515
- emits: ["confirm", "cancel"],
3546
+ emits: ["confirm", "cancel", "update:activeTab"],
3516
3547
  setup(props, {
3517
3548
  emit,
3518
3549
  slots
3519
3550
  }) {
3520
- const activeTab = vue.ref(0);
3551
+ const activeTab = useSyncPropRef(() => props.activeTab, (value) => emit("update:activeTab", value));
3521
3552
  const {
3522
3553
  children,
3523
3554
  linkChildren
3524
3555
  } = useChildren(PICKER_GROUP_KEY);
3525
3556
  linkChildren();
3526
- const showNextButton = () => activeTab.value < props.tabs.length - 1 && props.nextStepText;
3557
+ const showNextButton = () => +activeTab.value < props.tabs.length - 1 && props.nextStepText;
3527
3558
  const onConfirm = () => {
3528
3559
  if (showNextButton()) {
3529
- activeTab.value++;
3560
+ activeTab.value = +activeTab.value + 1;
3530
3561
  } else {
3531
3562
  emit("confirm", children.map((item) => item.confirm()));
3532
3563
  }
@@ -4694,6 +4725,10 @@
4694
4725
  return vue.createVNode("label", {
4695
4726
  "id": `${id}-label`,
4696
4727
  "for": getInputId(),
4728
+ "onClick": (event) => {
4729
+ preventDefault(event);
4730
+ focus();
4731
+ },
4697
4732
  "style": labelAlign === "top" && labelWidth ? {
4698
4733
  width: addUnit(labelWidth)
4699
4734
  } : void 0
@@ -5622,7 +5657,19 @@
5622
5657
  return props.parent.props[name2];
5623
5658
  }
5624
5659
  };
5625
- const disabled = vue.computed(() => getParentProp("disabled") || props.disabled);
5660
+ const disabled = vue.computed(() => {
5661
+ if (props.parent && props.bindGroup) {
5662
+ const disabled2 = getParentProp("disabled") || props.disabled;
5663
+ if (props.role === "checkbox") {
5664
+ const checkedCount = getParentProp("modelValue").length;
5665
+ const max = getParentProp("max");
5666
+ const overlimit = max && checkedCount >= +max;
5667
+ return disabled2 || overlimit && !props.checked;
5668
+ }
5669
+ return disabled2;
5670
+ }
5671
+ return props.disabled;
5672
+ });
5626
5673
  const direction = vue.computed(() => getParentProp("direction"));
5627
5674
  const iconStyle = vue.computed(() => {
5628
5675
  const checkedColor = props.checkedColor || getParentProp("checkedColor");
@@ -9957,6 +10004,10 @@
9957
10004
  });
9958
10005
  const GridItem = withInstall(stdin_default$M);
9959
10006
  const getDistance = (touches) => Math.sqrt((touches[0].clientX - touches[1].clientX) ** 2 + (touches[0].clientY - touches[1].clientY) ** 2);
10007
+ const getCenter = (touches) => ({
10008
+ x: (touches[0].clientX + touches[1].clientX) / 2,
10009
+ y: (touches[0].clientY + touches[1].clientY) / 2
10010
+ });
9960
10011
  const bem$C = createNamespace("image-preview")[1];
9961
10012
  var stdin_default$L = vue.defineComponent({
9962
10013
  props: {
@@ -9985,6 +10036,7 @@
9985
10036
  displayHeight: 0
9986
10037
  });
9987
10038
  const touch = useTouch();
10039
+ const imageRef = vue.ref();
9988
10040
  const swipeItem = vue.ref();
9989
10041
  const vertical = vue.computed(() => {
9990
10042
  const {
@@ -10006,9 +10058,7 @@
10006
10058
  transitionDuration: zooming || moving ? "0s" : ".3s"
10007
10059
  };
10008
10060
  if (scale !== 1) {
10009
- const offsetX = moveX / scale;
10010
- const offsetY = moveY / scale;
10011
- style.transform = `scale(${scale}, ${scale}) translate(${offsetX}px, ${offsetY}px)`;
10061
+ style.transform = `matrix(${scale}, 0, 0, ${scale}, ${moveX}, ${moveY})`;
10012
10062
  }
10013
10063
  return style;
10014
10064
  });
@@ -10034,10 +10084,26 @@
10034
10084
  }
10035
10085
  return 0;
10036
10086
  });
10037
- const setScale = (scale) => {
10087
+ const setScale = (scale, center) => {
10088
+ var _a;
10038
10089
  scale = clamp(scale, +props.minZoom, +props.maxZoom + 1);
10039
10090
  if (scale !== state.scale) {
10091
+ const ratio = scale / state.scale;
10040
10092
  state.scale = scale;
10093
+ if (center) {
10094
+ const imageRect = useRect((_a = imageRef.value) == null ? void 0 : _a.$el);
10095
+ const origin = {
10096
+ x: imageRect.width * 0.5,
10097
+ y: imageRect.height * 0.5
10098
+ };
10099
+ const moveX = state.moveX - (center.x - imageRect.left - origin.x) * (ratio - 1);
10100
+ const moveY = state.moveY - (center.y - imageRect.top - origin.y) * (ratio - 1);
10101
+ state.moveX = clamp(moveX, -maxMoveX.value, maxMoveX.value);
10102
+ state.moveY = clamp(moveY, -maxMoveY.value, maxMoveY.value);
10103
+ } else {
10104
+ state.moveX = 0;
10105
+ state.moveY = 0;
10106
+ }
10041
10107
  emit("scale", {
10042
10108
  scale,
10043
10109
  index: props.active
@@ -10046,20 +10112,20 @@
10046
10112
  };
10047
10113
  const resetScale = () => {
10048
10114
  setScale(1);
10049
- state.moveX = 0;
10050
- state.moveY = 0;
10051
10115
  };
10052
10116
  const toggleScale = () => {
10053
10117
  const scale = state.scale > 1 ? 1 : 2;
10054
- setScale(scale);
10055
- state.moveX = 0;
10056
- state.moveY = 0;
10118
+ setScale(scale, scale === 2 ? {
10119
+ x: touch.startX.value,
10120
+ y: touch.startY.value
10121
+ } : void 0);
10057
10122
  };
10058
10123
  let fingerNum;
10059
10124
  let startMoveX;
10060
10125
  let startMoveY;
10061
10126
  let startScale;
10062
10127
  let startDistance;
10128
+ let lastCenter;
10063
10129
  let doubleTapTimer;
10064
10130
  let touchStartTime;
10065
10131
  let isImageMoved = false;
@@ -10083,7 +10149,7 @@
10083
10149
  state.zooming = fingerNum === 2 && !offsetX.value;
10084
10150
  if (state.zooming) {
10085
10151
  startScale = state.scale;
10086
- startDistance = getDistance(event.touches);
10152
+ startDistance = getDistance(touches);
10087
10153
  }
10088
10154
  };
10089
10155
  const onTouchMove = (event) => {
@@ -10112,7 +10178,8 @@
10112
10178
  if (touches.length === 2) {
10113
10179
  const distance = getDistance(touches);
10114
10180
  const scale = startScale * distance / startDistance;
10115
- setScale(scale);
10181
+ lastCenter = getCenter(touches);
10182
+ setScale(scale, lastCenter);
10116
10183
  }
10117
10184
  }
10118
10185
  };
@@ -10166,7 +10233,7 @@
10166
10233
  }
10167
10234
  const maxZoom = +props.maxZoom;
10168
10235
  if (state.scale > maxZoom) {
10169
- state.scale = maxZoom;
10236
+ setScale(maxZoom, lastCenter);
10170
10237
  }
10171
10238
  }
10172
10239
  }
@@ -10211,6 +10278,7 @@
10211
10278
  }, [slots.image({
10212
10279
  src: props.src
10213
10280
  })]) : vue.createVNode(Image$1, {
10281
+ "ref": imageRef,
10214
10282
  "src": props.src,
10215
10283
  "fit": "contain",
10216
10284
  "class": bem$C("image", {
@@ -12677,20 +12745,6 @@
12677
12745
  requires: ["popperOffsets"],
12678
12746
  fn: offset
12679
12747
  };
12680
- const useSyncPropRef = (getProp, setProp) => {
12681
- const propRef = vue.ref(getProp());
12682
- vue.watch(getProp, (value) => {
12683
- if (value !== propRef.value) {
12684
- propRef.value = value;
12685
- }
12686
- });
12687
- vue.watch(propRef, (value) => {
12688
- if (value !== getProp()) {
12689
- setProp(value);
12690
- }
12691
- });
12692
- return propRef;
12693
- };
12694
12748
  const [name$r, bem$q] = createNamespace("popover");
12695
12749
  const popupProps = ["overlay", "duration", "teleport", "overlayStyle", "overlayClass", "closeOnClickOverlay"];
12696
12750
  const popoverProps = {
@@ -16783,7 +16837,7 @@
16783
16837
  });
16784
16838
  }
16785
16839
  };
16786
- const version = "4.3.0";
16840
+ const version = "4.3.2";
16787
16841
  function install(app) {
16788
16842
  const components = [
16789
16843
  ActionBar,