drug template
This commit is contained in:
parent
527e5c4eb2
commit
c915ddf630
|
@ -4,7 +4,7 @@ import KUNGalgameSettingsPanel from './setting-panel/KUNGalgameSettingPanel.vue'
|
|||
// 导入图标
|
||||
import { Icon } from '@iconify/vue'
|
||||
// 导入必要 vue 函数
|
||||
import { computed, onBeforeMount, ref } from 'vue'
|
||||
import { onBeforeMount, ref } from 'vue'
|
||||
// 导入 css 动画
|
||||
import 'animate.css'
|
||||
// 导入路由
|
||||
|
@ -40,8 +40,6 @@ const topBarItem: topBar[] = [
|
|||
{ index: 4, name: '关于我们', router: 'kungalgame' },
|
||||
{ index: 5, name: '返回主页', router: '/' },
|
||||
]
|
||||
// 初始不展示用户头像点击信息
|
||||
let isShowInfo = ref(false)
|
||||
|
||||
// 初始进入页面 header 没有附加样式
|
||||
let topicStyle = {}
|
||||
|
|
|
@ -1,26 +1,38 @@
|
|||
<!-- 设置面板组件,展示整个论坛的设置面板 -->
|
||||
<script setup lang="ts">
|
||||
// 引入图标字体
|
||||
import { Icon } from '@iconify/vue'
|
||||
// 引入看板娘组件
|
||||
import Loli from './components/Loli.vue'
|
||||
// 引入背景设置组件
|
||||
import Background from './components/Background.vue'
|
||||
// 引入点击按钮组件
|
||||
import SwitchButton from './components/SwitchButton.vue'
|
||||
// 导入设置面板 store
|
||||
import { useSettingsPanelStore } from '@/store/modules/settings'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import Drug from './components/Drug.vue'
|
||||
|
||||
// 使用设置面板的 store
|
||||
const settingsStore = useSettingsPanelStore()
|
||||
let { showSettings, showFixedLoli } = storeToRefs(settingsStore)
|
||||
const handleClose = () => {
|
||||
showSettings.value = false
|
||||
}
|
||||
|
||||
// 用户点击固定看板娘
|
||||
const handleClick = () => {}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 根元素 -->
|
||||
<div class="root">
|
||||
<div class="container">
|
||||
<div class="title">
|
||||
<span>设置面板</span><Icon class="settings-icon" icon="uiw:setting-o" />
|
||||
</div>
|
||||
<div class="mode">
|
||||
<!-- 白天 / 黑夜模式切换 -->
|
||||
<span>模式切换</span>
|
||||
<div class="mode-container">
|
||||
<li>
|
||||
|
@ -33,11 +45,12 @@ const handleClose = () => {
|
|||
<Icon
|
||||
class="moon"
|
||||
icon="line-md:sunny-outline-to-moon-loop-transition"
|
||||
/>
|
||||
/>we
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!-- 设置主页的宽度 -->
|
||||
<span>主页页面宽度设置</span>
|
||||
<div class="page-width">
|
||||
<span>61.8%</span><input class="main" type="range" value="0" /><span
|
||||
|
@ -47,11 +60,18 @@ const handleClose = () => {
|
|||
</div>
|
||||
<!-- 背景设置组件 -->
|
||||
<Background />
|
||||
<div class="fix-loli"><span>是否固定看板娘</span><SwitchButton /></div>
|
||||
<div class="fix-loli">
|
||||
<!-- 处理固定看板娘按钮点击事件 -->
|
||||
<span>是否固定看板娘</span><SwitchButton @click="handleClick" />
|
||||
</div>
|
||||
<div><button class="reset">恢复所有设置为默认</button></div>
|
||||
</div>
|
||||
<!-- 看板娘组件 -->
|
||||
<Loli class="loli" />
|
||||
<!-- 此处使用 Teleport,如果固定看板娘,则将看板娘传送到根组件 -->
|
||||
<Drug />
|
||||
<Teleport to="body" :disabled="showFixedLoli">
|
||||
<Loli class="loli" :isShowFixedLoli="showFixedLoli" />
|
||||
</Teleport>
|
||||
<!-- 关闭面板 -->
|
||||
<div class="close"><Icon @click="handleClose" icon="line-md:close" /></div>
|
||||
</div>
|
||||
|
|
82
src/components/setting-panel/components/Drug.vue
Normal file
82
src/components/setting-panel/components/Drug.vue
Normal file
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div
|
||||
class="box"
|
||||
ref="box"
|
||||
@mousedown="startDrag"
|
||||
@wheel.prevent="changeSize"
|
||||
:style="boxStyle"
|
||||
>
|
||||
拖动我
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, CSSProperties, onMounted, onBeforeUnmount } from 'vue'
|
||||
|
||||
const box = ref<HTMLElement | null>(null)
|
||||
|
||||
const state = reactive({
|
||||
isDragging: false,
|
||||
isResizing: false,
|
||||
origin: { x: 0, y: 0 },
|
||||
translation: { x: 0, y: 0 },
|
||||
size: { width: 100, height: 100 },
|
||||
})
|
||||
|
||||
const boxStyle: CSSProperties = {
|
||||
position: 'absolute',
|
||||
top: `${state.translation.y}px`,
|
||||
left: `${state.translation.x}px`,
|
||||
width: `${state.size.width}px`,
|
||||
height: `${state.size.height}px`,
|
||||
backgroundColor: '#ccc',
|
||||
}
|
||||
|
||||
const startDrag = (event: MouseEvent) => {
|
||||
if (event.ctrlKey) {
|
||||
state.isResizing = true
|
||||
} else {
|
||||
state.isDragging = true
|
||||
}
|
||||
state.origin.x = event.clientX
|
||||
state.origin.y = event.clientY
|
||||
}
|
||||
|
||||
const stopDrag = () => {
|
||||
state.isDragging = false
|
||||
state.isResizing = false
|
||||
}
|
||||
|
||||
const drag = (event: MouseEvent) => {
|
||||
if (state.isDragging && box.value !== null) {
|
||||
const deltaX = event.clientX - state.origin.x
|
||||
const deltaY = event.clientY - state.origin.y
|
||||
state.translation.x += deltaX
|
||||
state.translation.y += deltaY
|
||||
box.value.style.top = `${state.translation.y}px`
|
||||
box.value.style.left = `${state.translation.x}px`
|
||||
state.origin.x = event.clientX
|
||||
state.origin.y = event.clientY
|
||||
}
|
||||
}
|
||||
|
||||
const changeSize = (event: WheelEvent) => {
|
||||
if (event.ctrlKey && box.value !== null) {
|
||||
const delta = Math.sign(event.deltaY) * 3
|
||||
state.size.width += delta
|
||||
state.size.height += delta
|
||||
box.value.style.width = `${state.size.width}px`
|
||||
box.value.style.height = `${state.size.height}px`
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
window.addEventListener('mouseup', stopDrag)
|
||||
window.addEventListener('mousemove', drag)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('mouseup', stopDrag)
|
||||
window.removeEventListener('mousemove', drag)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -17,10 +17,57 @@ import {
|
|||
mouth,
|
||||
face,
|
||||
} from '@/utils/loli'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
interface Position {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
const box = ref<HTMLElement | null>(null)
|
||||
const isDragging = ref(false)
|
||||
const mousePosition = ref<Position>({ x: 0, y: 0 })
|
||||
const elementPosition = ref<Position>({ x: 120, y: -250 })
|
||||
|
||||
const handleMouseDown = (event: MouseEvent) => {
|
||||
isDragging.value = true
|
||||
mousePosition.value = { x: event.clientX, y: event.clientY }
|
||||
}
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
if (isDragging.value) {
|
||||
const deltaX = event.clientX - mousePosition.value.x
|
||||
const deltaY = event.clientY - mousePosition.value.y
|
||||
elementPosition.value = {
|
||||
x: elementPosition.value.x + deltaX,
|
||||
y: elementPosition.value.y + deltaY,
|
||||
}
|
||||
mousePosition.value = { x: event.clientX, y: event.clientY }
|
||||
}
|
||||
}
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
box.value?.addEventListener('mousedown', handleMouseDown)
|
||||
box.value?.addEventListener('mousemove', handleMouseMove)
|
||||
box.value?.addEventListener('mouseup', handleMouseUp)
|
||||
})
|
||||
|
||||
const loliPositionXPixel = elementPosition.value.x + 'px'
|
||||
const loliPositionYPixel = elementPosition.value.y + 'px'
|
||||
|
||||
onUnmounted(() => {
|
||||
box.value?.removeEventListener('mousedown', handleMouseDown)
|
||||
box.value?.removeEventListener('mousemove', handleMouseMove)
|
||||
box.value?.removeEventListener('mouseup', handleMouseUp)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 看板娘 -->
|
||||
<!-- 给看板娘整体绑定鼠标移动事件,改变看板娘的位置 -->
|
||||
<div class="loli">
|
||||
<!-- 身体 -->
|
||||
<img class="lass" :src="lass" alt="ren" />
|
||||
|
@ -35,9 +82,10 @@ import {
|
|||
/* 看板娘 */
|
||||
.loli {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: -250px;
|
||||
left: 120px;
|
||||
position: fixed;
|
||||
// 根据父元素控制面板传过来的参数确定看板娘的位置
|
||||
top: v-bind(loliPositionYPixel);
|
||||
left: v-bind(loliPositionXPixel);
|
||||
}
|
||||
.lass {
|
||||
position: absolute;
|
||||
|
|
Loading…
Reference in a new issue