315 lines
7.9 KiB
Vue
315 lines
7.9 KiB
Vue
<script setup lang="ts">
|
|
import homeWorkApi from '@/api/system/homeWork'
|
|
import { useRoute } from 'vue-router'
|
|
|
|
const route = useRoute()
|
|
const OSS_URL = import.meta.env.VITE_OSS_URL
|
|
const activeBg = `url(${OSS_URL}/urm/homeWork/homeWork_temporary_active_bg.svg)`
|
|
const nonactiveBg = `url(${OSS_URL}/urm/homeWork/homeWork_temporary_nonactive_bg.svg)`
|
|
const activeNav = ref({
|
|
name: '原图',
|
|
type: 0,
|
|
url: '',
|
|
})
|
|
const nav = ref([
|
|
{
|
|
name: '原图',
|
|
type: 0,
|
|
url: '',
|
|
},
|
|
])
|
|
const loading = ref(false)
|
|
const dragging = ref(false) // 是否处于拖拽状态
|
|
const imgArea = ref()
|
|
const img = ref()
|
|
const movableData = ref({
|
|
x: 0,
|
|
y: 0,
|
|
scale: 1,
|
|
})
|
|
const scaleData = ref(1) // 另外存一份放大倍率
|
|
const distance = ref({
|
|
startDistance: 0,
|
|
endDistance: 0,
|
|
})
|
|
function clickAnswerStatus(i: any) {
|
|
activeNav.value = i
|
|
movableData.value = {
|
|
x: 0,
|
|
y: 0,
|
|
scale: 1,
|
|
}
|
|
loading.value = true
|
|
setTimeout(() => {
|
|
onImageLoad()
|
|
}, 150)
|
|
}
|
|
// 图片加载
|
|
function onImageLoad() {
|
|
loading.value = false
|
|
}
|
|
// 放大
|
|
function tapEnlarge() {
|
|
if (movableData.value.scale < 2) {
|
|
movableData.value.scale += 0.1
|
|
}
|
|
}
|
|
// 缩小
|
|
function tapLessen() {
|
|
if (movableData.value.scale > 0.6) {
|
|
movableData.value.scale -= 0.1
|
|
}
|
|
}
|
|
|
|
function touchTwo(e: anyObj[], mode: 'startDistance' | 'endDistance') {
|
|
// 双指缩放
|
|
const one = {
|
|
x: e[0].pageX, // 第一根手指的横坐标
|
|
y: e[0].pageY, // 第一根手指的纵坐标
|
|
} // 第一根手指的横坐标
|
|
const two = {
|
|
x: e[1].pageX, // 第二根手指的横坐标
|
|
y: e[1].pageY, // 第二根手指的纵坐标
|
|
}
|
|
|
|
distance.value[mode] = getDistance(one, two)
|
|
}
|
|
|
|
function getDistance(start: anyObj, stop: anyObj) {
|
|
return Math.sqrt(
|
|
Math.pow(Math.abs(start.x - stop.x), 2) + Math.pow(Math.abs(start.y - stop.y), 2),
|
|
)
|
|
}
|
|
|
|
const startDrag = (event: anyObj) => {
|
|
if (event.touches?.length === 2) {
|
|
// 两个触点
|
|
touchTwo(event.touches, 'startDistance')
|
|
return
|
|
}
|
|
dragging.value = true
|
|
const x = (event.touches ? event.touches[0].pageX : event.pageX) - movableData.value.x
|
|
const y = (event.touches ? event.touches[0].pageY : event.pageY) - movableData.value.y
|
|
|
|
const move = (event: anyObj) => {
|
|
if (event.touches?.length === 2) {
|
|
// 两个触点
|
|
touchTwo(event.touches, 'endDistance')
|
|
const scale2 =
|
|
scaleData.value + distance.value.endDistance / distance.value.startDistance - 1.01 // 减去原本的1倍 0.01是防止小数计算误差
|
|
movableData.value.scale = scale2 > 2 ? 2 : scale2 < 0.5 ? 0.5 : scale2 // 最大2倍 最小0.5倍
|
|
return
|
|
}
|
|
if (dragging.value) {
|
|
movableData.value.x = (event.touches ? event.touches[0].pageX : event.pageX) - x
|
|
movableData.value.y = (event.touches ? event.touches[0].pageY : event.pageY) - y
|
|
}
|
|
}
|
|
const stopDrag = () => {
|
|
distance.value.startDistance = distance.value.endDistance = 0
|
|
scaleData.value = movableData.value.scale
|
|
dragging.value = false
|
|
document.removeEventListener('mousemove', move)
|
|
document.removeEventListener('touchmove', move)
|
|
document.removeEventListener('mouseup', stopDrag)
|
|
document.removeEventListener('touchend', stopDrag)
|
|
}
|
|
|
|
document.addEventListener('mousemove', move)
|
|
document.addEventListener('touchmove', move)
|
|
document.addEventListener('mouseup', stopDrag)
|
|
document.addEventListener('touchend', stopDrag)
|
|
}
|
|
// 获取详情
|
|
async function getTemporaryJobDetail() {
|
|
loading.value = true
|
|
try {
|
|
const { data } = await homeWorkApi.temporaryJobDetail(route.params.id)
|
|
if (data.data.status === 1) {
|
|
nav.value = [
|
|
{
|
|
name: '原图',
|
|
type: 0,
|
|
url: data.data.submitUrl,
|
|
},
|
|
{ name: '批改图', type: 1, url: data.data.markUrl },
|
|
]
|
|
} else {
|
|
nav.value = [
|
|
{
|
|
name: '原图',
|
|
type: 0,
|
|
url: data.data.submitUrl,
|
|
},
|
|
]
|
|
}
|
|
activeNav.value = nav.value[0]
|
|
loading.value = false
|
|
} catch (err) {
|
|
console.log(err)
|
|
loading.value = false
|
|
}
|
|
}
|
|
onUnmounted(() => {
|
|
document.removeEventListener('mousemove', () => {})
|
|
document.removeEventListener('mouseup', () => {})
|
|
document.removeEventListener('touchmove', () => {})
|
|
document.removeEventListener('touchend', () => {})
|
|
})
|
|
onActivated(() => {
|
|
getTemporaryJobDetail()
|
|
movableData.value = {
|
|
x: 0,
|
|
y: 0,
|
|
scale: 1,
|
|
}
|
|
})
|
|
</script>
|
|
<template>
|
|
<div class="sinle_temporary">
|
|
<div class="top">
|
|
<BackBar />
|
|
</div>
|
|
<div class="main">
|
|
<div
|
|
class="main_answer"
|
|
:style="{
|
|
'background-image': `url(${OSS_URL}/urm/homeWork/homeWork_temporary_single_bg.svg)`,
|
|
}"
|
|
>
|
|
<div class="nav">
|
|
<div
|
|
v-for="i in nav"
|
|
:key="i.type"
|
|
class="nav_item pointer"
|
|
:style="{
|
|
'background-image': i.type === activeNav.type ? activeBg : nonactiveBg,
|
|
color: i.type === activeNav.type ? '' : '#666',
|
|
}"
|
|
@click="clickAnswerStatus(i)"
|
|
>
|
|
{{ i.name }}
|
|
</div>
|
|
</div>
|
|
<Empty v-if="loading" class="empty" type="loading" content=""></Empty>
|
|
<div v-else class="area">
|
|
<div
|
|
ref="imgArea"
|
|
:style="{
|
|
transform: `translate(${movableData.x}px, ${movableData.y}px) scale(${movableData.scale})`,
|
|
}"
|
|
class="area-content"
|
|
@mousedown.prevent="startDrag"
|
|
@touchstart.prevent="startDrag"
|
|
>
|
|
<img ref="img" :src="activeNav.url" alt="" @load="onImageLoad" />
|
|
</div>
|
|
<div class="tool">
|
|
<Icon
|
|
name="homeWork_temporary_fangda"
|
|
width="48"
|
|
class="pointer tool_fangda"
|
|
@click="tapEnlarge"
|
|
></Icon>
|
|
<Icon
|
|
name="homeWork_temporary_suoxiao"
|
|
width="48"
|
|
class="pointer"
|
|
@click="tapLessen"
|
|
></Icon>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<style scoped lang="scss">
|
|
.sinle_temporary {
|
|
@include main_bg;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
box-sizing: border-box;
|
|
|
|
.top {
|
|
padding: 3vh 64px 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-end;
|
|
}
|
|
.main {
|
|
padding: 0 64px;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
&_answer {
|
|
position: relative;
|
|
width: 1792px;
|
|
height: 85.25vh;
|
|
background-size: 100%;
|
|
|
|
.nav {
|
|
position: absolute;
|
|
top: -4.75vh;
|
|
width: calc(100% - 394px);
|
|
margin-left: 197px;
|
|
display: flex;
|
|
justify-content: center;
|
|
font-family: $font-special;
|
|
font-size: 3.33vh;
|
|
font-weight: 400;
|
|
line-height: 5vh;
|
|
text-align: center;
|
|
|
|
&_item {
|
|
width: 300px;
|
|
height: 7.67vh;
|
|
line-height: 7.67vh;
|
|
border-radius: 3.33vh 3.33vh 0 0;
|
|
background-size: 100%;
|
|
background-repeat: no-repeat;
|
|
&:first-child {
|
|
margin-right: 24px;
|
|
}
|
|
}
|
|
}
|
|
.area {
|
|
position: absolute;
|
|
top: 9.58vh;
|
|
left: 48px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: calc(100% - 96px);
|
|
height: 71.92vh;
|
|
overflow: hidden;
|
|
|
|
.tool {
|
|
position: absolute;
|
|
bottom: 2vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 188px;
|
|
height: 5.33vh;
|
|
border-radius: 4.5vh;
|
|
background: rgba(0, 0, 0, 0.45);
|
|
&_fangda {
|
|
margin-right: 32px;
|
|
}
|
|
}
|
|
.area-content {
|
|
width: 825px;
|
|
height: 71.92vh;
|
|
}
|
|
img {
|
|
width: 100%;
|
|
max-height: 100%;
|
|
object-fit: contain;
|
|
cursor: grab;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|