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