<template> <div class="row"> <div class="col-1"></div> <div class="col-10 q-pt-md"> <div ref="div" style="width: 100%; background-color: #646464; height: 40vh"> <div style="position: absolute"> <Vue3DraggableResizable :class="[options_model == index ? 'action' : 'point']" v-for="(item, index) in value_point.length" :initW="point.w" :adsorbParent="false" :initH="point.h" :resizable="false" v-model:x="value_point[index].x" v-model:y="value_point[index].y" @activated="options_model = index" @click="options_model = index" @dragging="dragStartHandle($event, index)"> <span>{{ index+ 1 }}</span> </Vue3DraggableResizable> </div> </div> </div> </div> <div> <div class="row"> <div class="col-1"></div> <div class="col-2 q-px-md" @mousewheel="details_selsect"> <q-select class="q-pt-md" :label="$t('point')" :dense="true" filled v-model="options_model" @update:model-value="(val) => { options_model = val }" :options="options" emit-value map-options /></div> <div class="col-2 q-px-md" @mousewheel="details_selsect_val($event,'x')"> <q-input filled type="number" class="q-pt-md" :dense="true" v-model="value[options_model].x" @update:model-value="chang(options_model, $event, 'h')" label="x" lazy-rules /> </div> <div class="col-2 q-px-md" @mousewheel="details_selsect_val($event,'y')"> <q-input filled type="number" class="q-pt-md" :dense="true" v-model="value[options_model].y" @update:model-value="chang(options_model, $event, 'h')" label="y" lazy-rules /></div> <div class="q-pt-md col-2"> <q-btn color="white" @click="reset(options_model, true, 'h')" text-color="black" :label="$t('reset')" /> </div> <div class="col-2 q-pt-md"> <div><q-btn color="white" @click="resetall" text-color="black" :label="$t('resetall')" /></div> </div> </div> </div> </template> <style scoped> .action { background-color: rgb(27, 180, 111); border-radius: 50%; } .point { background-color: rgb(186, 245, 245); border-radius: 50%; } </style> <script lang="ts"> import { defineComponent, onMounted, ref, computed, watch, nextTick, onBeforeUnmount, defineExpose } from "vue"; import { useStore } from "src/store"; import { useI18n } from "vue-i18n"; import Vue3DraggableResizable from 'vue3-draggable-resizable' import 'vue3-draggable-resizable/dist/Vue3DraggableResizable.css' import DensityCorrection from "src/entities/DensityCorrection"; import DensityCorrectionPoint from "src/entities/DensityCorrectionPoint"; import { config } from "process"; import { QSelect, QInput, QBtn } from "quasar"; import { div } from "zrender/lib/core/vector"; import GlobalData from "src/common/GlobalData"; import { number } from "@intlify/core-base"; export default defineComponent({ name: "ComponentDensityCorrection", components: { Vue3DraggableResizable }, setup() { let set = GlobalData.getInstance().getCurrentClient(); let $store = useStore(); let $t = useI18n(); const ste_status = ref(0); let allconfig = JSON.parse($store.state.fusion_configuration); let config = JSON.parse($store.state.fusion_configuration).projectors[0]; const configselsect = computed(() => { return $store.state.selected_projector; }); /** * 用于计算当前投影仪的索引 */ let serverconfig = JSON.parse($store.state.fusion_configuration); const selectedprojector = computed(() => { return ( $store.getters.GetTheCurrentlySelectedCamera[0] * serverconfig.col + $store.getters.GetTheCurrentlySelectedCamera[1] ); }); const value_point_amount = ref(5) const deepcopy = (o1: any, o2: any) => { for (let k in o2) { if (typeof o2[k] === "object") { o1[k] = {}; deepcopy(o1[k], o2[k]); } else { o1[k] = o2[k]; } } }; const use_server_config = () => { value.value = [] value_point.value = [] for (let index = 0; index < config.point4.length; index++) { let tmp: DensityCorrectionPoint = config.point4[index]; value.value.push(tmp) let x_y = coordinate_transformation_value_to_xy(tmp.x, tmp.y) let def_x_f = coordinate_transformation_value_to_xy(tmp.def_x, tmp.def_y) let tmp_point: DensityCorrectionPoint = { control_point: tmp.control_point, x: x_y.x, y: x_y.y, def_x: def_x_f.x, def_y: def_x_f.y } value_point.value.push(tmp_point) } } const use_set_cache = () => { if (set_cache.value[selectedprojector.value] != null) { let tmp = JSON.parse(set_cache.value[selectedprojector.value]); deepcopy(value.value, tmp.value) deepcopy(value_point.value, tmp.value_point) recalculate_coordinates() } } const save_set_cache = () => { let tmp = { value: value.value, value_point: value_point.value } set_cache.value[selectedprojector.value] = JSON.stringify(tmp); } watch( () => configselsect, (newVal, oldVal) => { let tmp = JSON.parse($store.state.fusion_configuration); let fortmp = null; let i; for (i of tmp.projectors) { if ( i.col === $store.getters.GetTheCurrentlySelectedCamera[1] && i.row === $store.getters.GetTheCurrentlySelectedCamera[0] ) { fortmp = JSON.parse(JSON.stringify(i)); } } ste_status.value = 1; config = JSON.parse(JSON.stringify(fortmp)); use_server_config(); use_set_cache(); setTimeout(() => { ste_status.value = 0; }, 100); }, { deep: true } ); const set_cache: any = ref([]); //值 let value = ref(<DensityCorrection[]>[]); //位置 let value_point = ref(<DensityCorrectionPoint[]>[]); /** * 当前选中的点的索引 */ const options_model = ref(0) const div = ref(); const max = ref({ x: 0, y: 0 }) const point = ref({ w: 20, h: 20 }) watch(() => options_model, (newval, oldval) => { set?.SetBlendingOption("blending_grids_select_point", `4:${options_model.value + 1}`) }, { deep: true }) /** * 分辨率和页面的比例 */ let Proportion = ref({ x: 100, y: 1000 }); nextTick(() => { max.value.x = div.value.offsetWidth max.value.y = div.value.offsetHeight }) const options = computed(() => { let tmp = [] for (let index = 0; index < value_point.value.length; index++) { tmp.push({ label: `${index + 1}`, value: index, }) } return tmp }) const chang_point_amount = (val: number) => { start_point() } const dragStartHandle = ($event: any, index: number) => { let obj_x = $event.x let obj_y = $event.y let tmp = coordinate_transformation_xy_to_value(obj_x, obj_y) value.value[index].x = Math.round(tmp.x) value.value[index].y = Math.round(tmp.y) send_value(index, Math.round(tmp.x), Math.round(tmp.y)) save_set_cache() } const chang = (index: number, $event: any, type: string) => { index = Number(index) let tmp = coordinate_transformation_value_to_xy(value.value[index].x, value.value[index].y) value_point.value[index].y = Math.round(tmp.y) value_point.value[index].x = Math.round(tmp.x) send_value(index, Math.round(value.value[index].x), Math.round(value.value[index].y)) save_set_cache() } /** * 将分辨率的坐标转换为 页面的坐标 * @param x x坐标 * @param y y坐标 */ const coordinate_transformation_value_to_xy = (x: number, y: number): { x: number, y: number } => { x = x / Proportion.value.x y = (allconfig.projector_height - y) / Proportion.value.y return { x, y } } /** * 将页面的坐标转换为 分辨率的坐标 * @param x x坐标 * @param y y坐标 */ const coordinate_transformation_xy_to_value = (x: number, y: number): { x: number, y: number } => { x = (x + point.value.w / 14) * Proportion.value.x // x = (x-point.value.w) * Proportion.value.x y = (max.value.y - (y + point.value.h)) * Proportion.value.y return { x, y } } const start_point = () => { value.value = [] value_point.value = [] for (let index = 0; index < config.point4.length; index++) { let tmp: DensityCorrectionPoint = config.point4[index]; value.value.push(tmp) let x_y = coordinate_transformation_value_to_xy(tmp.x, tmp.y) let def_x_f = coordinate_transformation_value_to_xy(tmp.def_x, tmp.def_y) let tmp_point: DensityCorrectionPoint = { control_point: tmp.control_point, x: x_y.x, y: x_y.y, def_x: def_x_f.x, def_y: def_x_f.y } value_point.value.push(tmp_point) } } /** * 创建空值 让dom先渲染 */ const start = () => { let tmp: DensityCorrectionPoint = { control_point: 0, x: 0, y: 0, def_x: 0, def_y: 0 }; value.value.push(tmp) value_point.value.push(tmp) } start() onMounted(() => { Proportion.value.x = allconfig.projector_width / (div.value.offsetWidth - point.value.w) Proportion.value.y = allconfig.projector_height / (div.value.offsetHeight - point.value.h) start_point() start() use_server_config() if ( sessionStorage.FourPointCalibration && sessionStorage.FourPointCalibration.length > 0 ) { set_cache.value = JSON.parse(sessionStorage.FourPointCalibration); use_set_cache(); } window.onresize = () => { return (() => { if (div != null) { recalculate_coordinates() } })(); }; }) onBeforeUnmount(() => { sessionStorage.FourPointCalibration = JSON.stringify(set_cache.value); }); const reset = (index: number, send: boolean, type: string) => { value.value[index].x = value.value[index].def_x value.value[index].y = value.value[index].def_y chang(index, value.value[index].def_y, type) save_set_cache() } const send_value = (index: number, x: number, y: number) => { let row = $store.getters.GetTheCurrentlySelectedCamera[0] let col = $store.getters.GetTheCurrentlySelectedCamera[1] set?.setBlendingCorrection(row, col, 4, value_point.value.length, index + 1, Number(x), Number(y)); } const resetall = () => { for (let index = 0; index < value_point.value.length; index++) { value.value[index].x = value.value[index].def_x value.value[index].y = value.value[index].def_y let tmp = coordinate_transformation_value_to_xy(value.value[index].x, value.value[index].y) value_point.value[index].y = Math.round(tmp.y) value_point.value[index].x = Math.round(tmp.x) } send_value(-2,0,0) } const recalculate_coordinates = () => { try { Proportion.value.x = allconfig.projector_width / (div.value.offsetWidth - point.value.w) Proportion.value.y = allconfig.projector_height / (div.value.offsetHeight - point.value.h) max.value.x = div.value.offsetWidth max.value.y = div.value.offsetHeight for (let index = 0; index < value.value.length; index++) { let x_y = coordinate_transformation_value_to_xy(value.value[index].x, value.value[index].y) let def_x_y = coordinate_transformation_value_to_xy(value.value[index].def_x, value.value[index].def_x) value_point.value[index].x = x_y.x value_point.value[index].y = x_y.y value_point.value[index].def_x = def_x_y.x value_point.value[index].def_y = def_x_y.y } } catch (error) { } } /** * 滚轮切换 * @param details */ const details_selsect=(details:any) => { let spt=details.deltaY/100 if(spt<0){ if(options_model.value>=value_point.value.length-1){ options_model.value=0 }else{ options_model.value++ } }else{ if(options_model.value<=1){ options_model.value=value_point.value.length-1 }else{ options_model.value-- } } } /** * 滚轮改变数据 */ const details_selsect_val = (details: any, type: string) => { let spt = details.deltaY / 100 switch (type) { case 'x': if (spt < 0) { value.value[options_model.value].x++ } else { value.value[options_model.value].x-- } break; default: if (spt < 0) { value.value[options_model.value].y++ } else { value.value[options_model.value].y-- } break; } chang(options_model.value,"","") } defineExpose({ options_model, }); return { details_selsect, resetall, div, max, point, options_model, value, value_point, dragStartHandle, chang, reset, value_point_amount, chang_point_amount, options, details_selsect_val } } }) </script>