diff --git a/src/image-preview/ImagePreview.js b/src/image-preview/ImagePreview.js index 91683ba2a..9c03d4e7c 100644 --- a/src/image-preview/ImagePreview.js +++ b/src/image-preview/ImagePreview.js @@ -1,9 +1,11 @@ // Utils +import { inBrowser } from '../utils'; import { bem, createComponent } from './shared'; // Mixins import { PopupMixin } from '../mixins/popup'; import { TouchMixin } from '../mixins/touch'; +import { BindEventMixin } from '../mixins/bind-event'; // Components import Icon from '../icon'; @@ -12,10 +14,13 @@ import ImagePreviewItem from './ImagePreviewItem'; export default createComponent({ mixins: [ + TouchMixin, PopupMixin({ skipToggleEvent: true, }), - TouchMixin, + BindEventMixin(function (bind) { + bind(window, 'resize', this.resize, true); + }), ], props: { @@ -72,10 +77,16 @@ export default createComponent({ data() { return { active: 0, + windowWidth: 0, + windowHeight: 0, doubleClickTimer: null, }; }, + created() { + this.resize(); + }, + watch: { startPosition: 'setActive', @@ -95,6 +106,13 @@ export default createComponent({ }, methods: { + resize() { + if (inBrowser) { + this.windowWidth = window.innerWidth; + this.windowHeight = window.innerHeight; + } + }, + emitClose() { if (!this.asyncClose) { this.$emit('input', false); @@ -151,6 +169,8 @@ export default createComponent({ active={this.active} maxZoom={this.maxZoom} minZoom={this.minZoom} + windowWidth={this.windowWidth} + windowHeight={this.windowHeight} onScale={this.emitScale} onClose={this.emitClose} /> diff --git a/src/image-preview/ImagePreviewItem.js b/src/image-preview/ImagePreviewItem.js index e05ae5ba8..0c4c2ec0d 100644 --- a/src/image-preview/ImagePreviewItem.js +++ b/src/image-preview/ImagePreviewItem.js @@ -27,25 +27,30 @@ export default { active: Number, minZoom: [Number, String], maxZoom: [Number, String], + windowWidth: Number, + windowHeight: Number, }, data() { - this.windowWidth = window.innerWidth; - this.windowHeight = window.innerHeight; - return { scale: 1, moveX: 0, moveY: 0, moving: false, zooming: false, - vertical: false, + imageRatio: 0, displayWidth: 0, displayHeight: 0, }; }, computed: { + vertical() { + const { windowWidth, windowHeight } = this; + const windowRatio = windowHeight / windowWidth; + return this.imageRatio > windowRatio; + }, + imageStyle() { const { scale } = this; const style = { @@ -62,22 +67,29 @@ export default { }, maxMoveX() { - if (this.displayWidth) { - return Math.max( - 0, - (this.scale * this.displayWidth - this.windowWidth) / 2 - ); + if (this.imageRatio) { + const displayWidth = this.vertical + ? this.windowHeight / this.imageRatio + : this.windowWidth; + + return Math.max(0, (this.scale * displayWidth - this.windowWidth) / 2); } + return 0; }, maxMoveY() { - if (this.displayHeight) { + if (this.imageRatio) { + const displayHeight = this.vertical + ? this.windowHeight + : this.windowWidth * this.imageRatio; + return Math.max( 0, - (this.scale * this.displayHeight - this.windowHeight) / 2 + (this.scale * displayHeight - this.windowHeight) / 2 ); } + return 0; }, }, @@ -225,20 +237,8 @@ export default { }, onLoad(event) { - const { windowWidth, windowHeight } = this; const { naturalWidth, naturalHeight } = event.target; - const windowRatio = windowHeight / windowWidth; - 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; - } + this.imageRatio = naturalHeight / naturalWidth; }, }, diff --git a/src/mixins/bind-event.js b/src/mixins/bind-event.js new file mode 100644 index 000000000..a184f5afa --- /dev/null +++ b/src/mixins/bind-event.js @@ -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, + }; +} diff --git a/src/mixins/bind-event.ts b/src/mixins/bind-event.ts deleted file mode 100644 index 5a54365c8..000000000 --- a/src/mixins/bind-event.ts +++ /dev/null @@ -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, - }; -}