update
This commit is contained in:
parent
a7176f8be6
commit
7246f89bc0
|
@ -43,7 +43,7 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
.mouse-selection {
|
||||
position: absolute;
|
||||
background-color: rgba($themeColor, 0.25);
|
||||
background: rgba(150, 150, 150, 0.25);
|
||||
z-index: 200;
|
||||
|
||||
&.quadrant-1 {
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import { ref, computed, onMounted, onUnmounted, Ref } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { State } from '@/store/state'
|
||||
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
||||
|
||||
export default (canvasRef: Ref<HTMLElement | null>) => {
|
||||
const canvasScale = ref(1)
|
||||
const viewportLeft = ref(0)
|
||||
const viewportTop = ref(0)
|
||||
|
||||
const store = useStore<State>()
|
||||
const editorAreaShowScale = computed(() => store.state.editorAreaShowScale)
|
||||
|
||||
const setViewportSize = () => {
|
||||
if(!canvasRef.value) return
|
||||
const canvasWidth = canvasRef.value.clientWidth
|
||||
const canvasHeight = canvasRef.value.clientHeight
|
||||
|
||||
if(canvasHeight / canvasWidth > VIEWPORT_ASPECT_RATIO) {
|
||||
const viewportActualWidth = canvasWidth * (editorAreaShowScale.value / 100)
|
||||
canvasScale.value = viewportActualWidth / VIEWPORT_SIZE
|
||||
viewportLeft.value = (canvasWidth - viewportActualWidth) / 2
|
||||
viewportTop.value = (canvasHeight - viewportActualWidth * VIEWPORT_ASPECT_RATIO) / 2
|
||||
}
|
||||
else {
|
||||
const viewportActualHeight = canvasHeight * (editorAreaShowScale.value / 100)
|
||||
canvasScale.value = viewportActualHeight / (VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO)
|
||||
viewportLeft.value = (canvasWidth - viewportActualHeight / VIEWPORT_ASPECT_RATIO) / 2
|
||||
viewportTop.value = (canvasHeight - viewportActualHeight) / 2
|
||||
}
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(setViewportSize)
|
||||
|
||||
onMounted(() => {
|
||||
if(canvasRef.value) resizeObserver.observe(canvasRef.value)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
if(canvasRef.value) resizeObserver.unobserve(canvasRef.value)
|
||||
})
|
||||
|
||||
return {
|
||||
canvasScale,
|
||||
viewportLeft,
|
||||
viewportTop,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import { ref, reactive, Ref, toRefs } from 'vue'
|
||||
|
||||
export default (e: MouseEvent, viewportRef: Ref<HTMLElement | null>, canvasScale: number) => {
|
||||
const isMouseDown = ref(false)
|
||||
const mouseSelectionState = reactive({
|
||||
isShow: false,
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
quadrant: 4,
|
||||
})
|
||||
const startMousePosition = reactive({
|
||||
x: 0,
|
||||
y: 0,
|
||||
})
|
||||
|
||||
const minSelectionRange = 5
|
||||
|
||||
if(!viewportRef.value) return
|
||||
|
||||
isMouseDown.value = true
|
||||
const viewportRect = viewportRef.value.getBoundingClientRect()
|
||||
|
||||
startMousePosition.x = e.pageX
|
||||
startMousePosition.y = e.pageY
|
||||
|
||||
mouseSelectionState.top = (startMousePosition.x - viewportRect.y) / canvasScale
|
||||
mouseSelectionState.left = (startMousePosition.y - viewportRect.x) / canvasScale
|
||||
|
||||
const mousemoveListener = (e: MouseEvent) => {
|
||||
if(!isMouseDown.value) return
|
||||
|
||||
const currentPageX = e.pageX
|
||||
const currentPageY = e.pageY
|
||||
|
||||
const offsetWidth = (currentPageX - startMousePosition.x) / canvasScale
|
||||
const offsetHeight = (currentPageY - startMousePosition.y) / canvasScale
|
||||
|
||||
const width = Math.abs(offsetWidth)
|
||||
const height = Math.abs(offsetHeight)
|
||||
|
||||
if(width < minSelectionRange || height < minSelectionRange) return
|
||||
|
||||
let quadrant = 0
|
||||
if(offsetWidth > 0 && offsetHeight > 0) quadrant = 4
|
||||
else if(offsetWidth < 0 && offsetHeight < 0) quadrant = 1
|
||||
else if(offsetWidth > 0 && offsetHeight < 0) quadrant = 2
|
||||
else if(offsetWidth < 0 && offsetHeight > 0) quadrant = 3
|
||||
|
||||
mouseSelectionState.isShow = true
|
||||
mouseSelectionState.quadrant = quadrant
|
||||
mouseSelectionState.width = width
|
||||
mouseSelectionState.height = height
|
||||
}
|
||||
const mouseupListener = () => {
|
||||
isMouseDown.value = false
|
||||
mouseSelectionState.isShow = false
|
||||
|
||||
document.removeEventListener('mousemove', mousemoveListener)
|
||||
document.removeEventListener('mouseup', mouseupListener)
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', mousemoveListener)
|
||||
document.addEventListener('mouseup', mouseupListener)
|
||||
|
||||
return { ...toRefs(mouseSelectionState) }
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
height: viewportStyles.height + 'px',
|
||||
left: viewportStyles.left + 'px',
|
||||
top: viewportStyles.top + 'px',
|
||||
transform: `scale(${viewportStyles.scale})`,
|
||||
transform: `scale(${canvasScale})`,
|
||||
}"
|
||||
>
|
||||
<MouseSelection
|
||||
|
@ -49,6 +49,7 @@ import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
|||
import { getImageDataURL } from '@/utils/image'
|
||||
|
||||
import useDropImage from '@/hooks/useDropImage'
|
||||
import useSetViewportSize from './hooks/useSetViewportSize'
|
||||
|
||||
import MouseSelection from './MouseSelection.vue'
|
||||
import SlideBackground from './SlideBackground.vue'
|
||||
|
@ -62,9 +63,11 @@ export default defineComponent({
|
|||
AlignmentLine,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore<State>()
|
||||
const viewportRef = ref<HTMLElement | null>(null)
|
||||
const isShowGridLines = ref(false)
|
||||
const alignmentLines = ref<AlignmentLineProps[]>([])
|
||||
const currentSlide = computed(() => store.getters.currentSlide)
|
||||
|
||||
const dropImageFile = useDropImage(viewportRef)
|
||||
watch(dropImageFile, () => {
|
||||
|
@ -75,51 +78,15 @@ export default defineComponent({
|
|||
}
|
||||
})
|
||||
|
||||
const viewportStyles = reactive({
|
||||
const canvasRef = ref<HTMLElement | null>(null)
|
||||
const { canvasScale, viewportLeft, viewportTop } = useSetViewportSize(canvasRef)
|
||||
const viewportStyles = computed(() => ({
|
||||
width: VIEWPORT_SIZE,
|
||||
height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO,
|
||||
left: 0,
|
||||
top: 0,
|
||||
scale: 1,
|
||||
})
|
||||
left: viewportLeft.value,
|
||||
top: viewportTop.value,
|
||||
}))
|
||||
|
||||
const canvasRef = ref<Element | null>(null)
|
||||
const canvasScale = ref(1)
|
||||
|
||||
const store = useStore<State>()
|
||||
const currentSlide = computed(() => store.getters.currentSlide)
|
||||
|
||||
const editorAreaShowScale = computed(() => store.state.editorAreaShowScale)
|
||||
const setViewportSize = () => {
|
||||
if(!canvasRef.value) return
|
||||
const canvasWidth = canvasRef.value.clientWidth
|
||||
const canvasHeight = canvasRef.value.clientHeight
|
||||
|
||||
if(canvasHeight / canvasWidth > VIEWPORT_ASPECT_RATIO) {
|
||||
const viewportActualWidth = canvasWidth * (editorAreaShowScale.value / 100)
|
||||
canvasScale.value = viewportActualWidth / VIEWPORT_SIZE
|
||||
viewportStyles.scale = canvasScale.value
|
||||
viewportStyles.left = (canvasWidth - viewportActualWidth) / 2
|
||||
viewportStyles.top = (canvasHeight - viewportActualWidth * VIEWPORT_ASPECT_RATIO) / 2
|
||||
}
|
||||
else {
|
||||
const viewportActualHeight = canvasHeight * (editorAreaShowScale.value / 100)
|
||||
canvasScale.value = viewportActualHeight / (VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO)
|
||||
viewportStyles.scale = canvasScale.value
|
||||
viewportStyles.left = (canvasWidth - viewportActualHeight / VIEWPORT_ASPECT_RATIO) / 2
|
||||
viewportStyles.top = (canvasHeight - viewportActualHeight) / 2
|
||||
}
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(setViewportSize)
|
||||
|
||||
onMounted(() => {
|
||||
if(canvasRef.value) resizeObserver.observe(canvasRef.value)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
if(canvasRef.value) resizeObserver.unobserve(canvasRef.value)
|
||||
})
|
||||
|
||||
const mouseSelectionState = reactive({
|
||||
isShow: false,
|
||||
top: 0,
|
||||
|
@ -205,26 +172,6 @@ export default defineComponent({
|
|||
text: '粘贴',
|
||||
subText: 'Ctrl + V',
|
||||
},
|
||||
{ divider: true },
|
||||
{
|
||||
text: '参考线',
|
||||
children: [
|
||||
{
|
||||
text: '打开',
|
||||
disable: isShowGridLines.value,
|
||||
icon: isShowGridLines.value ? 'icon-check' : '',
|
||||
iconPlacehoder: true,
|
||||
action: () => isShowGridLines.value = true,
|
||||
},
|
||||
{
|
||||
text: '关闭',
|
||||
disable: !isShowGridLines.value,
|
||||
icon: !isShowGridLines.value ? 'icon-check' : '',
|
||||
iconPlacehoder: true,
|
||||
action: () => isShowGridLines.value = false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '清空页面',
|
||||
},
|
||||
|
@ -235,6 +182,7 @@ export default defineComponent({
|
|||
canvasRef,
|
||||
viewportRef,
|
||||
viewportStyles,
|
||||
canvasScale,
|
||||
mouseSelectionState,
|
||||
handleClickBlankArea,
|
||||
removeEditorAreaFocus,
|
||||
|
|
Loading…
Reference in New Issue