design.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. var floatBtnListHtml = '<div class="float-btn-list">';
  2. floatBtnListHtml += '<p class="hint" style="font-size: 12px; margin: 5px 0 8px;">建议上传正方形图片</p>';
  3. floatBtnListHtml += '<ul>';
  4. floatBtnListHtml += '<li v-for="(item,index) in list" :key="item.id">';
  5. floatBtnListHtml += '<img-icon-upload :data="{data : item}"></img-icon-upload>';
  6. floatBtnListHtml += '<div class="right-wrap">';
  7. floatBtnListHtml += '<div class="action-box" v-show="item.iconType == \'icon\'">';
  8. floatBtnListHtml += '<div class="action" @click="iconStyle($event, index)"><i class="iconfont iconpifu"></i></div>';
  9. floatBtnListHtml += '<div class="action" :id="\'float-btn-color-\' + index"><i class="iconfont iconyanse"></i></div>';
  10. floatBtnListHtml += '</div>';
  11. floatBtnListHtml += '<nc-link :data="{field: $parent.data.list[index].link}"></nc-link>';
  12. floatBtnListHtml += '</div>';
  13. floatBtnListHtml += '<i class="del" @click="del(index)" data-disabled="1">x</i>';
  14. floatBtnListHtml += '<div class="error-msg"></div>';
  15. floatBtnListHtml += '</li>';
  16. floatBtnListHtml += '</ul>';
  17. floatBtnListHtml += '<div class="add-item text-color" v-if="showAddItem" @click="add">';
  18. floatBtnListHtml += '<i>+</i>';
  19. floatBtnListHtml += '<span>添加一个浮动按钮</span>';
  20. floatBtnListHtml += '</div>';
  21. floatBtnListHtml += '</div>';
  22. Vue.component("float-btn-list",{
  23. data: function () {
  24. return {
  25. list: this.$parent.data.list,
  26. maxTip : 3,//最大上传数量提示
  27. showAddItem : true,
  28. screenWidth:0,
  29. colorPicker:{}
  30. };
  31. },
  32. created : function(){
  33. if(!this.$parent.data.verify) this.$parent.data.verify = [];
  34. this.$parent.data.verify.push(this.verify);//加载验证方法
  35. this.$parent.data.ignore = ['textColor','pageBgColor','componentBgColor','elementBgColor','marginTop','marginBottom','marginBoth','componentAngle','elementAngle'];//加载忽略内容 -- 其他设置中的属性设置
  36. this.$parent.data.ignoreLoad = true; // 等待忽略数组赋值后加载
  37. getElementPosition(this.$parent);
  38. window.onresize = () => {
  39. return (() => {
  40. window.screenWidth = document.body.clientWidth;
  41. this.screenWidth = window.screenWidth
  42. })()
  43. };
  44. this.changeShowAddItem();//获取默认值
  45. this.list.forEach(function (item) {
  46. if (!item.id) item.id = ns.gen_non_duplicate(10)
  47. })
  48. },
  49. watch : {
  50. list : function(){
  51. this.changeShowAddItem();
  52. getElementPosition(this.$parent)
  53. },
  54. screenWidth(val){
  55. // 为了避免频繁触发resize函数导致页面卡顿,使用定时器
  56. getElementPosition(this.$parent);
  57. },
  58. "$parent.data.btnBottom": function () {
  59. getElementPosition(this.$parent);
  60. }
  61. },
  62. mounted(){
  63. this.fetchAllMenuIconColor();
  64. },
  65. methods: {
  66. verify :function () {
  67. var res = { code: true, message: "" };
  68. if(this.list.length >0){
  69. for(var i=0;i < this.list.length;i++){
  70. if(this.$parent.data.list[i].imageUrl == "" && this.$parent.data.list[i].icon == ""){
  71. res.code = false;
  72. res.message = "请添加图片";
  73. break;
  74. }
  75. }
  76. }else{
  77. res.code = false;
  78. res.message = "请添加一个浮动按钮";
  79. }
  80. return res;
  81. },
  82. //改变添加浮动按钮
  83. changeShowAddItem(){
  84. if(this.list.length >= this.maxTip) this.showAddItem = false;
  85. else this.showAddItem = true;
  86. },
  87. /**
  88. * 选择图标风格
  89. * @param event
  90. * @param index
  91. */
  92. iconStyle(event, index){
  93. var self = this;
  94. selectIconStyle({
  95. elem: event.currentTarget,
  96. icon: self.list[index].icon,
  97. callback: function (data) {
  98. if (data) {
  99. self.list[index].style = data;
  100. } else {
  101. iconStyleSet({
  102. style: JSON.stringify(self.list[index].style),
  103. query: {
  104. icon: self.list[index].icon
  105. }
  106. }, function(style){
  107. self.list[index].style = style;
  108. })
  109. }
  110. }
  111. })
  112. },
  113. /**
  114. * 渲染颜色组件
  115. * @param id
  116. * @param color
  117. * @param callback
  118. */
  119. colorRender(id, color, callback){
  120. var self = this;
  121. if (this.colorPicker[id]) return;
  122. setTimeout(function () {
  123. self.colorPicker[id] = Colorpicker.create({
  124. el: id,
  125. color: color,
  126. change: function (elem, hex) {
  127. callback(elem, hex)
  128. }
  129. });
  130. })
  131. },
  132. /**
  133. * 渲染全部菜单颜色选择器
  134. */
  135. fetchAllMenuIconColor(){
  136. var self = this;
  137. this.list.forEach(function (item, index) {
  138. self.colorRender('float-btn-color-' + index, '', function (elem, color) {
  139. index = $(elem).parents('li').index();
  140. if (self.list[index].style.iconBgColor.length || self.list[index].style.iconBgImg) {
  141. self.list[index].style.iconBgColor = [color];
  142. } else {
  143. self.list[index].style.iconColor = [color];
  144. }
  145. self.$forceUpdate();
  146. })
  147. })
  148. },
  149. add(){
  150. var self = this;
  151. this.list.push({ imageUrl : '', title : '', link : {name: ''}, iconType: 'img', icon: '', style: {fontSize: 60, iconBgColor: [], iconBgColorDeg: 0,iconBgImg: '',bgRadius: 0,iconColor: ['#000'],iconColorDeg: 0}})
  152. this.colorRender('float-btn-color-' + (this.list.length - 1), '', function (elem, color) {
  153. var index = $(elem).parents('li').index();
  154. if (self.list[index].style.iconBgColor.length || self.list[index].style.iconBgImg) {
  155. self.list[index].style.iconBgColor = [color];
  156. } else {
  157. self.list[index].style.iconColor = [color];
  158. }
  159. self.$forceUpdate();
  160. })
  161. },
  162. del(index){
  163. this.list.splice(index, 1);
  164. delete this.colorPicker['float-btn-color-' + index];
  165. }
  166. },
  167. template: floatBtnListHtml
  168. });
  169. /**
  170. * 按钮位置
  171. */
  172. var btnPosition = '<div class="layui-form-item icon-radio">';
  173. btnPosition += '<label class="layui-form-label sm">{{data.label}}</label>';
  174. btnPosition += '<div class="layui-input-block">';
  175. btnPosition += '<template v-for="(item,index) in list">';
  176. btnPosition += '<span :class="[parent[data.field] == item.value ? \'\' : \'layui-hide\']">{{item.label}}</span>';
  177. btnPosition += '</template>';
  178. btnPosition += '<ul class="icon-wrap">';
  179. btnPosition += '<template v-for="(item,index) in list">';
  180. btnPosition += '<li @click="changePosition(item.value)" :class="{\'border-color\':parent[data.field] == item.value}">';
  181. btnPosition += '<i class="iconfont" :class="[item.icon_img,parent[data.field] == item.value ? \'text-color\' : \'\']"></i>';
  182. btnPosition += '</li>';
  183. btnPosition += '</template>';
  184. btnPosition += '</ul>';
  185. btnPosition += '</div>';
  186. btnPosition += '</div>';
  187. Vue.component("btn-position", {
  188. props: {
  189. data: {
  190. type: Object,
  191. default: function () {
  192. return {
  193. field: "bottomPosition",
  194. label: "按钮位置"
  195. };
  196. }
  197. }
  198. },
  199. data: function () {
  200. return {
  201. list: [
  202. {
  203. label: "左上",
  204. value: "1",
  205. icon_img: "iconzuoshangjiao",
  206. },
  207. {
  208. label: "右上",
  209. value: "2",
  210. icon_img: "iconyoushangjiao",
  211. },
  212. {
  213. label: "左下",
  214. value: "3",
  215. icon_img: "iconzuoxiajiao",
  216. },
  217. {
  218. label: "右下",
  219. value: "4",
  220. icon_img: "iconyouxiajiao",
  221. },
  222. ],
  223. parent: this.$parent.data,
  224. imageSize: this.$parent.data.imageSize,
  225. };
  226. },
  227. created: function () {
  228. $('.float-btn').parent('.draggable-element').css({"border": "none"});// 将边框进行隐藏掉
  229. },
  230. watch: {
  231. "$parent.data.imageSize": function () {
  232. getElementPosition(this.$parent);
  233. }
  234. },
  235. methods: {
  236. changePosition:function(val){
  237. this.parent.bottomPosition = val;
  238. getElementPosition(this.$parent)
  239. }
  240. },
  241. template: btnPosition
  242. });
  243. function getElementPosition(params) {
  244. var type = parseInt(params.data.bottomPosition), //布局类型,1为第一种,2为第二种依次类推
  245. bottomNumber = parseInt(params.data.btnBottom); //上下偏移的变量
  246. /**
  247. * #diyView .diy-view-wrap .preview-block =》 显示框【定位的参照对象是body】,#diyView =》 外边框【定位的参照对象是body】
  248. * 1、弹窗按钮是根据“外边框”进行定位的,但弹窗按钮是需要在“显示框”中展示
  249. * 2、弹窗按钮与显示框的上下间距定义为50px,左右为30px,这个是常量
  250. * 3、计算弹窗按钮的四个位置,都是根据 top,left进行计算的
  251. * */
  252. var box = document.querySelector("#diyView .diy-view-wrap .preview-block").getBoundingClientRect();
  253. var box1 = document.querySelector("#diyView").getBoundingClientRect();
  254. var topVal = 0; //弹窗按钮的top
  255. var leftVal = 0; //弹窗按钮的left
  256. var leftOffSet = 30; //弹窗按钮左右的偏移量
  257. if (type == 1) {
  258. // topVal = 显示框的top - 外边框的top + 距离显示框下边距的50px + 偏移量
  259. // leftVal = 显示框的left - 外边框的left + 距离显示框右边距的30px
  260. topVal = 100 + bottomNumber + "px";
  261. leftVal = box.left - box1.left + leftOffSet + "px";
  262. } else if (type == 2) {
  263. // topVal = 显示框的top - 外边框的top + 距离显示框下边距的50px + 偏移量
  264. // leftVal = 显示框的left - 外边框的left + 显示框的width(82) - 弹窗按钮的width - 距离显示框右边距的30px
  265. topVal = 100 + bottomNumber + "px";
  266. leftVal = box.left - box1.left + box.width - params.data.imageSize - 2 - leftOffSet + "px";
  267. } else if (type == 3) {
  268. // topVal = 显示框的top - 外边框的上边距(20) - 防止贴边(20) - 弹出按钮高度 - 弹出按钮的下外边距 - 偏移量
  269. // leftVal = 显示框的left - 外边框的left + 距离显示框左边距的30px
  270. // topVal = box.top - box1.top + box.height - 82 - topOff - bottomNumber + "px";
  271. topVal = $("#diyView .preview-wrap .div-wrap").height() - 20 - 20 - (params.data.list.length * params.data.imageSize) - ((params.data.list.length - 1) * 10) - bottomNumber + 'px';
  272. leftVal = box.left - box1.left + leftOffSet + "px";
  273. } else if (type == 4) {
  274. // topVal = 显示框的top - 外边框的上边距(20) - 防止贴边(20) - 弹出按钮高度 - 弹出按钮的下外边距 - 偏移量
  275. // leftVal = 显示框的left - 外边框的left + 显示框的width - 弹窗按钮的width - 边框width - 距离显示框右边距的30px
  276. topVal = $("#diyView .preview-wrap .div-wrap").height() - 20 - 20 - (params.data.list.length * params.data.imageSize) - ((params.data.list.length - 1) * 10) - bottomNumber + 'px';
  277. leftVal = box.left - box1.left + box.width - params.data.imageSize - 2 - leftOffSet + "px";
  278. }
  279. $(".draggable-element .float-btn").css({
  280. left: leftVal,
  281. top: topVal,
  282. 'z-index': 999
  283. });
  284. $(".draggable-element .float-btn .edit-attribute").css({
  285. position: 'fixed',
  286. right: '15px',
  287. top: Math.abs(box1.top)
  288. })
  289. }