[bugfix] ImagePreview: wrong index (#1961)

This commit is contained in:
neverland 2018-10-24 21:11:37 +08:00 committed by GitHub
parent 4b63a62822
commit d0b8595b50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 188 additions and 1923 deletions

View File

@ -72,7 +72,7 @@
"@babel/preset-env": "^7.1.0", "@babel/preset-env": "^7.1.0",
"@vue/server-test-utils": "^1.0.0-beta.25", "@vue/server-test-utils": "^1.0.0-beta.25",
"@vue/test-utils": "^1.0.0-beta.25", "@vue/test-utils": "^1.0.0-beta.25",
"autoprefixer": "^9.1.5", "autoprefixer": "^9.3.0",
"babel-core": "^7.0.0-0", "babel-core": "^7.0.0-0",
"babel-jest": "^23.6.0", "babel-jest": "^23.6.0",
"babel-loader": "^8.0.4", "babel-loader": "^8.0.4",
@ -80,22 +80,22 @@
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"css-loader": "^1.0.0", "css-loader": "^1.0.0",
"dependency-tree": "^6.2.1", "dependency-tree": "^6.2.1",
"eslint": "^5.6.1", "eslint": "^5.7.0",
"eslint-plugin-vue-libs": "^3.0.0", "eslint-plugin-vue-libs": "^3.0.0",
"fast-glob": "^2.2.3", "fast-glob": "^2.2.3",
"fast-vue-md-loader": "^1.0.3", "fast-vue-md-loader": "^1.0.3",
"gh-pages": "^2.0.1", "gh-pages": "^2.0.1",
"gulp": "^3.9.1", "gulp": "^3.9.1",
"gulp-iconfont": "^10.0.1", "gulp-iconfont": "^10.0.2",
"gulp-iconfont-css": "^2.3.0", "gulp-iconfont-css": "^2.3.0",
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"husky": "^1.1.1", "husky": "^1.1.2",
"jest": "^23.6.0", "jest": "^23.6.0",
"jest-serializer-vue": "^2.0.2", "jest-serializer-vue": "^2.0.2",
"lint-staged": "^7.3.0", "lint-staged": "^7.3.0",
"md5-file": "^4.0.0", "md5-file": "^4.0.0",
"postcss": "^7.0.5", "postcss": "^7.0.5",
"postcss-calc": "^6.0.2", "postcss-calc": "^7.0.0",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"precss": "3.1.2", "precss": "3.1.2",
"progress-bar-webpack-plugin": "^1.11.0", "progress-bar-webpack-plugin": "^1.11.0",
@ -106,17 +106,17 @@
"stylelint": "^9.6.0", "stylelint": "^9.6.0",
"stylelint-config-standard": "^18.2.0", "stylelint-config-standard": "^18.2.0",
"uppercamelcase": "^3.0.0", "uppercamelcase": "^3.0.0",
"url-loader": "^1.1.1", "url-loader": "^1.1.2",
"vant-doc": "1.0.17", "vant-doc": "1.0.18",
"vue": "2.5.17", "vue": "2.5.17",
"vue-jest": "^2.6.0", "vue-jest": "^3.0.0",
"vue-loader": "^15.4.2", "vue-loader": "^15.4.2",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue-server-renderer": "^2.5.17", "vue-server-renderer": "^2.5.17",
"vue-sfc-compiler": "^0.1.3", "vue-sfc-compiler": "^0.1.3",
"vue-template-compiler": "2.5.17", "vue-template-compiler": "2.5.17",
"vue-template-es2015-compiler": "^1.6.0", "vue-template-es2015-compiler": "^1.6.0",
"webpack": "^4.20.2", "webpack": "^4.22.0",
"webpack-cli": "^3.1.2", "webpack-cli": "^3.1.2",
"webpack-serve": "^2.0.2" "webpack-serve": "^2.0.2"
} }

View File

