<style> .diy-rubik .layout { /* width: 750px; */ position: relative; } .diy-rubik .layout .rubik { position: absolute; top: 0; left: 0; border: 1px dashed #c9c9c9; cursor: pointer; color: #c9c9c9; z-index: 11; } .diy-component-preview { background-color: #fff; } .diy-component-preview:hover { box-shadow: inset 0 0 10000px rgba(0, 0, 0, .03); } .diy-rubik .block { border: 1px solid #e0e0e0; padding: 25px; margin: 0 50px 50px 0; zoom: 0.2; text-align: center; cursor: pointer; } .diy-rubik .rubik-list { width: 750px; height: 372px; } .diy-rubik .block.active { border: 1px #5CB3FD solid; } .defaultImg { background: url('../../../assets/img/default.png') } .diy-rubik .layout .rubik.active { border: 1px solid #5CB3FD; } .app-gallery-item { width: 100px; height: 100px; border: 1px solid #e3e3e3; border-radius: 2px; margin-right: 10px; margin-bottom: 10px; position: relative; } .diy-rubik .layout .rubik .delete { position: absolute; right: -16px; top: -16px; padding: 8px; z-index: 14; } </style> <template> <div :class="{'active':rubData.isCked}"> <div class="diy-component-options" v-if="rubData.isCked"> <el-button type="primary" icon="el-icon-delete" style="left: -25px; top: 0px;" @click="delPlugin()"></el-button> <el-button type="primary" icon="el-icon-document-copy" style="left: -25px; top: 30px;"></el-button> <el-button type="primary" icon="el-icon-arrow-up" v-if="index>0" @click="resetSord(0)" style="right: -25px; top: 0;"></el-button> <el-button type="primary" icon="el-icon-arrow-down" v-if="index!=dataLeng-1" @click="resetSord(1)" style="right: -25px; top: 30px;"></el-button> </div> <div class="diy-rubik"> <div class="diy-component-preview" :style="{backgroundColor:rubData.data.background}"> <div :style="{paddingTop:rubData.data.top+'px',paddingRight:rubData.data.right+'px',paddingBottom:rubData.data.bottom+'px', paddingLeft:rubData.data.left+'px'}"> <div class="layout" :style="blockStyle(rubData.data.style)" :class="{'defaultImg':rubData.data.style==8}" @click="blockClick"> <div class="rubik" style="width:100%;height:100%;" @mousemove="blockMove" :style="rubData.isCked ? (isMove ? 'z-index: 12' : 'z-index: 10') : 'z-index: 16'"></div> <template v-for="(item, index) in cList"> <div class="rubik" flex="main:center cross:center" :key="index+1" @click.stop="selectRubik(index)" :class="rubik == index ? 'active' : ''" :style="layoutRubik(index)"> <template v-if="rubData.data.style == 8"> <el-button class="delete" v-show="index == rubik && !isMove" size="mini" type="danger" icon="el-icon-close" circle @click.stop="deleteRubik(index)"></el-button> </template> <span v-if="!rubData.data.list[index].pic_url">{{rubikSize(index)}}</span> <img v-else :src="getIconLink(rubData.data.list[index].pic_url)" style="width: 100%;visibility: hidden;"> </div> <div class="rubik" :style="emptyStyle(index)" v-if="rubData.data.style == 8" :key="index"></div> <img v-if="rubData.data.list[index].pic_url && rubData.data.style == 0" :src="getIconLink(rubData.data.list[index].pic_url)" :key="index" style="width: 100%;visibility: hidden;display: block"> </template> </div> </div> </div> <div class="diy-component-edit" v-if="rubData.isCked"> <el-form label-width="100px"> <el-tabs v-model="activeName" type="card"> <el-tab-pane label="图片样式" name="first"> <el-row> <el-col :span="12"> <el-form-item label="上边距"> <el-input type="text" size="small" @keyup.native="checkInteger(rubData.data,'top','-')" v-model="rubData.data.top" @change="getminNum()"> <template slot="append">px</template> </el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="下边距"> <el-input type="text" size="small" @keyup.native="checkInteger(rubData.data,'bottom','-')" v-model="rubData.data.bottom" @change="getminNum()"> <template slot="append">px</template> </el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="左边距"> <el-input type="text" size="small" @keyup.native="checkInteger(rubData.data,'left','-')" v-model="rubData.data.left" @change="getminNum()"> <template slot="append">px</template> </el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="右边距"> <el-input type="text" size="small" @keyup.native="checkInteger(rubData.data,'right','-')" v-model="rubData.data.right" @change="getminNum()"> <template slot="append">px</template> </el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="背景色"> <el-color-picker v-model="rubData.data.background"></el-color-picker> </el-form-item> </el-col> </el-row> <el-form-item label="样式"> <div flex="dir:left" style="flex-wrap: wrap;"> <div class="block" @click="selectStyle(index)" :class="blockActive(index)" v-for="(item,index) in style_list" :key="index"> <div class="rubik-list"> <img :src="item.icon" style="width: 750px; height: 360px;" alt="" /> </div> <div style="font-size: 60px; margin: 30px;">{{item.name}}</div> </div> </div> </el-form-item> </el-tab-pane> <el-tab-pane label="图片上传" name="second"> <el-form-item label="图片间隙" v-if="rubData.data.style > 0"> <el-input v-model="rubData.data.space" size="small" type="number" min="0" max="10"> <template slot="append">px</template> </el-input> </el-form-item> <template v-if="rubData.data.style == 8"> <el-form-item label="魔方宽度"> <el-input v-model="rubData.data.w" size="small" type="number" min="0" max="10"> </el-input> </el-form-item> <el-form-item label="魔方高度"> <el-input v-model="rubData.data.h" size="small" type="number" min="0" max="10"> </el-input> </el-form-item> </template> <template v-if="rubData.data.list&&!rubData.data.list[rubik]"> <el-form-item label="图片上传"> <span>请先在左边选择图片位置</span> </el-form-item> </template> <template v-else> <el-card shadow="never"> <el-form-item label="图片上传"> <el-button size="mini" @click="choicImg=true">选择图片</el-button> <div flex style="flex-wrap: wrap;" v-if="rubData.data.list&&rubData.data.list[rubik].pic_url"> <div flex="main:center cross:center" class="app-gallery-item" style="height: 100px; width: 100px;"> <img :src="getIconLink(rubData.data.list[rubik].pic_url)" style="width:100%;height:100%;"> </div> </div> </el-form-item> <el-form-item label="选择链接"> <div style="border:1px solid #dcdfe6;padding:5px;" v-if="rubData.data.list&&rubData.data.list.length>0 && rubData.data.list[rubik].link && rubData.data.list[rubik].link.length>0"> <el-input size="small" style="width: 100%;margin-bottom:5px;" placeholder="名称" v-model="rubData.data.list[rubik].link[0].PageName"> </el-input> <el-input size="small" v-model="rubData.data.list[rubik].link[0].PageUrl" placeholder="点击选择链接"> <template slot="append"> <el-button @click="isShowLink=true">选择链接</el-button> </template> </el-input> </div> </el-form-item> </el-card> </template> <el-form-item label="热区划分"> <choiceArea :multiple="true" :pic-list="rubData.data.list" :hotspot-array="rubData.data.hotspot" width="750px" :height="rubData.data.height + 'px'" @confirm="selectHotspot" :is-link="true" :chooseType="'rubik'"> <el-button size="mini">划分热区</el-button> </choiceArea> </el-form-item> </el-tab-pane> </el-tabs> </el-form> </div> </div> <!-- 选择图片文件 --> <el-dialog title="选择文件" :visible.sync="choicImg" width="1240px"> <ChooseImg @SelectId="SelectId"></ChooseImg> </el-dialog> <el-dialog title="选择链接" :visible.sync="isShowLink" width="800px"> <chooseMenu ref="chooseMenu"></chooseMenu> <span slot="footer" class="dialog-footer"> <el-button size="small" @click="isShowLink=false">取 消</el-button> <el-button size="small" type="danger" @click="getChoiceLink()">确 定</el-button> </span> </el-dialog> </div> </template> <script> import chooseMenu from "../../common/chooseMenu.vue"; import ChooseImg from "@/components/global/ChooseImg.vue"; import choiceArea from "../../common/choiceArea.vue"; export default { props: ["rubData", "index", "dataLeng"], data() { return { rubik: 0, init: true, activeName: 'first', link: '', isMove: false, zoom: 2, // 缩放倍数 choicImg: false, isShowLink: false, style_list: [{ name: '1张图', height: 360, w: 1, h: 1, list: [{ w: 1, h: 1, x: 0, y: 0, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-0.png', }, { name: '2张图', height: 360, w: 25, h: 12, list: [{ w: 10, h: 12, x: 0, y: 0, }, { w: 15, h: 12, x: 10, y: 0, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-1.png', }, { name: '3张图', height: 360, w: 25, h: 12, list: [{ w: 10, h: 12, x: 0, y: 0, }, { w: 15, h: 6, x: 10, y: 0, }, { w: 15, h: 6, x: 10, y: 6, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-2.png', }, { name: '4张图', height: 360, w: 50, h: 24, list: [{ w: 20, h: 24, x: 0, y: 0, }, { w: 30, h: 12, x: 20, y: 0, }, { w: 15, h: 12, x: 20, y: 12, }, { w: 15, h: 12, x: 35, y: 12, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-3.png', }, { name: '2张图平分', height: 240, w: 50, h: 16, list: [{ w: 25, h: 16, x: 0, y: 0, }, { w: 25, h: 16, x: 25, y: 0, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-4.png', }, { name: '3张图平分', height: 240, w: 75, h: 24, list: [{ w: 25, h: 24, x: 0, y: 0, }, { w: 25, h: 24, x: 25, y: 0, }, { w: 25, h: 24, x: 50, y: 0, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-5.png', }, { name: '4张图左右平分', height: 186, w: 4, h: 1, list: [{ w: 1, h: 1, x: 0, y: 0, }, { w: 1, h: 1, x: 1, y: 0, }, { w: 1, h: 1, x: 2, y: 0, }, { w: 1, h: 1, x: 3, y: 0, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-6.png', }, { name: '4张图上下平分', height: 372, w: 250, h: 124, list: [{ w: 125, h: 62, x: 0, y: 0, }, { w: 125, h: 62, x: 125, y: 0, }, { w: 125, h: 62, x: 0, y: 62, }, { w: 125, h: 62, x: 125, y: 62, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-7.png', }, { name: '自定义魔方', height: 372, w: 375, h: 186, list: [{}, { w: 125, h: 93, x: 125, y: 0, }, { w: 125, h: 93, x: 250, y: 0, }, { w: 125, h: 93, x: 0, y: 93, }, { w: 125, h: 93, x: 125, y: 93, }, { w: 125, h: 93, x: 250, y: 93, }, ], icon: this.domainManager().ImageUrl + '/Static/rubik-8.png', }, ] }; }, created() {}, components: { ChooseImg, chooseMenu, choiceArea }, computed: { cList() { return this.rubData.data.list }, }, methods: { //删除链接 deleteRubik(index) { this.cList.splice(index); }, // 魔方展示样式(preview) blockStyle(index) { if (index === 8) { let per = 750 / this.rubData.data.w; this.rubData.data.height = this.rubData.data.h * 750 / this.rubData.data.w; return `height: ${this.rubData.data.height}px;background-size: ${per}px ${per}px;`; } else { if (index === 0) { this.rubData.data.height = 'auto'; if (this.rubData.data.list && this.rubData.data.list.length > 0) { return `height: ${this.rubData.data.list[0].pic_url ? 'auto' : '360px'}`; } } return `height: ${this.style_list[index] ? this.style_list[index].height : 360}px`; } }, // 自定义魔方点击事件(preview) blockClick(e) { if (this.rubData.data.style < 8) { return; } if (this.isMove) { this.isMove = false; this.rubData.data.list[this.rubik] ? this.rubData.data.list[this.rubik].zIndex = 11 : ''; } else { this.isMove = true; // 每一小格的宽度 let per = this.rubData.data.w > 0 && this.rubData.data.h > 0 ? 750 / this.rubData.data.w : 750; // 每一小格宽度的百分比 let wPer = this.rubData.data.w > 0 ? 100 / this.rubData.data.w : 100; // 每一小格高度的百分比 let hPer = this.rubData.data.h > 0 ? 100 / this.rubData.data.h : 100; // x轴占多少格 let numberX = Math.floor(e.offsetX * this.zoom / per); // y轴咱多少格 let numberY = Math.floor(e.offsetY * this.zoom / per); for (let i in this.rubData.data.list) { let _this = this.rubData.data.list[i]; if (numberX >= _this.x && numberX < _this.x + _this.w && numberY >= _this.y && numberY < _this.y + _this .h) { this.isMove = false; return; } } let block = { backgroundColor: '#fff', numberX: numberX, numberY: numberY, x: numberX, y: numberY, w: 1, h: 1, link: {} }; this.rubData.data.list.push(JSON.parse(JSON.stringify(block))); this.rubik = this.rubData.data.list.length - 1; } }, // 选择图片展示样式(edit) selectStyle(index) { this.rubData.data.style = index; if (index === 8) { this.rubData.data.list = []; this.rubData.data.w = 1; this.rubData.data.h = 1; return; } let style = JSON.parse(JSON.stringify(this.style_list[index])); for (let i in style.list) { style.list[i].link = [{ PageUrl: '', IsParameter: 0, ParameterValue: '', PageName: '' }]; } this.rubData.data.height = style.height; this.rubData.data.w = style.w; this.rubData.data.h = style.h; this.rubData.data.list = style.list; this.rubData.data.hotspot = []; }, // 图片展示样式选中(edit) blockActive(index) { return this.rubData.data.style === index ? 'active' : '' }, // 图片选中事件(preview) selectRubik(index) { if (this.rubData.data.list && this.rubData.data.list[this.rubik]) { this.rubData.data.list[this.rubik].zIndex = 11; } this.rubik = index; this.isMove = false; }, // 选中图片展示样式的展示(preview) layoutRubik(index) { let list = this.rubData.data.list; if (!list) { return ''; } let style = list[index]; style = this.getStyle(style, this.rubData.data, true, true); if (style.pic_url) { style.backgroundImage = `url('${this.getIconLink(style.pic_url)}')`; style.backgroundRepeat = 'no-repeat'; style.backgroundSize = 'cover'; style.backgroundPosition = 'center'; } return style; }, // 通过占比获取图片的宽度、高度、左边距、上边距 getStyle(block, list, isSpace = true, isPreview = false) { let width = block.w * 100 / list.w + '%'; let height = block.h * 100 / list.h + '%'; let left = block.x * 100 / list.w + '%'; let top = block.y * 100 / list.h + '%'; if (isSpace) { let space = this.rubData.data.space; let wMultiple = 0; let hMultiple = 0; if (block.w < list.w) { wMultiple += 1; } if (block.h < list.h) { hMultiple += 1; } if (block.x > 0) { left = `calc(${left} + ${space}px)`; } if (block.y > 0) { top = `calc(${top} + ${space}px)`; } if (block.x + block.w < list.w && block.x > 0) { wMultiple += 1; } if (block.y + block.h < list.h && block.y > 0) { hMultiple += 1; } width = `calc(${width} - ${space * wMultiple}px)`; height = `calc(${height} - ${space * hMultiple}px)`; } if (this.rubData.data.style === 0 && isPreview && this.rubData.data.list[0].pic_url) { height = 'auto'; } block.width = width; block.height = height; block.left = left; block.top = top; return block; }, // 各个图片的尺寸标注(preview) rubikSize(index) { if (this.rubData.data.style <= -1) { return ''; } if (this.rubData.data.style == 0) { return '宽度为750,不限高度'; } let style = this.rubData.data; let object = style.list[index]; return `${Math.ceil(object.w * 750 / style.w)}*${Math.ceil(object.h * 750 / style.w)}`; }, emptyStyle(index) { let list = JSON.parse(JSON.stringify(this.rubData.data.list)); if (!list) { return ''; } let style = list[index]; style = this.getStyle(style, this.rubData.data, false, true); style.background = '#F7F7F7'; style.zIndex = 9; style.border = 'none'; return style; }, // 自定义魔方鼠标移动事件(preview) blockMove(e) { if (!this.isMove) { return; } let per = this.rubData.data.w > 0 && this.rubData.data.h > 0 ? 750 / this.rubData.data.w : 750; let wPer = this.rubData.data.w > 0 ? 100 / this.rubData.data.w : 100; let hPer = this.rubData.data.h > 0 ? 100 / this.rubData.data.h : 100; let future = this.rubData.data.list[this.rubik]; if (!future) { return; } // x轴占多少格 let numberX = Math.floor(e.offsetX * this.zoom / per); // y轴咱多少格 let numberY = Math.floor(e.offsetY * this.zoom / per); let futureX = Math.min(numberX, future.numberX); let futureY = Math.min(numberY, future.numberY); let futureW = (Math.abs(numberX - future.numberX) + 1); let futureH = (Math.abs(numberY - future.numberY) + 1); for (let i in this.rubData.data.list) { let _this = this.rubData.data.list[i]; if (i == this.rubik) { continue; } if (futureX + futureW <= _this.x) { continue; } else if (futureX < _this.x && futureX + futureW > _this.x) { if (futureH + futureY <= _this.y) { continue; } else if (futureY < _this.y && futureY + futureH > _this.y) { futureH = _this.y - futureY; } else if (futureY >= _this.y && futureY < _this.y + _this.h) { futureW = _this.x - futureX; } else { continue; } } else if (futureX >= _this.x && futureX < _this.x + _this.w) { if (futureY + futureH <= _this.y) { continue; } else if (futureY + futureH > _this.y && futureY < _this.y) { futureH = _this.y - futureY; } else if (futureY >= _this.y && futureY < _this.y + _this.h) { return; } else { continue; } } else { continue; } } if (futureW == 0) { return; } if (futureH == 0) { return; } future.x = futureX; future.y = futureY; future.w = futureW; future.h = futureH; }, rubikLink() { if (!this.rubData.data.list[this.rubik].link) { Vue.set(this.rubData.data.list[this.rubik], 'link', {}); } return this.rubData.data.list[this.rubik].link.name }, //获取选择链接 getChoiceLink() { //调用子组件方法 var obj = this.$refs.chooseMenu.getChooseMenu(); if (this.rubik < 0) { return ''; } if (this.rubData.data.list.length <= 0) { return ''; } this.rubData.data.list[this.rubik].link[0].PageUrl = obj.PageUrl; this.rubData.data.list[this.rubik].link[0].IsParameter = obj.IsParameter; this.rubData.data.list[this.rubik].link[0].ParameterValue = obj.ParameterValue; this.rubData.data.list[this.rubik].link[0].PageName = obj.PageName; this.rubData.data.list[this.rubik].link[0].new_link_url = obj.new_link_url; this.isShowLink = false; }, // 热区选择(edit) selectHotspot(list) { this.rubData.data.hotspot = list; }, //选择图片 SelectId(msg) { this.rubData.data.list[this.rubik].pic_url = msg.url; this.choicImg = false; }, //向父组件传值 并调用排序 resetSord(IsUp) { this.$emit('getSord', this.index, IsUp); }, //点击触发父组件删除 delPlugin() { this.$emit('comDelPlugin', this.index); }, getminNum(){ if(this.rubData.data.top==''){ this.rubData.data.top=0; } if(this.rubData.data.right==''){ this.rubData.data.right=0; } if(this.rubData.data.bottom==''){ this.rubData.data.bottom=0; } if(this.rubData.data.left==''){ this.rubData.data.left=0; } } }, updated() { this.init = false; }, watch: { 'rubData.data.w': { handler(newVal, oldVal) { if (this.rubData.data.style == 8 && !this.init) { this.rubData.data.list = []; } this.rubData.data.w = Math.max(newVal, 1); if (this.rubData.data.style == 8) { this.rubData.data.w = Math.min(this.rubData.data.w, 10) } }, }, 'rubData.data.h': { handler(newVal, oldVal) { if (this.rubData.data.style == 8 && !this.init) { this.rubData.data.list = []; } this.rubData.data.h = Math.max(newVal, 1); if (this.rubData.data.style == 8) { this.rubData.data.h = Math.min(this.rubData.data.h, 10) } }, }, 'rubData.data.space': { handler(newVal, oldVal) { this.rubData.data.space = Math.min(Math.max(newVal, 0), 10); }, }, rubik(newVal, oldVal) { if (!this.isMove) { this.rubData.data.list[newVal] ? this.rubData.data.list[newVal].zIndex = 12 : ''; this.rubData.data.list[oldVal] ? this.rubData.data.list[oldVal].zIndex = 11 : ''; } }, space(newVal, oldVal) { this.rubData.data.space = Math.max(newVal, 0); for (let i in this.rubData.data.list) { let block = this.rubData.data.list[i]; block = this.getStyle(block, this.rubData.data); } } }, mounted() { } }; </script>