mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
feat(ImagePreview): fit window resize (#6760)
* feat(ImagePreview): fit window resize * fix(ImagePreview): incorrect max move
This commit is contained in:
parent
7987287be0
commit
3748ab646c
@ -1,9 +1,11 @@
|
|||||||
// Utils
|
// Utils
|
||||||
|
import { inBrowser } from '../utils';
|
||||||
import { bem, createComponent } from './shared';
|
import { bem, createComponent } from './shared';
|
||||||
|
|
||||||
// Mixins
|
// Mixins
|
||||||
import { PopupMixin } from '../mixins/popup';
|
import { PopupMixin } from '../mixins/popup';
|
||||||
import { TouchMixin } from '../mixins/touch';
|
import { TouchMixin } from '../mixins/touch';
|
||||||
|
import { BindEventMixin } from '../mixins/bind-event';
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
@ -12,10 +14,13 @@ import ImagePreviewItem from './ImagePreviewItem';
|
|||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
mixins: [
|
mixins: [
|
||||||
|
TouchMixin,
|
||||||
PopupMixin({
|
PopupMixin({
|
||||||
skipToggleEvent: true,
|
skipToggleEvent: true,
|
||||||
}),
|
}),
|
||||||
TouchMixin,
|
BindEventMixin(function (bind) {
|
||||||
|
bind(window, 'resize', this.resize, true);
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
@ -72,10 +77,16 @@ export default createComponent({
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
active: 0,
|
active: 0,
|
||||||
|
windowWidth: 0,
|
||||||
|
windowHeight: 0,
|
||||||
doubleClickTimer: null,
|
doubleClickTimer: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.resize();
|
||||||
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
startPosition: 'setActive',
|
startPosition: 'setActive',
|
||||||
|
|
||||||
@ -95,6 +106,13 @@ export default createComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
resize() {
|
||||||
|
if (inBrowser) {
|
||||||
|
this.windowWidth = window.innerWidth;
|
||||||
|
this.windowHeight = window.innerHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
emitClose() {
|
emitClose() {
|
||||||
if (!this.asyncClose) {
|
if (!this.asyncClose) {
|
||||||
this.$emit('input', false);
|
this.$emit('input', false);
|
||||||
@ -151,6 +169,8 @@ export default createComponent({
|
|||||||
active={this.active}
|
active={this.active}
|
||||||
maxZoom={this.maxZoom}
|
maxZoom={this.maxZoom}
|
||||||
minZoom={this.minZoom}
|
minZoom={this.minZoom}
|
||||||
|
windowWidth={this.windowWidth}
|
||||||
|
windowHeight={this.windowHeight}
|
||||||
onScale={this.emitScale}
|
onScale={this.emitScale}
|
||||||
onClose={this.emitClose}
|
onClose={this.emitClose}
|
||||||
/>
|
/>
|
||||||
|
@ -27,25 +27,30 @@ export default {
|
|||||||
active: Number,
|
active: Number,
|
||||||
minZoom: [Number, String],
|
minZoom: [Number, String],
|
||||||
maxZoom: [Number, String],
|
maxZoom: [Number, String],
|
||||||
|
windowWidth: Number,
|
||||||
|
windowHeight: Number,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
this.windowWidth = window.innerWidth;
|
|
||||||
this.windowHeight = window.innerHeight;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
scale: 1,
|
scale: 1,
|
||||||
moveX: 0,
|
moveX: 0,
|
||||||
moveY: 0,
|
moveY: 0,
|
||||||
moving: false,
|
moving: false,
|
||||||
zooming: false,
|
zooming: false,
|
||||||
vertical: false,
|
imageRatio: 0,
|
||||||
displayWidth: 0,
|
displayWidth: 0,
|
||||||
displayHeight: 0,
|
displayHeight: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
vertical() {
|
||||||
|
const { windowWidth, windowHeight } = this;
|
||||||
|
const windowRatio = windowHeight / windowWidth;
|
||||||
|
return this.imageRatio > windowRatio;
|
||||||
|
},
|
||||||
|
|
||||||
imageStyle() {
|
imageStyle() {
|
||||||
const { scale } = this;
|
const { scale } = this;
|
||||||
const style = {
|
const style = {
|
||||||
@ -62,22 +67,29 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
maxMoveX() {
|
maxMoveX() {
|
||||||
if (this.displayWidth) {
|
if (this.imageRatio) {
|
||||||
return Math.max(
|
const displayWidth = this.vertical
|
||||||
0,
|
? this.windowHeight / this.imageRatio
|
||||||
(this.scale * this.displayWidth - this.windowWidth) / 2
|
: this.windowWidth;
|
||||||
);
|
|
||||||
|
return Math.max(0, (this.scale * displayWidth - this.windowWidth) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
maxMoveY() {
|
maxMoveY() {
|
||||||
if (this.displayHeight) {
|
if (this.imageRatio) {
|
||||||
|
const displayHeight = this.vertical
|
||||||
|
? this.windowHeight
|
||||||
|
: this.windowWidth * this.imageRatio;
|
||||||
|
|
||||||
return Math.max(
|
return Math.max(
|
||||||
0,
|
0,
|
||||||
(this.scale * this.displayHeight - this.windowHeight) / 2
|
(this.scale * displayHeight - this.windowHeight) / 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -225,20 +237,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onLoad(event) {
|
onLoad(event) {
|
||||||
const { windowWidth, windowHeight } = this;
|
|
||||||
const { naturalWidth, naturalHeight } = event.target;
|
const { naturalWidth, naturalHeight } = event.target;
|
||||||
const windowRatio = windowHeight / windowWidth;
|
this.imageRatio = naturalHeight / naturalWidth;
|
||||||
const imageRatio = naturalHeight / naturalWidth;
|
|
||||||
|
|
||||||
this.vertical = imageRatio > windowRatio;
|
|
||||||
|
|
||||||
if (this.vertical) {
|
|
||||||
this.displayWidth = windowHeight / imageRatio;
|
|
||||||
this.displayHeight = windowHeight;
|
|
||||||
} else {
|
|
||||||
this.displayWidth = windowWidth;
|
|
||||||
this.displayHeight = windowWidth * imageRatio;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
31
src/mixins/bind-event.js
Normal file
31
src/mixins/bind-event.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Bind event when mounted or activated
|
||||||
|
*/
|
||||||
|
import { on, off } from '../utils/dom/event';
|
||||||
|
|
||||||
|
let uid = 0;
|
||||||
|
|
||||||
|
export function BindEventMixin(handler) {
|
||||||
|
const key = `binded_${uid++}`;
|
||||||
|
|
||||||
|
function bind() {
|
||||||
|
if (!this[key]) {
|
||||||
|
handler.call(this, on, true);
|
||||||
|
this[key] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function unbind() {
|
||||||
|
if (this[key]) {
|
||||||
|
handler.call(this, off, false);
|
||||||
|
this[key] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
mounted: bind,
|
||||||
|
activated: bind,
|
||||||
|
deactivated: unbind,
|
||||||
|
beforeDestroy: unbind,
|
||||||
|
};
|
||||||
|
}
|
@ -1,33 +0,0 @@
|
|||||||
/**
|
|
||||||
* Bind event when mounted or activated
|
|
||||||
*/
|
|
||||||
import { on, off } from '../utils/dom/event';
|
|
||||||
|
|
||||||
type BindEventMixinThis = {
|
|
||||||
binded: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type BindEventHandler = (bind: Function, isBind: boolean) => void;
|
|
||||||
|
|
||||||
export function BindEventMixin(handler: BindEventHandler) {
|
|
||||||
function bind(this: BindEventMixinThis) {
|
|
||||||
if (!this.binded) {
|
|
||||||
handler.call(this, on, true);
|
|
||||||
this.binded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function unbind(this: BindEventMixinThis) {
|
|
||||||
if (this.binded) {
|
|
||||||
handler.call(this, off, false);
|
|
||||||
this.binded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
mounted: bind,
|
|
||||||
activated: bind,
|
|
||||||
deactivated: unbind,
|
|
||||||
beforeDestroy: unbind,
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user