tiny-vue/packages/renderless/src/image-viewer/vue.ts

273 lines
6.8 KiB
TypeScript

/**
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import {
computedIsSingle,
watchVisible,
computedIsFirst,
computedIsLast,
computedCurrentImg,
computedImgStyle,
hide,
deviceSupportInstall,
deviceSupportUninstall,
handleImgLoad,
handleImgError,
handleMouseDown,
reset,
toggleMode,
prev,
next,
handleActions,
handleVisible,
getImageWidth,
swipeLeft,
swipeRight,
handleDelete,
touchstart,
touchmove,
touchend,
computeZIndex,
activeItems,
imagePreview,
initPage,
beforeDestroy,
itemClick,
selectOption,
langClick,
getLastPrev,
getDefaultPrev,
getCenterPosition,
filterImageUrl
} from './index'
export const api = [
'state',
'zIndex',
'touchstart',
'touchmove',
'touchend',
'urlList',
'hide',
'prev',
'next',
'handleActions',
'toggleMode',
'handleImgLoad',
'handleImgError',
'handleMouseDown',
'handleVisible',
'swipeLeft',
'swipeRight',
'handleDelete',
'activeItems',
'imagePreview',
'itemClick',
'selectOption',
'langClick'
]
const initState = ({ reactive, computed, api, mode, props, constants, inject }) => {
const state = reactive({
originScale: '',
moveable: false,
pageX: '',
pageY: '',
pageY2: '',
pageX2: '',
mfPreviewVisible: inject('mfPreviewVisible', null),
scale: 1,
time: null,
index: mode === 'pc' || mode === 'mobile-first' ? 0 : props.startPosition,
imageName: '',
isShow: false,
infinite: true,
loading: false,
transform: { scale: 1, deg: 0, offsetX: 0, offsetY: 0, objfit: 'contain', enableTransition: false },
urlList:
props.urlList || (Array.isArray(inject('urlList')) && inject('urlList').length !== 0) ? inject('urlList') : null,
mode: constants.MODE.CONTAIN,
previewVisible: props.previewVisible,
fullScreen: props.imageFullCurrent,
hammer: null,
imageItemWidth: 0,
imageAllWidth: 0,
imageTransform: 0,
imageTransformSize: 0,
imageTransition: 300,
imageList: null,
arrowStyle: null,
delete: false,
isLast: computed(() => api.computedIsLast()),
isFirst: computed(() => api.computedIsFirst()),
isSingle: computed(() => api.computedIsSingle()),
imgStyle: computed(() => api.computedImgStyle()),
currentImg: computed(() => api.computedCurrentImg()),
zIndex: computed(() => api.computeZIndex()),
currentIndex: 0,
mobileCurrentIndex: -1,
isImagePreview: false,
hiddenThumbnail: false,
firstX: 0,
endX: 0,
showImageViewer: true,
isThumbnail: props.isThumbnail,
isMenuView: props.isMenuView,
showFlag: 0,
boxVisibility: false,
fileName: '',
scrollTop: 0,
thumbnailTop: constants.THUMBNAILTOP,
menuTop: constants.MENUTOP,
centerIndex: -1
})
return state
}
const initApi = ({ api, state, props, parent, nextTick, emit, t, constants, vm, mode }) => {
Object.assign(api, {
state,
touchstart: touchstart({ state, mode, api }),
touchmove: touchmove(state),
touchend: touchend(state),
reset: reset(state),
prev: prev({ state, api, vm }),
next: next({ state, api, vm }),
getImageWidth: getImageWidth({ state, parent, props, nextTick, vm, mode }),
handleVisible: handleVisible({ state, emit, props }),
handleActions: handleActions(state, props, emit),
handleImgLoad: handleImgLoad(state),
handleMouseDown: handleMouseDown(state),
computedIsFirst: computedIsFirst(state),
computedIsSingle: computedIsSingle(props),
handleImgError: handleImgError({ state, t }),
computedIsLast: computedIsLast({ state, props }),
watchVisible: watchVisible(state),
deviceSupportUninstall: deviceSupportUninstall({ state, mode }),
computedCurrentImg: computedCurrentImg({ state, api }),
computedImgStyle: computedImgStyle({ state, constants }),
computeZIndex: computeZIndex({ constants, props }),
hide: hide({ props, api, state }),
deviceSupportInstall: deviceSupportInstall({ state, api, mode }),
toggleMode: toggleMode({ state, constants, api }),
swipeRight: swipeRight({ api, state, emit }),
swipeLeft: swipeLeft({ api, state, emit }),
handleDelete: handleDelete({ api, state, emit }),
activeItems: activeItems(state),
imagePreview: imagePreview(state),
initPage: initPage({ state, nextTick, api }),
beforeDestroy: beforeDestroy({ api, state }),
itemClick: itemClick({ state, vm, nextTick }),
selectOption: selectOption({ state, api }),
langClick: langClick(state),
getLastPrev: getLastPrev({ state, vm }),
getDefaultPrev: getDefaultPrev({ state, vm }),
getCenterPosition: getCenterPosition({ state, vm }),
filterImageUrl: filterImageUrl()
})
}
const initWatch = ({ watch, state, api, props, nextTick, vm }) => {
watch(
() => state.index,
(value) => {
if (!props.keepStyle) {
api.reset()
}
props.onSwitch(value)
},
{ immediate: true }
)
watch(
() => props.previewVisible,
(value) => {
api.watchVisible(value)
if (props.previewVisible || state.mfPreviewVisible) {
nextTick(() => {
api.getImageWidth()
})
}
},
{ immediate: true }
)
watch(
() => state.currentImg,
(value) => {
nextTick(() => {
const index = state.urlList.indexOf(value)
let imageIns = vm.$refs[`img_${index}`]
if (Array.isArray(imageIns)) {
imageIns = imageIns[0]
}
if (imageIns) {
state.loading = !imageIns.complete
}
})
},
{ immediate: true }
)
watch(
() => state.isImagePreview,
() =>
nextTick(() => {
api.getImageWidth()
})
)
watch(
() => props.urlList,
() => {
state.urlList = props.urlList
},
{ deep: true }
)
}
export const renderless = (
props,
{ computed, onMounted, onBeforeUnmount, onUpdated, reactive, watch, inject, provide },
{ t, parent, nextTick, emit, constants, vm, mode }
) => {
const api = {}
const state = initState({ reactive, computed, api, mode, props, constants, inject })
initApi({ api, state, props, parent, nextTick, emit, t, constants, vm, mode })
initWatch({ watch, state, api, props, nextTick, vm })
onMounted(api.deviceSupportInstall)
onUpdated(() => {
if (props.asyncClose) {
setTimeout(() => {
state.previewVisible = false
emit('update:preview-visible', false)
}, 3000)
}
})
onBeforeUnmount(api.beforeDestroy)
provide('change-size', true)
return api
}