1.热区新增热区回显

sws 2024-08-12
v1.0.0
sws 2024-08-12 16:06:29 +08:00
parent 0b9ebaf5c1
commit e2cd246b21
7 changed files with 58 additions and 57 deletions

View File

@ -1,7 +1,7 @@
<template>
<div class="slider w">
<el-slider v-model="internal_value" :min="min" :max="max" :step="step" />
<input-number v-model="internal_value" class="slider-input" :min="min" :max="max"></input-number>
<el-slider v-model="modelValue" :min="min" :max="max" :step="step" />
<input-number v-model="modelValue" class="slider-input" :min="min" :max="max"></input-number>
</div>
</template>
@ -20,7 +20,7 @@ const props = defineProps({
default: 1,
},
});
const internal_value = defineModel({ type: Number, default: 0 });
const modelValue = defineModel({ type: Number, default: 0 });
</script>
<style lang="scss" scoped>
.slider {

View File

@ -16,7 +16,7 @@
<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 v-for="(item, index) in hot_list.data" :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>
<div class="drag-btn" :data-index="index" @mousedown.prevent="start_drag_btn(index, $event)"></div>
<div class="text">
@ -32,7 +32,7 @@
<div class="size-16 fw mb-10">图片热区</div>
<div class="size-12 cr-9 mb-20">框选热区范围双击设置热区信息</div>
<div class="flex-col gap-20 item">
<div v-for="(item, index) in hot_list.hot" :key="index" class="flex-row align-c gap-10">
<div v-for="(item, index) in hot_list.data" :key="index" class="flex-row align-c gap-10">
<el-input v-model="item.name" class="name" placeholder="名称"></el-input>
<url-value v-model="item.link"></url-value>
<icon name="del" size="20" @click="del_event(index)"></icon>
@ -89,16 +89,9 @@ const hot_list = ref<hotData>({
img: '',
img_height: 1,
img_width: 1,
hot: [],
data: [],
});
const hot_list_index = ref(0);
watch(
() => modelValue.value,
(val) => {
hot_list.value = cloneDeep(val);
},
{ immediate: true, deep: true }
);
//#region -----------------------------------------------start
const imgBoxRef = ref<HTMLElement | null>(null);
@ -134,8 +127,8 @@ const end_drag = (event: MouseEvent) => {
if (!imgBoxRef.value) return;
init_drag_style.value = ``;
if (rect_end.value.width > 16 && rect_end.value.height > 16) {
hot_list.value.hot.push({
name: '热区' + (hot_list.value.hot.length + 1),
hot_list.value.data.push({
name: '热区' + (hot_list.value.data.length + 1),
link: {},
drag_start: cloneDeep(rect_start.value),
drag_end: cloneDeep(rect_end.value),
@ -143,6 +136,7 @@ const end_drag = (event: MouseEvent) => {
}
rect_end.value = { x: 0, y: 0, width: 0, height: 0 };
};
const area_box_point = ref({ x: 0, y: 0 });
// area-box
const dbl_drag_event = (item: hotListData, index: number) => {
@ -155,15 +149,15 @@ const start_drag_area_box = (index: number, event: MouseEvent) => {
hot_list_index.value = index;
event.stopPropagation();
drag_box_bool.value = true;
let clone_drag_start = cloneDeep(hot_list.value.hot[hot_list_index.value].drag_start);
let clone_drag_end = cloneDeep(hot_list.value.hot[hot_list_index.value].drag_end);
let clone_drag_start = cloneDeep(hot_list.value.data[hot_list_index.value].drag_start);
let clone_drag_end = cloneDeep(hot_list.value.data[hot_list_index.value].drag_end);
//
area_box_point.value = {
x: clone_drag_start.x - event.clientX,
y: clone_drag_start.y - event.clientY,
};
//
//
document.onmousemove = (areaBoxEvent) => {
areaBoxEvent.stopPropagation();
if (drag_box_bool.value) {
@ -186,8 +180,8 @@ const start_drag_area_box = (index: number, event: MouseEvent) => {
if (new_coordinate.y + Math.max(clone_drag_end.height, 1) > imgBoxRef.value.getBoundingClientRect().height) {
new_coordinate.y = imgBoxRef.value.getBoundingClientRect().height - Math.max(clone_drag_end.height, 1) - 7;
}
hot_list.value.hot[hot_list_index.value].drag_start.x = new_coordinate.x;
hot_list.value.hot[hot_list_index.value].drag_start.y = new_coordinate.y;
hot_list.value.data[hot_list_index.value].drag_start.x = new_coordinate.x;
hot_list.value.data[hot_list_index.value].drag_start.y = new_coordinate.y;
}
};
document.onmouseup = (areaBoxEvent) => {
@ -200,8 +194,8 @@ const start_drag_btn = (index: number, event: MouseEvent) => {
hot_list_index.value = index;
event.stopPropagation();
drag_box_scale_bool.value = true;
let clone_drag_start = hot_list.value.hot[hot_list_index.value].drag_start;
let clone_drag_end = hot_list.value.hot[hot_list_index.value].drag_end;
let clone_drag_start = hot_list.value.data[hot_list_index.value].drag_start;
let clone_drag_end = hot_list.value.data[hot_list_index.value].drag_end;
document.onmousemove = (dragBtnEvent) => {
dragBtnEvent.stopPropagation();
//
@ -209,7 +203,7 @@ const start_drag_btn = (index: number, event: MouseEvent) => {
if (!imgBoxRef.value) return;
clone_drag_end.x = dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left;
clone_drag_end.y = dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top;
hot_list.value.hot[hot_list_index.value].drag_end = {
hot_list.value.data[hot_list_index.value].drag_end = {
x: clone_drag_end.x,
y: clone_drag_end.y,
width: clone_drag_end.x - clone_drag_start.x > 0 ? clone_drag_end.x - clone_drag_start.x : 0,
@ -223,7 +217,7 @@ const start_drag_btn = (index: number, event: MouseEvent) => {
};
};
const del_area_event = (index: number) => {
hot_list.value.hot.splice(index, 1);
hot_list.value.data.splice(index, 1);
};
const rect_style = computed(() => {
return (start: rectCoords, end: rectCoords) => {
@ -234,7 +228,7 @@ const rect_style = computed(() => {
//#region -----------------------------------------------start
const del_event = (index: number) => {
hot_list.value.hot.splice(index, 1);
hot_list.value.data.splice(index, 1);
};
//#endregion -----------------------------------------------end
@ -248,8 +242,8 @@ const hot_close_event = () => {
hot_dialog_visible.value = false;
};
const hot_confirm_event = () => {
hot_list.value.hot[hot_list_index.value].link = form.value.link;
hot_list.value.hot[hot_list_index.value].name = form.value.name;
hot_list.value.data[hot_list_index.value].link = form.value.link;
hot_list.value.data[hot_list_index.value].name = form.value.name;
hot_close_event();
};
//#endregion -----------------------------------------------end
@ -260,6 +254,7 @@ const open_hot_event = () => {
if (modelValue.value.img.length > 0) {
dialog_visible.value = true;
hot_list.value = cloneDeep(modelValue.value);
console.log(1);
} else {
ElMessage({
type: 'warning',
@ -274,16 +269,16 @@ const close_event = () => {
};
//
const confirm_event = () => {
if (hot_list.value.hot.length > 0) {
if (hot_list.value.data.length > 0) {
// hotlink
if (is_obj_empty(hot_list.value.hot)) {
if (is_obj_empty(hot_list.value.data)) {
ElMessage({
type: 'warning',
message: '请先设置热区',
});
return;
}
const no_link_list = hot_list.value.hot.filter((item) => {
const no_link_list = hot_list.value.data.filter((item) => {
return is_obj_empty(item.link);
});
if (no_link_list.length > 0) {
@ -292,7 +287,7 @@ const confirm_event = () => {
} else {
hot_list.value.img_height = imgRef.value?.clientHeight || 0;
hot_list.value.img_width = imgRef.value?.clientWidth || 0;
modelValue.value = hot_list.value;
modelValue.value = cloneDeep(hot_list.value);
close_event();
}
} else {

View File

@ -2,7 +2,7 @@
<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 v-for="(item, index) in hot_data" :key="index" class="hot_box" :style="rect_style(item.drag_start, item.drag_end)"></div>
</div>
</div>
</template>
@ -19,41 +19,44 @@ const hotRef = ref<HTMLElement | null>(null);
const style = ref('');
const style_container = ref('');
const img = ref('');
const hot = ref<hotListData[]>([]);
const hot_data = ref<hotListData[]>([]);
//
const img_width = ref(1);
const img_height = ref(1);
// containerRef
const w_scale1 = ref(1);
const h_scale1 = ref(1);
// hotRef
const w_scale2 = ref(1);
const h_scale2 = ref(1);
watch(
props.value,
(newVal, oldValue) => {
const new_content = newVal?.content || {};
const new_style = newVal?.style || {};
img.value = new_content?.img[0];
hot.value = new_content?.hot.hot;
hot_data.value = new_content?.hot?.data || [];
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);
nextTick(() => {
if (containerRef.value && hotRef.value) {
//
w_scale1.value = containerRef.value?.clientWidth / img_width.value;
h_scale1.value = containerRef.value?.clientHeight / img_height.value;
// containerRefhotRef
w_scale2.value = hotRef.value?.clientWidth / containerRef.value?.clientWidth;
h_scale2.value = hotRef.value?.clientHeight / containerRef.value?.clientHeight;
}
});
},
{ 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;`;
return `left: ${start.x * w_scale1.value * w_scale2.value}px;top: ${start.y * h_scale1.value * h_scale2.value}px;width: ${Math.max(end.width * w_scale1.value * w_scale2.value, 1)}px;height: ${Math.max(end.height * h_scale1.value * h_scale2.value, 1)}px;display: flex;`;
};
});
</script>
@ -61,8 +64,10 @@ const rect_style = computed(() => {
.hot {
min-height: 1rem;
.hot_box {
background-color: red;
background: rgba(42, 148, 255, 0.25);
border: 1px dashed #8ec6ff;
position: absolute;
opacity: 0.6;
}
}
</style>

View File

@ -4,7 +4,7 @@
<card-container class="common-content-height">
<div class="mb-12">内容设置</div>
<el-form-item label="上传照片">
<upload v-model="form.img" :limit="1" is-tips tips-text="请先选择照片图片宽度750px高度不限" @update:model-value="update_hot_data"></upload>
<upload v-model="form.img" :limit="1" is-tips tips-text="请先选择照片图片宽度750px高度不限" @update:model-value="update_upload_data"></upload>
</el-form-item>
<hot v-model="form.hot"></hot>
</card-container>
@ -23,13 +23,13 @@ const props = defineProps({
});
const form = ref(props.value);
const update_hot_data = (val: any) => {
const update_upload_data = (val: any) => {
if (val.length > 0) {
form.value.hot.img = val[0].url;
} else {
form.value.hot.img = '';
}
form.value.hot.hot = [];
form.value.hot.data = [];
};
</script>
<style lang="scss" scoped>

View File

@ -15,8 +15,10 @@ const defaultHotZone: DefaultHotZone = {
img: [],
hot: {
// /src/assets/images/components/model-user-info/avatar.png
img_height: 1,
img_width: 1,
img: '',
hot: [],
data: [],
},
},
style: {

View File

@ -186,7 +186,6 @@ watch(
//
const emits = defineEmits(['rightUpdate']);
const activeNames = reactive(['1', '2']);
console.log(import.meta.url);
const components = reactive([
{
title: '基础组件',

View File

@ -104,7 +104,7 @@ declare global {
img: string;
img_width: number;
img_height: number;
hot: hotListData[];
data: hotListData[];
};
type rectCoords = {
x: number;