@ -83,7 +83,7 @@ export default create({
moveY: 0, moveY: 0,
moving: false, moving: false,
zooming: false, zooming: false,
active: this.startPosition active: 0
}; };
}, },
@ -108,6 +108,10 @@ export default create({
}, },
watch: { watch: {
value() {
this.active = this.startPosition;
},
startPosition(active) { startPosition(active) {
this.active = active; this.active = active;
} }
@ -122,7 +126,7 @@ export default create({
event.preventDefault(); event.preventDefault();
const deltaTime = new Date() - this.touchStartTime; const deltaTime = new Date() - this.touchStartTime;
const { offsetX, offsetY } = this.$refs.swipe; const { offsetX = 0, offsetY = 0 } = this.$refs.swipe || {};
// prevent long tap to close component // prevent long tap to close component
if (deltaTime < 300 && offsetX < 10 && offsetY < 10) { if (deltaTime < 300 && offsetX < 10 && offsetY < 10) {
@ -164,9 +168,10 @@ export default create({
onTouchStart(event) { onTouchStart(event) {
const { touches } = event; const { touches } = event;
const { offsetX } = this.$refs.swipe; const { offsetX } = this.$refs.swipe;
if (touches.length === 1 && this.scale !== 1) { if (touches.length === 1 && this.scale !== 1) {
this.startMove(event); this.startMove(event);
} else if (touches.length === 2 && !offsetX) { } /* istanbul ignore else */ else if (touches.length === 2 && !offsetX) {
this.startZoom(event); this.startZoom(event);
} }
}, },
@ -194,6 +199,7 @@ export default create({
}, },
onTouchEnd(event) { onTouchEnd(event) {
/* istanbul ignore else */
if (this.moving || this.zooming) { if (this.moving || this.zooming) {
let stopPropagation = true; let stopPropagation = true;

View File

@ -19,3 +19,23 @@ exports[`render image 1`] = `
</div> </div>
</div> </div>
`; `;
exports[`zoom 1`] = `
<div class="van-image-preview">
<div class="van-image-preview__index">1/3</div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 300px;">
<div class="van-swipe-item" style="width: 100px; height: 100%;">
<img src="https://img.yzcdn.cn/1.png" class="van-image-preview__image">
</div>
<div class="van-swipe-item" style="width: 100px; height: 100%;">
<img src="https://img.yzcdn.cn/2.png" class="van-image-preview__image">
</div>
<div class="van-swipe-item" style="width: 100px; height: 100%;">
<img src="https://img.yzcdn.cn/3.png" class="van-image-preview__image">
</div>
</div>
<!---->
</div>
</div>
`;

View File

@ -1,7 +1,16 @@
import Vue from 'vue'; import Vue from 'vue';
import ImagePreview from '..'; import ImagePreview from '..';
import ImagePreviewVue from '../ImagePreview'; import ImagePreviewVue from '../ImagePreview';
import { mount, triggerDrag } from '../../../test/utils'; import { mount, trigger, triggerDrag } from '../../../test/utils';
function triggerZoom(el, x, y) {
trigger(el, 'touchstart', 0, 0, { x, y });
trigger(el, 'touchmove', -x / 4, -y / 4, { x, y });
trigger(el, 'touchmove', -x / 3, -y / 3, { x, y });
trigger(el, 'touchmove', -x / 2, -y / 2, { x, y });
trigger(el, 'touchmove', -x, -y, { x, y });
trigger(el, 'touchend', 0, 0, { touchList: [] });
}
const images = [ const images = [
'https://img.yzcdn.cn/1.png', 'https://img.yzcdn.cn/1.png',
@ -60,3 +69,18 @@ test('register component', () => {
Vue.use(ImagePreview); Vue.use(ImagePreview);
expect(Vue.component(ImagePreviewVue.name)).toBeTruthy(); expect(Vue.component(ImagePreviewVue.name)).toBeTruthy();
}); });
test('zoom', async() => {
const getBoundingClientRect = Element.prototype.getBoundingClientRect;
Element.prototype.getBoundingClientRect = jest.fn(() => ({ width: 100 }));
const wrapper = mount(ImagePreviewVue, {
propsData: { images, value: true }
});
const image = wrapper.find('img');
triggerZoom(image, 300, 300);
triggerDrag(image, 300, 300);
expect(wrapper).toMatchSnapshot();
Element.prototype.getBoundingClientRect = getBoundingClientRect;
});

View File

@ -8,10 +8,8 @@ export {
mount mount
}; };
// Trigger pointer/touch event function getTouch(el, x, y) {
export function trigger(wrapper, eventName, x = 0, y = 0) { return {
const el = wrapper.element ? wrapper.element : wrapper;
const touch = {
identifier: Date.now(), identifier: Date.now(),
target: el, target: el,
pageX: x, pageX: x,
@ -23,12 +21,22 @@ export function trigger(wrapper, eventName, x = 0, y = 0) {
rotationAngle: 10, rotationAngle: 10,
force: 0.5 force: 0.5
}; };
}
// Trigger pointer/touch event
export function trigger(wrapper, eventName, x = 0, y = 0, options = {}) {
const el = wrapper.element ? wrapper.element : wrapper;
const touchList = options.touchList || [getTouch(el, x, y)];
if (options.x || options.y) {
touchList.push(getTouch(el, options.x, options.y));
}
const event = document.createEvent('CustomEvent'); const event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, true, true, {}); event.initCustomEvent(eventName, true, true, {});
event.touches = [touch]; event.touches = touchList;
event.targetTouches = [touch]; event.targetTouches = touchList;
event.changedTouches = [touch]; event.changedTouches = touchList;
event.clientX = x; event.clientX = x;
event.clientY = y; event.clientY = y;

2013
yarn.lock

File diff suppressed because it is too large Load Diff