工具栏-拖动 折叠

This commit is contained in:
zdg 2024-08-02 09:21:57 +08:00
parent ee53207d31
commit dbf6b665a8
3 changed files with 155 additions and 20 deletions

View File

@ -0,0 +1,81 @@
/**
* @description: v-drag
* @author zdg
* @date 2023-06-07
*/
// 工具包
const utils = {
// Creates an event handler that can be used in Vue code
// setup start moving end
vueDragEvent: (el, action) => {
el.dispatchEvent(new Event(`drag-${action}`))
},
dragStart: (el, target, axis, snap, e) => {
// el.style.cursor = 'move'
// el.onmousedown = function (e) {
// const disX = e.clientX - el.offsetLeft
// const disY = e.clientY - el.offsetTop
// document.onmousemove = function (e) {
// const left = e.clientX - disX
// const top= e.clientY - disY
// }
// }
},
}
// 首次向元素添加可拖动配置 | Add draggable configuration to element for the first time
const mountedHook = (el, binding) => {
console.log(el, binding)
const value = binding.value || {}
const handleSelector = value instanceof Object ? value.el : value // 获取元素
const isOpen = value instanceof Object ? value.open || true : true // 是否开启拖拽 默认:开启
const handleArray = [] // 拖拽元素
if (!isOpen) return false // 没有开启不加载后面的代码
let axis
// Store all the DOM elements that will be used as handles.
// They can be declared using a string with a CSS tag, class or id, or using Vue refs.
if (!!handleSelector) {
if (handleSelector instanceof HTMLElement) {
handleArray.push(handleSelector);
} else {
// handleArray.push(document.querySelectorAll(handleSelector));
document.querySelectorAll(handleSelector).forEach((child) => {
handleArray.push(child);
});
}
}
if (handleArray.length !== 0) {
// Define move element and apply CSS class
// el.classList.add(window.data.class.usesHandle);
handleArray.forEach((grabElement) => {
// Apply CSS class to each grab element
// grabElement.classList.add(window.data.class.handle);
// Add events to start drag with handle
grabElement.onmousedown = (e) => utils.dragStart(grabElement, el, axis, e);
grabElement.ontouchstart = (e) => utils.dragStart(grabElement, el, axis, e);
});
} else {
// Add events to start drag without handle
el.onmousedown = (e) => utils.dragStart(el, el, axis, e);
el.ontouchstart = (e) => utils.dragStart(el, el, axis, e);
}
// Vue event on setup
utils.vueDragEvent(el, 'setup')
}
export default {
// Hooks for Vue3
mounted(el, binding) {
mountedHook(el, binding)
},
// Hooks for Vue2
inserted(el, binding) {
mountedHook(el, binding)
},
update(el, binding){
},
updated(el, binding){
},
}

View File

@ -175,9 +175,9 @@ const eventHandles = (type, win) => {
const setIgnore = (_, ignore) => {win.setIgnoreMouseEvents(ignore, {forward: true})} const setIgnore = (_, ignore) => {win.setIgnoreMouseEvents(ignore, {forward: true})}
Remote.ipcMain.on('tool-sphere:set:ignore', setIgnore) Remote.ipcMain.on('tool-sphere:set:ignore', setIgnore)
// 关闭窗口 // 关闭窗口
Remote.ipcMain.once('tool-sphere:close', () => { win.destroy() }) Remote.ipcMain.once('tool-sphere:close', () => { win&&win.destroy() })
// 放大监听-测试 // 放大监听-测试
Remote.ipcMain.once('maximize-window', () => {win.destroy()}) Remote.ipcMain.once('maximize-window', () => {win&&win.destroy()})
const on = { const on = {
onClosed: () => {Remote.ipcMain.off('tool-sphere:set:ignore', setIgnore)} onClosed: () => {Remote.ipcMain.off('tool-sphere:set:ignore', setIgnore)}
} }
@ -185,8 +185,7 @@ const eventHandles = (type, win) => {
break} break}
case 'open-PDF': { case 'open-PDF': {
// 最小化窗口 minimize() // 最小化窗口 minimize()
Remote.ipcMain.once('open-PDF:minimize', () => {win.destroy()}) Remote.ipcMain.once('open-PDF:minimize', () => {win&&win.destroy()})
win.webContents.openDevTools()
publicMethods() // 加载公共方法 publicMethods() // 加载公共方法
break} break}
default: default:

View File

