前几天体验了下有赞微商城的店铺装修,里面的自定义魔方矩阵排列布局,可以很大程度方便客户对店铺进行一个自定义的排列。
我们来分析一下功能。
首先,可以选择几行几列进行排列
可以选择哪几块作为一个模块
下面是我的代码以及效果图
<html><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>魔方矩阵</title> <!-- 引入样式文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.4/lib/index.css"> <!-- 引入 Vue 和 Vant 的 JS 文件 --> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vant@2.4/lib/vant.min.js"></script> <style type="text/css"> #app{ padding: 40px; } .decorate-cube{ position: relative; } .decorate-cube .cube-row:last-of-type .cube-item { border-right: 1px solid #e5e5e5; } .decorate-cube .cube-selected { position: absolute; background-color: #fff; border: 1px solid #ebedf0; text-align: center; color: #7d7e80; cursor: pointer; box-sizing: border-box; } .decorate-cube .cube-selected.cube-selected-click { background: #e0edff; border: 1px solid #155bd4; color: #155bd4; z-index: 2; cursor: auto; } .decorate-cube .cube-selected-text { font-size: 12px; width: 100%; position: absolute; top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%); } .decorate-cube .cube-row { float: left; list-style: none; padding: 0; margin: 0; } .decorate-cube .cube-item:first-child { border-top: 1px solid #e5e5e5; } .decorate-cube .cube-item { background: #f8f8f8; border-left: 1px solid #e5e5e5; border-bottom: 1px solid #e5e5e5; cursor: pointer; text-align: center; box-sizing: border-box; } .decorate-cube .cube-item.item-selecting{ background: #e0edff; } .decorate-cube .cube-item.item-selecting .van-icon{ display: none; } .decorate-cube .cube-item.item-selected { background: #e0edff; visibility: hidden; } .decorate-cube .cube-item.item-selected .van-icon{ display: none; } </style> </head> <body> <div id="app"> <div style="margin-bottom: 20px"> 魔方密度: <select v-model="density"> <option value='4' >4 x 4</option> <option value='5' >5 x 5</option> <option value='6' >6 x 6</option> <option value='7' >7 x 7</option> </select> </div> <div> <ul v-for="n in densityNum" > <li :class="['cube-item',{'item-selecting': isSelecting(i,n),'item-selected':isSelected(i,n) }]" v-for="i in densityNum" :style={'width':cubeItemWidth+'px','height':cubeItemHeight+'px'} :data-x="i" :data-y="n" @click="cubeItemClick($event)"> <van-icon name="plus" color="#bbbbb" :style={'line-height':cubeItemHeight+'px'} /> </li> </ul> <div v-for="(item, index) in cudeSelected" :style={'width':getCubeSelectedWidth(item)+'px','height':getCubeSelectedHeight(item)+'px','top':getCubeSelectedTop(item)+'px','left':getCubeSelectedLeft(item)+'px'} > <div> {{ Math.round(750/density*((parseInt(item.end.y) - parseInt(item.start.y) + 1))) }} x {{ Math.round(750/density*((parseInt(item.end.x) - parseInt(item.start.x) + 1))) }} 像素</div> </div> </div> </div> <script> var vm = new Vue({ el: '#app', data:{ 'density':4, //密度 'cubeWidth':320, //魔方宽度 'cubeHeight':320, //魔方高度 'cudeSelecting':{ 'start':null, 'end':null, 'data':[] }, 'cudeSelected':[] //已经生成的单元 }, computed:{ //密度值 densityNum:function () { return parseInt(this.density); }, //单元魔方高度 cubeItemHeight:function () { return this.cubeHeight/this.density; }, //单元魔方宽度 cubeItemWidth:function () { return this.cubeWidth/this.density; } }, methods:{ //魔方点击事件 cubeItemClick:function (event) { var el = event.currentTarget; var x = el.getAttribute('data-x'); var y = el.getAttribute('data-y'); var domclass = el.getAttribute('class'); console.log('['+x+','+y+','+domclass+']执行了点击'); var cudeSelectingStart = this.cudeSelecting.start; var coord = {x:x,y:y}; if(-1 !== domclass.indexOf('item-selected')){ alert("已经被占用"); return; } if(null == cudeSelectingStart){ this.cudeSelecting.start = coord; this.cudeSelecting.data.push(coord); }else{ this.cudeSelecting.end = coord; this.cudeSelecting.data.push(coord); //获取开始和结束之间所有魔方单元 var start = cudeSelectingStart; var end = coord; var x_start = Math.min(start.x,end.x); var x_end = Math.max(start.x,end.x); var y_start = Math.min(start.y,end.y); var y_end = Math.max(start.y,end.y); var real_start = {x:Math.min(start.x,end.x),y:Math.min(start.y,end.y)}; var real_end = {x:Math.max(start.x,end.x),y:Math.max(start.y,end.y)}; //清空正在选择的 vm.cudeSelecting.data.splice(0); for(var i=x_start;i<=x_end;i++){ for(var j=y_start;j<=y_end;j++){ this.cudeSelecting.data.push({x:i,y:j}); } } var cudeSelectingData = this.cudeSelecting.data; var cudeSelectedArr = []; for(var i=0;i<cudeSelectingData.length;i++){ cudeSelectedArr.push(cudeSelectingData[i]) } console.log(cudeSelectedArr); console.log(real_start); console.log(real_end); //加入选中的 var cudeSelected = { 'start':real_start, 'end':real_end, 'data':cudeSelectedArr } this.cudeSelected.push(cudeSelected); //清除正在选择的 this.cudeSelecting.start = null; this.cudeSelecting.end = null; vm.cudeSelecting.data.splice(0); } }, //判断是否正在选择 isSelecting:function (x,y) { var cudeSelectingData = this.cudeSelecting.data; for(var i = 0, len = cudeSelectingData.length; i < len; i++){ var coord = cudeSelectingData[i]; if(parseInt(coord.x) === parseInt(x) && parseInt(coord.y) === parseInt(y)){ return true; } } return false; }, //判断是否已经选择 isSelected:function (x,y) { var list = this.cudeSelected; for(var i=0;i<list.length;i++){ var data = list[i].data; for(var j=0;j<data.length;j++){ var coord = data[j]; if(parseInt(coord.x) === parseInt(x) && parseInt(coord.y) === parseInt(y)){ return true; } } } return false; }, //计算选中层的宽度 getCubeSelectedWidth:function (item) { return (parseInt(item.end.y) - parseInt(item.start.y) + 1) * this.cubeItemWidth; }, //计算选中层的高度 getCubeSelectedHeight:function (item) { return (parseInt(item.end.x) - parseInt(item.start.x) + 1) * this.cubeItemHeight; }, //计算选中层的右边距离 getCubeSelectedTop:function (item) { return (item.start.x-1) * this.cubeItemHeight; }, //计算选中层的左边距离 getCubeSelectedLeft:function (item) { return (item.start.y-1) * this.cubeItemWidth; } } }); </script> </body></html>
运行效果如下:
- 热门文章
- Mysql 8.0+开启远程访问
- Vue3+Ts 组合API调用子组件方法
- JAVA生成微信小程序分享海报
- 基于 Vue 实现魔方矩阵排列效果
- JAVA开发微信特约商户进件/提交申请单
- 检查Office(Word/Excel)文档是否需要密码-通...
- Nginx 跨域配置支持
- 微信/v3/merchant/media/upload 网络图片上...
- 简述分布式CAP理论
- Iterator迭代器设计模式
- 我的标签
- JAVA<7>
- Js<4>
- 设计模式<4>
- TS<2>
- nginx<2>
- 微信服务商<2>
- 微信小程序<1>
- Vue<1>
- Vue3<1>
- IPv6<1>
- Apache POI<1>
- Mysql<1>
- rocketmq<1>
- 分布式数据库<1>
- polygon<1>
- 地图<1>
- CAP<1>
- jQuery<1>
- Git<1>
- curl<1>
- 分布式系统<1>
- 设计<0>
- Redis<0>
- HikariCP<0>
- 数据库连接池<0>
- 多线程<0>
- 友情链接
- 江西云戈信息技术