mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
feat: convert zoom control component to conposition API
This commit is contained in:
parent
1adf609b35
commit
8995910cb2
@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
export type TZoomData = {
|
||||||
|
text: string
|
||||||
|
value: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ZoomList: TZoomData[] = [
|
||||||
|
{
|
||||||
|
text: '25%',
|
||||||
|
value: 25,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '50%',
|
||||||
|
value: 50,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '75%',
|
||||||
|
value: 75,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '100%',
|
||||||
|
value: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '125%',
|
||||||
|
value: 125,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '150%',
|
||||||
|
value: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '200%',
|
||||||
|
value: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '最佳尺寸',
|
||||||
|
value: -1,
|
||||||
|
// icon: 'icon-best-size',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
export const OtherList: TZoomData[] = [
|
||||||
|
{
|
||||||
|
text: '250%',
|
||||||
|
value: 250,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '300%',
|
||||||
|
value: 300,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '350%',
|
||||||
|
value: 350,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '400%',
|
||||||
|
value: 400,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '450%',
|
||||||
|
value: 450,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '500%',
|
||||||
|
value: 500,
|
||||||
|
},
|
||||||
|
]
|
@ -19,255 +19,232 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { defineComponent } from 'vue'
|
import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||||
import addMouseWheel from '@/common/methods/addMouseWheel'
|
import addMouseWheel from '@/common/methods/addMouseWheel'
|
||||||
|
import { OtherList, TZoomData, ZoomList } from './data';
|
||||||
|
import { useSetupMapGetters } from '@/common/hooks/mapGetters';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const store = useStore()
|
||||||
|
|
||||||
// 组件大小控制器
|
// 组件大小控制器
|
||||||
const NAME = 'zoom-control'
|
|
||||||
let holder: number | undefined
|
let holder: number | undefined
|
||||||
|
|
||||||
// TODO: TS类型补全
|
const hideControl = ref(false)
|
||||||
export default defineComponent({
|
const activezoomIndex = ref(0)
|
||||||
name: NAME,
|
const zoomList = ref<TZoomData[]>(ZoomList)
|
||||||
data() {
|
const show = ref(false)
|
||||||
return {
|
const zoom = ref<TZoomData>({
|
||||||
hideControl: false,
|
|
||||||
activezoomIndex: 0,
|
|
||||||
zoomList: [
|
|
||||||
{
|
|
||||||
text: '25%',
|
|
||||||
value: 25,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '50%',
|
|
||||||
value: 50,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '75%',
|
|
||||||
value: 75,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '100%',
|
|
||||||
value: 100,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '125%',
|
|
||||||
value: 125,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '150%',
|
|
||||||
value: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '200%',
|
|
||||||
value: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '最佳尺寸',
|
|
||||||
value: -1,
|
|
||||||
// icon: 'icon-best-size',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
show: false,
|
|
||||||
zoom: {
|
|
||||||
value: 0,
|
value: 0,
|
||||||
text: 0,
|
text: '',
|
||||||
},
|
})
|
||||||
otherList: [
|
const otherList = ref<TZoomData[]>(OtherList)
|
||||||
{
|
const otherIndex = ref(-1)
|
||||||
text: '250%',
|
const bestZoom = ref(0)
|
||||||
value: 250,
|
const curAction = ref('')
|
||||||
},
|
|
||||||
{
|
const { dPage, dScreen, zoomScreenChange, dZoom } = useSetupMapGetters(['dPage', 'dScreen', 'zoomScreenChange', 'dZoom'])
|
||||||
text: '300%',
|
|
||||||
value: 300,
|
watch(
|
||||||
},
|
activezoomIndex,
|
||||||
{
|
(data) => {
|
||||||
text: '350%',
|
if (data < 0 || data > zoomList.value.length - 1) {
|
||||||
value: 350,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '400%',
|
|
||||||
value: 400,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '450%',
|
|
||||||
value: 450,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: '500%',
|
|
||||||
value: 500,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
otherIndex: -1,
|
|
||||||
bestZoom: 0,
|
|
||||||
curAction: "",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['dPage', 'dScreen', 'zoomScreenChange', 'dZoom']),
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
activezoomIndex(value) {
|
|
||||||
if (value < 0 || value > this.zoomList.length - 1) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.zoom = JSON.parse(JSON.stringify(this.zoomList[value]))
|
zoom.value = JSON.parse(JSON.stringify(zoomList.value[data]))
|
||||||
},
|
}
|
||||||
otherIndex(value) {
|
)
|
||||||
if (value < 0 || value > this.otherList.length - 1) {
|
|
||||||
|
watch(
|
||||||
|
otherIndex,
|
||||||
|
(data) => {
|
||||||
|
if (data < 0 || data > otherList.value.length - 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.zoom = JSON.parse(JSON.stringify(this.otherList[value]))
|
zoom.value = JSON.parse(JSON.stringify(otherList.value[data]))
|
||||||
},
|
}
|
||||||
zoom(value) {
|
)
|
||||||
let realValue = value.value
|
|
||||||
|
watch(
|
||||||
|
zoom,
|
||||||
|
(data) => {
|
||||||
|
let realValue = data.value
|
||||||
if (realValue === -1) {
|
if (realValue === -1) {
|
||||||
realValue = this.calcZoom()
|
realValue = calcZoom()
|
||||||
}
|
}
|
||||||
this.updateZoom(realValue)
|
store.dispatch('updateZoom', realValue)
|
||||||
this.autoFixTop()
|
// updateZoom(realValue)
|
||||||
|
autoFixTop()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
dScreen,
|
||||||
|
() => {
|
||||||
|
screenChange()
|
||||||
},
|
},
|
||||||
dScreen: {
|
{ deep: true, }
|
||||||
handler() {
|
)
|
||||||
this.screenChange()
|
|
||||||
|
watch(
|
||||||
|
zoomScreenChange,
|
||||||
|
() => {
|
||||||
|
activezoomIndex.value = zoomList.value.length - 1
|
||||||
|
screenChange()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
dPage,
|
||||||
|
() => {
|
||||||
|
screenChange()
|
||||||
},
|
},
|
||||||
deep: true,
|
{ deep: true }
|
||||||
},
|
)
|
||||||
zoomScreenChange() {
|
|
||||||
this.activezoomIndex = this.zoomList.length - 1
|
onMounted(async () => {
|
||||||
this.screenChange()
|
await nextTick()
|
||||||
},
|
window.addEventListener('click', close)
|
||||||
dPage: {
|
if (route.path === '/draw') {
|
||||||
handler(val) {
|
activezoomIndex.value = 3
|
||||||
this.screenChange()
|
hideControl.value = true
|
||||||
},
|
|
||||||
deep: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
async mounted() {
|
|
||||||
await this.$nextTick()
|
|
||||||
window.addEventListener('click', this.close)
|
|
||||||
if (this.$route.path === '/draw') {
|
|
||||||
this.activezoomIndex = 3
|
|
||||||
this.hideControl = true
|
|
||||||
} else {
|
} else {
|
||||||
this.activezoomIndex = this.zoomList.length - 1
|
activezoomIndex.value = zoomList.value.length - 1
|
||||||
}
|
}
|
||||||
// 添加滚轮监听
|
// 添加滚轮监听
|
||||||
addMouseWheel('page-design', (isDown: boolean) => {
|
addMouseWheel('page-design', (isDown: boolean) => {
|
||||||
this.mousewheelZoom(isDown)
|
mousewheelZoom(isDown)
|
||||||
})
|
})
|
||||||
// 添加窗口大小监听
|
// 添加窗口大小监听
|
||||||
window.addEventListener('resize', (event) => {
|
window.addEventListener('resize', (event) => {
|
||||||
this.changeScreen()
|
changeScreen()
|
||||||
})
|
})
|
||||||
},
|
})
|
||||||
beforeUnmount() {
|
|
||||||
window.removeEventListener('click', this.close)
|
onBeforeUnmount(() => {
|
||||||
},
|
window.removeEventListener('click', close)
|
||||||
methods: {
|
})
|
||||||
...mapActions(['updateZoom', 'updateScreen']),
|
|
||||||
changeScreen() {
|
// ...mapActions(['updateZoom', 'updateScreen']),
|
||||||
|
function changeScreen() {
|
||||||
clearTimeout(holder)
|
clearTimeout(holder)
|
||||||
holder = setTimeout(() => {
|
holder = setTimeout(() => {
|
||||||
const screen = document.getElementById('page-design')
|
const screen = document.getElementById('page-design')
|
||||||
if (!screen) return
|
if (!screen) return
|
||||||
this.updateScreen({
|
store.dispatch('updateScreen', {
|
||||||
width: screen.offsetWidth,
|
width: screen.offsetWidth,
|
||||||
height: screen.offsetHeight,
|
height: screen.offsetHeight,
|
||||||
})
|
})
|
||||||
|
// updateScreen({
|
||||||
|
// width: screen.offsetWidth,
|
||||||
|
// height: screen.offsetHeight,
|
||||||
|
// })
|
||||||
}, 300)
|
}, 300)
|
||||||
},
|
}
|
||||||
screenChange() {
|
|
||||||
|
function screenChange() {
|
||||||
// 弹性尺寸即时修改
|
// 弹性尺寸即时修改
|
||||||
if (this.activezoomIndex === this.zoomList.length - 1) {
|
if (activezoomIndex.value === zoomList.value.length - 1) {
|
||||||
this.updateZoom(this.calcZoom())
|
store.dispatch('updateZoom', calcZoom())
|
||||||
this.autoFixTop()
|
// this.updateZoom(this.calcZoom())
|
||||||
|
autoFixTop()
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
selectItem(index: number) {
|
|
||||||
this.activezoomIndex = index
|
function selectItem(index: number) {
|
||||||
this.otherIndex = -1
|
activezoomIndex.value = index
|
||||||
this.show = false
|
otherIndex.value = -1
|
||||||
},
|
show.value = false
|
||||||
close(_: MouseEvent) {
|
}
|
||||||
this.show = false
|
|
||||||
},
|
function close(_: MouseEvent) {
|
||||||
add() {
|
show.value = false
|
||||||
this.curAction = 'add'
|
}
|
||||||
this.show = false
|
|
||||||
if (this.activezoomIndex === this.zoomList.length - 2 || this.activezoomIndex === this.zoomList.length - 1) {
|
function add() {
|
||||||
this.activezoomIndex = this.zoomList.length
|
curAction.value = 'add'
|
||||||
|
show.value = false
|
||||||
|
if (
|
||||||
|
activezoomIndex.value === zoomList.value.length - 2 ||
|
||||||
|
activezoomIndex.value === zoomList.value.length - 1
|
||||||
|
) {
|
||||||
|
activezoomIndex.value = zoomList.value.length
|
||||||
// this.otherIndex += 1
|
// this.otherIndex += 1
|
||||||
if (this.bestZoom) {
|
if (bestZoom.value) {
|
||||||
this.nearZoom(true)
|
nearZoom(true)
|
||||||
} else {
|
} else {
|
||||||
this.otherIndex += 1
|
otherIndex.value += 1
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.activezoomIndex != this.zoomList.length) {
|
if (activezoomIndex.value != zoomList.value.length) {
|
||||||
this.activezoomIndex++
|
activezoomIndex.value++
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.otherIndex < this.otherList.length - 1) {
|
if (otherIndex.value < otherList.value.length - 1) {
|
||||||
this.otherIndex++
|
otherIndex.value++
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
sub() {
|
|
||||||
this.curAction = null as any
|
function sub() {
|
||||||
this.show = false
|
curAction.value = ''
|
||||||
if (this.otherIndex === 0) {
|
show.value = false
|
||||||
this.otherIndex = -1
|
if (otherIndex.value === 0) {
|
||||||
this.activezoomIndex = this.zoomList.length - 2
|
otherIndex.value = -1
|
||||||
|
activezoomIndex.value = zoomList.value.length - 2
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.otherIndex != -1) {
|
if (otherIndex.value != -1) {
|
||||||
this.otherIndex--
|
otherIndex.value--
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.activezoomIndex === this.zoomList.length - 1) {
|
if (activezoomIndex.value === zoomList.value.length - 1) {
|
||||||
if (this.bestZoom) {
|
if (bestZoom) {
|
||||||
this.nearZoom()
|
nearZoom()
|
||||||
} else {
|
} else {
|
||||||
this.activezoomIndex = this.zoomList.length - 2
|
activezoomIndex.value = zoomList.value.length - 2
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.activezoomIndex != 0) {
|
if (activezoomIndex.value != 0) {
|
||||||
this.activezoomIndex--
|
activezoomIndex.value--
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
mousewheelZoom(down: boolean) {
|
|
||||||
const value = Number(this.dZoom.toFixed(0))
|
function mousewheelZoom(down: boolean) {
|
||||||
|
const value = Number(dZoom.value.toFixed(0))
|
||||||
if (down && value <= 1) return
|
if (down && value <= 1) return
|
||||||
this.updateZoom(down ? value - 1 : value + 1)
|
store.dispatch('updateZoom', down ? value - 1 : value + 1)
|
||||||
this.zoom.text = (value + '%') as any
|
// updateZoom(down ? value - 1 : value + 1)
|
||||||
this.autoFixTop()
|
zoom.value.text = (value + '%') as any
|
||||||
},
|
autoFixTop()
|
||||||
nearZoom(add?: boolean) {
|
}
|
||||||
for (let i = 0; i < this.zoomList.length; i++) {
|
|
||||||
this.activezoomIndex = i
|
function nearZoom(add?: boolean) {
|
||||||
if (this.zoomList[i].value > this.bestZoom) {
|
for (let i = 0; i < zoomList.value.length; i++) {
|
||||||
|
activezoomIndex.value = i
|
||||||
|
if (zoomList.value[i].value > bestZoom.value) {
|
||||||
if (add) break
|
if (add) break
|
||||||
} else if (this.zoomList[i].value < this.bestZoom) {
|
} else if (zoomList.value[i].value < bestZoom.value) {
|
||||||
if (!add) break
|
if (!add) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.bestZoom = 0
|
bestZoom.value = 0
|
||||||
},
|
}
|
||||||
calcZoom() {
|
|
||||||
let widthZoom = ((this.dScreen.width - 142) * 100) / this.dPage.width
|
|
||||||
let heightZoom = ((this.dScreen.height - 122) * 100) / this.dPage.height
|
|
||||||
|
|
||||||
this.bestZoom = Math.min(widthZoom, heightZoom)
|
function calcZoom() {
|
||||||
return this.bestZoom
|
let widthZoom = ((dScreen.value.width - 142) * 100) / dPage.value.width
|
||||||
},
|
let heightZoom = ((dScreen.value.height - 122) * 100) / dPage.value.height
|
||||||
async autoFixTop() {
|
|
||||||
await this.$nextTick()
|
bestZoom.value = Math.min(widthZoom, heightZoom)
|
||||||
|
return bestZoom.value
|
||||||
|
}
|
||||||
|
|
||||||
|
async function autoFixTop() {
|
||||||
|
await nextTick()
|
||||||
const presetPadding = 60
|
const presetPadding = 60
|
||||||
const el = document.getElementById('out-page')
|
const el = document.getElementById('out-page')
|
||||||
if (!el) return
|
if (!el) return
|
||||||
@ -275,14 +252,17 @@ export default defineComponent({
|
|||||||
|
|
||||||
const parentHeight = (el.offsetParent as HTMLElement).offsetHeight - 54
|
const parentHeight = (el.offsetParent as HTMLElement).offsetHeight - 54
|
||||||
let padding = (parentHeight - el.offsetHeight) / 2
|
let padding = (parentHeight - el.offsetHeight) / 2
|
||||||
if (typeof this.curAction === 'undefined') {
|
if (typeof curAction.value === 'undefined') {
|
||||||
padding += presetPadding / 2
|
padding += presetPadding / 2
|
||||||
}
|
}
|
||||||
this.curAction === 'add' && (padding -= presetPadding)
|
curAction.value === 'add' && (padding -= presetPadding)
|
||||||
this.$store.commit('updatePaddingTop', padding > 0 ? padding : 0)
|
store.commit('updatePaddingTop', padding > 0 ? padding : 0)
|
||||||
},
|
}
|
||||||
},
|
|
||||||
|
defineExpose({
|
||||||
|
screenChange
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user