1.热区新增热区回显

sws 2024-08-12
v1.0.0
sws 2024-08-12 14:36:10 +08:00
parent 1d0da72587
commit 0b9ebaf5c1
6 changed files with 74 additions and 12 deletions

View File

@ -126,7 +126,6 @@ const background_img_url_change = (arry: uploadList[]) => {
};
const margin_event = (val: number | undefined) => {
form.margin = Number(val);
form.margin_top = Number(val);
form.margin_bottom = Number(val);
form.margin_left = Number(val);

View File

@ -11,8 +11,10 @@
<div class="left-content flex-1 pa-20">
<el-scrollbar class="img-scrollbar">
<div class="img-container">
<div ref="imgBoxRef" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
<el-image :src="hot_list.img" class="w img" @selectstart.prevent @contextmenu.prevent @dragstart.prevent></el-image>
<div ref="imgBoxRef" class="oh" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
<div ref="imgRef">
<el-image :src="hot_list.img" class="w img" @selectstart.prevent @contextmenu.prevent @dragstart.prevent></el-image>
</div>
<div ref="areaRef" class="area" :style="init_drag_style"></div>
<div v-for="(item, index) in hot_list.hot" :key="index" class="area-box" :style="rect_style(item.drag_start, item.drag_end)" @mousedown.prevent="start_drag_area_box(index, $event)" @dblclick="dbl_drag_event(item, index)">
<div class="del-btn" @click.stop="del_area_event(index)"><icon name="close"></icon></div>
@ -85,6 +87,8 @@ const modelValue = defineModel({ type: Object as PropType<hotData>, default: {}
const dialog_visible = defineModel('visibleDialog', { type: Boolean, default: false });
const hot_list = ref<hotData>({
img: '',
img_height: 1,
img_width: 1,
hot: [],
});
const hot_list_index = ref(0);
@ -98,6 +102,7 @@ watch(
//#region -----------------------------------------------start
const imgBoxRef = ref<HTMLElement | null>(null);
const imgRef = ref<HTMLElement | null>(null);
const rect_start = ref<rectCoords>({ x: 0, y: 0, width: 0, height: 0 });
const rect_end = ref<rectCoords>({ x: 0, y: 0, width: 0, height: 0 });
const areaRef = ref<HTMLElement | null>(null);
@ -254,6 +259,7 @@ const hot_confirm_event = () => {
const open_hot_event = () => {
if (modelValue.value.img.length > 0) {
dialog_visible.value = true;
hot_list.value = cloneDeep(modelValue.value);
} else {
ElMessage({
type: 'warning',
@ -268,8 +274,30 @@ const close_event = () => {
};
//
const confirm_event = () => {
modelValue.value = hot_list.value;
close_event();
if (hot_list.value.hot.length > 0) {
// hotlink
if (is_obj_empty(hot_list.value.hot)) {
ElMessage({
type: 'warning',
message: '请先设置热区',
});
return;
}
const no_link_list = hot_list.value.hot.filter((item) => {
return is_obj_empty(item.link);
});
if (no_link_list.length > 0) {
ElMessage.error('请设置热区链接!');
return;
} else {
hot_list.value.img_height = imgRef.value?.clientHeight || 0;
hot_list.value.img_width = imgRef.value?.clientWidth || 0;
modelValue.value = hot_list.value;
close_event();
}
} else {
ElMessage.error('至少选择一个热区!');
}
};
//#endregion -----------------------------------------------end
</script>

View File

@ -1,7 +1,8 @@
<template>
<div :style="style_container">
<div class="video re" :style="style">
<div ref="containerRef" class="oh" :style="style_container">
<div ref="hotRef" class="hot re" :style="style">
<image-empty v-model="img" class="w" error-img-style="width:10rem;height:10rem;" error-style="padding:15rem 0;"></image-empty>
<div v-for="(item, index) in hot" :key="index" class="hot_box" :style="rect_style(item.drag_start, item.drag_end)"></div>
</div>
</div>
</template>
@ -13,24 +14,55 @@ const props = defineProps({
default: () => ({}),
},
});
const containerRef = ref<HTMLElement | null>(null);
const hotRef = ref<HTMLElement | null>(null);
const style = ref('');
const style_container = ref('');
const img = ref('');
const hot = ref<hotListData[]>([]);
const img_width = ref(1);
const img_height = ref(1);
watch(
props.value,
(newVal, oldValue) => {
console.log(newVal);
const new_content = newVal?.content || {};
const new_style = newVal?.style || {};
img.value = new_content?.img[0];
hot.value = new_content?.hot.hot;
img_width.value = new_content?.hot.img_width || 1;
img_height.value = new_content?.hot.img_height || 1;
style_container.value = common_styles_computer(new_style.common_style);
},
{ immediate: true, deep: true }
);
const rect_style = computed(() => {
return (start: rectCoords, end: rectCoords) => {
let w_scale1 = 1;
let h_scale1 = 1;
let w_scale2 = 1;
let h_scale2 = 1;
if (containerRef.value && hotRef.value) {
//
w_scale1 = containerRef.value?.clientWidth / img_width.value;
h_scale1 = containerRef.value?.clientHeight / img_height.value;
// containerRefhotRef
w_scale2 = hotRef.value?.clientWidth / containerRef.value?.clientWidth;
h_scale2 = hotRef.value?.clientHeight / containerRef.value?.clientHeight;
}
console.log('containerRef', containerRef.value?.clientWidth, containerRef.value?.clientHeight, 'hotRef', hotRef.value?.clientWidth, hotRef.value?.clientHeight);
console.log('w_scale1', w_scale1, 'h_scale1', h_scale1, 'w_scale2', w_scale2, 'h_scale2', h_scale2);
return `left: ${start.x * w_scale1 * w_scale2}px;top: ${start.y * h_scale1 * h_scale2}px;width: ${Math.max(end.width * w_scale1 * w_scale2, 1)}px;height: ${Math.max(end.height * h_scale1 * h_scale2, 1)}px;display: flex;`;
};
});
</script>
<style lang="scss" scoped>
.video {
.hot {
min-height: 1rem;
.hot_box {
background-color: red;
position: absolute;
}
}
</style>

View File

@ -29,6 +29,7 @@ const update_hot_data = (val: any) => {
} else {
form.value.hot.img = '';
}
form.value.hot.hot = [];
};
</script>
<style lang="scss" scoped>

View File

@ -13,9 +13,9 @@ const props = defineProps({
},
});
//
let form = reactive(props.value);
let form = ref(props.value);
const common_styles_update = (val: Object) => {
form.common_style = val;
form.value.common_style = val;
};
</script>
<style lang="scss" scoped>

View File

@ -102,6 +102,8 @@ declare global {
*/
type hotData = {
img: string;
img_width: number;
img_height: number;
hot: hotListData[];
};
type rectCoords = {