new feature: drug Loli !
This commit is contained in:
parent
c915ddf630
commit
51b03fa939
|
@ -45,7 +45,7 @@ const handleClick = () => {}
|
|||
<Icon
|
||||
class="moon"
|
||||
icon="line-md:sunny-outline-to-moon-loop-transition"
|
||||
/>we
|
||||
/>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -68,7 +68,6 @@ const handleClick = () => {}
|
|||
</div>
|
||||
<!-- 看板娘组件 -->
|
||||
<!-- 此处使用 Teleport,如果固定看板娘,则将看板娘传送到根组件 -->
|
||||
<Drug />
|
||||
<Teleport to="body" :disabled="showFixedLoli">
|
||||
<Loli class="loli" :isShowFixedLoli="showFixedLoli" />
|
||||
</Teleport>
|
||||
|
@ -83,7 +82,7 @@ const handleClick = () => {}
|
|||
width: 600px;
|
||||
top: 65px;
|
||||
right: 0;
|
||||
position: fixed;
|
||||
position: absolute;
|
||||
background-color: @kungalgame-trans-white-5;
|
||||
backdrop-filter: blur(5px);
|
||||
border-radius: 10px;
|
||||
|
|
|
@ -6,33 +6,42 @@
|
|||
@wheel.prevent="changeSize"
|
||||
:style="boxStyle"
|
||||
>
|
||||
拖动我
|
||||
<div
|
||||
class="box1"
|
||||
style="
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: aqua;
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { ref, reactive, CSSProperties } from 'vue'
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, CSSProperties, onMounted, onBeforeUnmount } from 'vue'
|
||||
export default {
|
||||
setup() {
|
||||
const box = ref<HTMLElement | null>(null)
|
||||
|
||||
const box = ref<HTMLElement | null>(null)
|
||||
|
||||
const state = reactive({
|
||||
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 = {
|
||||
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) => {
|
||||
const startDrag = (event: MouseEvent) => {
|
||||
if (event.ctrlKey) {
|
||||
state.isResizing = true
|
||||
} else {
|
||||
|
@ -40,14 +49,14 @@ const startDrag = (event: MouseEvent) => {
|
|||
}
|
||||
state.origin.x = event.clientX
|
||||
state.origin.y = event.clientY
|
||||
}
|
||||
}
|
||||
|
||||
const stopDrag = () => {
|
||||
const stopDrag = () => {
|
||||
state.isDragging = false
|
||||
state.isResizing = false
|
||||
}
|
||||
}
|
||||
|
||||
const drag = (event: MouseEvent) => {
|
||||
const drag = (event: MouseEvent) => {
|
||||
if (state.isDragging && box.value !== null) {
|
||||
const deltaX = event.clientX - state.origin.x
|
||||
const deltaY = event.clientY - state.origin.y
|
||||
|
@ -58,9 +67,9 @@ const drag = (event: MouseEvent) => {
|
|||
state.origin.x = event.clientX
|
||||
state.origin.y = event.clientY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const changeSize = (event: WheelEvent) => {
|
||||
const changeSize = (event: WheelEvent) => {
|
||||
if (event.ctrlKey && box.value !== null) {
|
||||
const delta = Math.sign(event.deltaY) * 3
|
||||
state.size.width += delta
|
||||
|
@ -68,15 +77,24 @@ const changeSize = (event: WheelEvent) => {
|
|||
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>
|
||||
return {
|
||||
box,
|
||||
boxStyle,
|
||||
startDrag,
|
||||
stopDrag,
|
||||
drag,
|
||||
changeSize,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('mouseup', this.stopDrag)
|
||||
window.addEventListener('mousemove', this.drag)
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('mouseup', this.stopDrag)
|
||||
window.removeEventListener('mousemove', this.drag)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -17,58 +17,66 @@ 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 })
|
||||
// 用户拖动看板娘和缩放看板娘
|
||||
import { ref, reactive, CSSProperties, onMounted, onBeforeUnmount } from 'vue'
|
||||
|
||||
const handleMouseDown = (event: MouseEvent) => {
|
||||
isDragging.value = true
|
||||
mousePosition.value = { x: event.clientX, y: event.clientY }
|
||||
const loli = ref<HTMLElement | null>(null)
|
||||
|
||||
const state = reactive({
|
||||
isDragging: false,
|
||||
isResizing: false,
|
||||
origin: { x: 0, y: 0 },
|
||||
translation: { x: 0, y: 0 },
|
||||
})
|
||||
|
||||
const loliStyle: CSSProperties = {
|
||||
top: `${state.translation.y}px`,
|
||||
left: `${state.translation.x}px`,
|
||||
}
|
||||
|
||||
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 startDragLoli = (event: MouseEvent) => {
|
||||
if (event.ctrlKey) {
|
||||
state.isResizing = true
|
||||
} else {
|
||||
state.isDragging = true
|
||||
}
|
||||
state.origin.x = event.clientX
|
||||
state.origin.y = event.clientY
|
||||
}
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging.value = false
|
||||
const stopDrag = () => {
|
||||
state.isDragging = false
|
||||
state.isResizing = false
|
||||
}
|
||||
|
||||
const drag = (event: MouseEvent) => {
|
||||
if (state.isDragging && loli.value !== null) {
|
||||
const deltaX = event.clientX - state.origin.x
|
||||
const deltaY = event.clientY - state.origin.y
|
||||
state.translation.x += deltaX
|
||||
state.translation.y += deltaY
|
||||
loli.value.style.top = `${state.translation.y}px`
|
||||
loli.value.style.left = `${state.translation.x}px`
|
||||
state.origin.x = event.clientX
|
||||
state.origin.y = event.clientY
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
box.value?.addEventListener('mousedown', handleMouseDown)
|
||||
box.value?.addEventListener('mousemove', handleMouseMove)
|
||||
box.value?.addEventListener('mouseup', handleMouseUp)
|
||||
window.addEventListener('mouseup', stopDrag)
|
||||
window.addEventListener('mousemove', drag)
|
||||
})
|
||||
|
||||
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)
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('mouseup', stopDrag)
|
||||
window.removeEventListener('mousemove', drag)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 看板娘 -->
|
||||
<!-- 给看板娘整体绑定鼠标移动事件,改变看板娘的位置 -->
|
||||
<div class="loli">
|
||||
<div class="loli" ref="loli" @mousedown="startDragLoli" :style="loliStyle">
|
||||
<!-- 身体 -->
|
||||
<img class="lass" :src="lass" alt="ren" />
|
||||
<img class="eye" :src="eye" alt="ren" />
|
||||
|
@ -82,10 +90,13 @@ onUnmounted(() => {
|
|||
/* 看板娘 */
|
||||
.loli {
|
||||
height: 100%;
|
||||
width: 300px;
|
||||
/* 定位看板娘,重要 */
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
// 根据父元素控制面板传过来的参数确定看板娘的位置
|
||||
top: v-bind(loliPositionYPixel);
|
||||
left: v-bind(loliPositionXPixel);
|
||||
// top: v-bind(loliPositionYPixel);
|
||||
// left: v-bind(loliPositionXPixel);
|
||||
}
|
||||
.lass {
|
||||
position: absolute;
|
||||
|
|
Loading…
Reference in a new issue