@ -2,11 +2,16 @@
<div class="warp-all"> <div class="warp-all">
<board-vue v-model="tabActive"></board-vue> <board-vue v-model="tabActive"></board-vue>
<!-- 底部工具栏 --> <!-- 底部工具栏 -->
<el-row id="test" class="tool-bottom-all" @mouseenter="mouseChange(0)" @mouseleave="mouseChange(1)"> <div ref="tool" class="tool-bottom-all" :style="dataPos.style"
<el-col :span="3" class="flex justify-center items-center"> @mouseenter="mouseChange(0)" @mouseleave="mouseChange(1)">
<div class="c-logo"><el-image :src="logo" @click="tabChange('close')" /></div> <div @mousedown="e => dargHandle(e,'down')"
</el-col> @mousemove="e => dargHandle(e,'move')"
<el-col :span="20"> @mouseup="e => dargHandle(e,'up')">
<div class="c-logo" @click="logoHandle" title="拖动 | 折叠 | 展开">
<el-image :src="logo" />
</div>
</div>
<div class="tool-btns" v-show="!isFold">
<el-segmented class="c-btns" v-model="tabActive" :options="btnList" size="large" block <el-segmented class="c-btns" v-model="tabActive" :options="btnList" size="large" block
@change="tabChange"> @change="tabChange">
<template #default="{item}"> <template #default="{item}">
@ -16,22 +21,27 @@
</div> </div>
</template> </template>
</el-segmented> </el-segmented>
</el-col> </div>
</el-row> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
// electron // electron
import { onMounted, ref } from 'vue' import { onMounted, ref, reactive } from 'vue'
import logo from '@root/resources/icon.png' // logo import logo from '@root/resources/icon.png' // logo
import boardVue from './components/board.vue' import boardVue from './components/board.vue' //
import vDrag from '@/directive/drag'
import { tryOnUnmounted } from '@vueuse/core'
// const Remote = require('@electron/remote') // remote // const Remote = require('@electron/remote') // remote
const { ipcRenderer } = require('electron') const { ipcRenderer } = require('electron')
const tool = ref()
const tabActive = ref('select') const tabActive = ref('select') //
const btnList = [ const isFold = ref(false) //
const isDrag = ref(false) //
const dataPos = reactive({style:{}}) //
const btnList = [ //
{ label: '选择', value: 'select', icon: 'icon-mouse' }, { label: '选择', value: 'select', icon: 'icon-mouse' },
{ label: '画笔', value: 'brush', icon: 'icon-huabi' }, { label: '画笔', value: 'brush', icon: 'icon-huabi' },
{ label: '板擦', value: 'eraser', icon: 'icon-xiangpica' }, { label: '板擦', value: 'eraser', icon: 'icon-xiangpica' },
@ -39,7 +49,7 @@ const btnList = [
{ label: '聚焦', value: 'focus', icon: 'icon-jujiao' }, { label: '聚焦', value: 'focus', icon: 'icon-jujiao' },
{ label: '更多', value: 'more', icon: 'icon-xiazai9' }, { label: '更多', value: 'more', icon: 'icon-xiazai9' },
] ]
let offsetX = 0, offsetY = 0, dragtime = 0
// ==== === // ==== ===
const tabChange = (val) => { // tab-change const tabChange = (val) => { // tab-change
switch (val) { switch (val) {
@ -60,6 +70,48 @@ const tabChange = (val) => { // 切换tab-change
break break
} }
} }
const logoHandle = (e,t) => { // logo - |
if (Date.now() - dragtime < 200) {
isFold.value = !isFold.value
}
console.log('click', isDrag.value)
}
const dargHandle = (e, type) => { //
e.preventDefault(); //
if (type == 'down') {
dragtime = Date.now()
return isDrag.value = true
} else if (type == 'up') {
return isDrag.value = false
} else {
if (!isDrag.value) return false
if (!e.clientX&&!e.clientY){ // 0
offsetX = 0
offsetY = 0
return false
}
if (!offsetX&&!offsetY) { // ,
setStyle()
} else {
const x = e.clientX - offsetX
const y = e.clientY - offsetY
setStyle(x, y)
}
offsetX = e.clientX
offsetY = e.clientY
}
}
const setStyle = (x, y) => { // -
if (offsetX && offsetY) { //
const {left, top} = dataPos.style
const ox = parseInt(left.replace('px',''))
const oy = parseInt(top.replace('px',''))
dataPos.style = {...dataPos.style, left: ox + x + 'px', top: oy + y + 'px'}
} else { //
const {left, top} = tool.value.getBoundingClientRect() //
dataPos.style = {bottom: 'unset', transform:'unset', left: left+'px', top: top+'px'}
}
}
const mouseChange = (bool) => { // 穿 const mouseChange = (bool) => { // 穿
let resBool = false let resBool = false
if (tabActive.value == 'select') resBool = !!bool if (tabActive.value == 'select') resBool = !!bool
@ -73,7 +125,8 @@ const mouseChange = (bool) => { // 鼠标移入工具栏 是否穿透
} }
// //
.tool-bottom-all{ .tool-bottom-all{
width: 45vw; // width: 45vw;
display: flex;
position: fixed; position: fixed;
bottom: 3em; bottom: 3em;
left: 50%; left: 50%;
@ -88,9 +141,11 @@ const mouseChange = (bool) => { // 鼠标移入工具栏 是否穿透
height: 5rem; height: 5rem;
border-radius: 50%; border-radius: 50%;
box-shadow: 0px 0px 8px rgb(0 0 0 / 40%); box-shadow: 0px 0px 8px rgb(0 0 0 / 40%);
position: absolute; // &:hover{
left: 0; // .el-image{transform: scale(1.1);}
// }
} }
.tool-btns{margin: 0 35px 0 7px;}
.c-btn{ .c-btn{
i{font-size: 2rem;} i{font-size: 2rem;}
} }