1 完整代碼下載 https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ 提取碼 3fzt (壓縮包名: 2020-3-24-demo.zip) 2 圖片展示 3 主要代碼 布爾運算後的物體的幾何體會自動 導入到 幾何體列表選項中, 可自由選配材質 紋理 挺簡 ...
1 完整代碼下載
https://pan.baidu.com/s/1JJyVcP2KqXsd5G6eaYpgHQ
提取碼 3fzt (壓縮包名: 2020-3-24-demo.zip)
2 圖片展示
3 主要代碼
布爾運算後的物體的幾何體會自動 導入到 幾何體列表選項中, 可自由選配材質 紋理
挺簡單, 都是中文
1 "use strict" 2 3 var View = (function (){ 4 5 var _View = function (){ 6 7 if(this.__proto__.size === undefined){this.__proto__.size = this.getSize();} 8 9 } 10 11 _View.prototype = { 12 13 constructor: _View, 14 15 //創建html元素 16 add: function (fel, elemName, id, cls){ 17 let el = document.createElement(elemName); 18 if(id){el.setAttribute('id',id);} 19 if(cls){el.className = cls;} 20 if(fel){fel.appendChild(el);} 21 return el; 22 }, 23 24 //刪除html元素 25 remove: function (){ 26 let k, arg = arguments, err = []; 27 for(k = 0; k < arg.length; k++){ 28 if(this.isEl(arg[k]) === false){err.push(arg[k]); continue;} 29 arg[k].parentNode.removeChild(arg[k]); 30 } 31 if(err.length > 0){return {err:'這裡有一些刪除失敗的元素', arr:err};} 32 return true; 33 }, 34 35 //id獲取html元素 36 get: function (id){ 37 return document.getElementById(id); 38 }, 39 40 //獲取可視寬高 41 getSize: function (){ 42 let w = window.innerWidth || document.body.clientWidth || document.documentElement.clientWidth; 43 let h = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight; 44 return {w:w, h:h}; 45 }, 46 47 //通過parentNode檢查元素是否存在於頁面中 48 isEl: function (el){ 49 if(typeof(el) !== 'object'){return false;} 50 //被刪除之後的html元素object的 parentNode等於null 51 if(!el.parentNode){return false;} 52 return true; 53 }, 54 55 //元素綁定事件 56 addEvent: function (target, ev, callback){ 57 target.addEventListener(ev, function(e){/* e.preventDefault(); */ if(callback){callback(e);}}, false); 58 return callback; 59 }, 60 61 removeEvent: function (target, ev, func){ 62 target.removeEventListener(ev, func); 63 }, 64 65 initBody: function (){ 66 document.body.style.width = this.size.w + "px"; 67 document.body.style.height = this.size.h + "px"; 68 document.body.style.overflow = "hidden"; 69 return this; 70 } 71 72 } 73 74 return _View; 75 76 })() 77 78 79 80 /** 81 限 谷歌 或 火狐 瀏覽器 82 依賴 View 類 83 */ 84 var Gui = (function (){ 85 86 //申明新的gui 87 var _Gui = function (obj, a, b, c, d){ 88 this.timer = 0; 89 this.info = new Map(); 90 //this.info.set(this.timer, this); 91 if(this.__proto__.timerAll_old.length !== 0){ 92 this.timerAll = this.__proto__.timerAll_old[0]; 93 this.__proto__.timerAll_old.splice(0, 1); 94 }else{ 95 this.__proto__.timerAll++; 96 this.timerAll = this.__proto__.timerAll; 97 } 98 this.elem = addBindMove(document.body, 'div', null, 'Gui box-shadown box-scroll-block'); 99 this.__proto__.objAll.set(this.timerAll, this); 100 let dis = this.autoChangeStartPosition === false ? 1 : this.timerAll; 101 this.setPos(15 * dis, 5 * dis, "right"); 102 if(typeof(obj) === "object" && Array.isArray(obj) === false){this.create(obj, a, b, c, d);} 103 else{/* console.warn("_Gui: 參數中的對象 格式錯誤"); */} 104 } 105 106 _Gui.prototype.objAll = new Map(); 107 108 _Gui.prototype.timerAll = 0; 109 110 _Gui.prototype.timerAll_old = []; 111 112 _Gui.prototype.autoChangeStartPosition = true; //自動改變初始位置 113 114 //創建新的塊 115 _Gui.prototype.create = function (obj, a, b, c, d){ 116 this.timer++; 117 _start(obj, a, b, c, d, this.timer, this.elem, this.info, this.timerAll, this.objAll); 118 return this; 119 } 120 121 //往塊里添加新的控制項 122 _Gui.prototype.add = function (obj, a, b, c, d){ 123 _start(obj, a, b, c, d, this.timer, this.elem, this.info, this.timerAll, this.objAll); 124 return this; 125 } 126 127 //添加 內容變動 回調(change 事件) 128 _Gui.prototype.change = function (){//arr.concat(arr_a, arr_b) 129 var arg = arguments, o = this.info.get(this.timer), tar = o.par.target; 130 var arr = tar.bs.concat(tar.fs, tar.ns, tar.ss, tar.ts, tar.cs), len = arr.length; 131 var arg_t_0 = typeof(arg[0]), call = o.objs.get(o.obj).callback; 132 if(arg_t_0 === "function" && len === 1){ 133 call[arr[0]] = arg[0]; 134 }else if(arg_t_0 === "string" && typeof(arg[1]) === "function"){ 135 call[arg[0]] = arg[1]; 136 }else if(arg_t_0 === "function" && len > 1){ 137 for(let k = 0; k < len; k++){ 138 call[arr[k]] = arg[0]; 139 } 140 }else if(arg_t_0 === "object" && Array.isArray(arg[0]) === false){ 141 for(let k in arg[0]){ 142 call[k] = arg[0][k]; 143 } 144 }else{ 145 console.log("change方法參數錯誤,添加失敗"); 146 } 147 //console.log(this.info.get(this.timer).obj); 148 return this; 149 } 150 151 //修改title 152 _Gui.prototype.title = function (value){ 153 if(!this.info.get(this.timer)){console.log("找不到title"); return;} 154 this.info.get(this.timer).title.innerHTML = "<span class='timerAll'>"+this.timerAll+"</span>"+"."+"<span class='timer'>"+this.timer+"</span>"+" "+(value || ""); 155 return this; 156 } 157 158 //修改name 159 _Gui.prototype.name = function (){ 160 let o = this.info.get(this.timer), objs; 161 let arg = arguments, typ0 = typeof(arg[0]), typ1 = typeof(arg[1]); 162 if(typeof(arg[2]) === "object" && Array.isArray(arg[2]) === false){objs = o.objs.get(arg[2]);}else{objs = o.objs.get(o.obj);} 163 var tar = objs.parameter.target, nameEl = objs.nameEl; 164 var arr = tar.bs.concat(tar.fs, tar.ns, tar.ss, tar.ts, tar.cs), len = arr.length; 165 166 var setVal = (el, val)=>{if(el.value !== undefined){el.value = val;}else if(el.innerHTML !== undefined){el.innerHTML = val;}else{console.log("name修改失敗");}} 167 168 if(typ0 === "string" && typ1 === "undefined" && len === 1){//string 169 setVal(nameEl[arr[0]], arg[0]); 170 171 }else if(typ0 === "object" && Array.isArray(typ0) === false){//object 172 let k; 173 for(k in arg[0]){ 174 setVal(nameEl[k], arg[0][k]); 175 } 176 177 }else if(typ0 === "string" && typ1 === "string" && arg[1] !== "_Gui_func_showStop"){//string, string 178 if(arr.indexOf(arg[0]) === -1 || !nameEl[arg[0]]){console.log("name修改失敗,視圖結構發生錯誤,請修複"); return;} 179 setVal(nameEl[arg[0]], arg[1]); 180 181 }else if(typ0 === "string" && arg[1] === "_Gui_func_showStop" && typeof(arg[2]) === "object"){ 182 if(nameEl[arg[0]] === undefined){console.log("showStop_name: 錯誤"); return;} 183 if(arg[3] === false){ 184 nameEl[arg[0]].style.color = "#2F4F4F"; 185 }else{ 186 nameEl[arg[0]].style.color = "red"; 187 } 188 189 190 }else{ 191 console.log("name方法參數錯誤,添加失敗"); 192 } 193 194 return this; 195 } 196 197 //獲取當前view對象 198 _Gui.prototype.getView = function (){ 199 return tar; 200 } 201 202 //設置 gui視圖位置 203 _Gui.prototype.setPos = function (x, y, dirX, dirY){ 204 205 let dirx = dirX || "left", diry = dirY || "top"; 206 207 if(dirx === "left" && this.elem.bindMove.style.right !== ""){ 208 this.elem.bindMove.style.right = ""; 209 } 210 else if(dirx === "right" && this.elem.bindMove.style.left !== ""){ 211 this.elem.bindMove.style.left = ""; 212 } 213 214 if(diry === "top" && this.elem.bindMove.style.bottom !== ""){ 215 this.elem.bindMove.style.bottom = ""; 216 } 217 else if(diry === "bottom" && this.elem.bindMove.style.top !== ""){ 218 this.elem.bindMove.style.top = ""; 219 } 220 221 if(x !== undefined) this.elem.bindMove.style[dirx] = x+"px"; 222 if(y !== undefined) this.elem.bindMove.style[diry] = y+"px"; 223 _setElemPos(this.elem); 224 225 return this; 226 227 } 228 229 //隱藏gui 230 _Gui.prototype.display = function (val){ 231 if(!this.elem){console.log("display, elem不存在"); return this;} 232 if(val !== "block" && val !== "none"){console.log("display 參數錯誤"); return this;} 233 this.elem.bindMove.style.display = val; 234 this.elem.style.display = val; 235 return this; 236 } 237 238 //關閉gui timer number, 可選, 關閉那個 timer塊(預設關閉整個Gui) 239 _Gui.prototype.close = function (timer){ 240 if(timer === "auto"){ 241 242 return this; 243 } 244 var o = this.info.get(timer); 245 if(o === undefined){ 246 let k; 247 for(k = 1; k <= this.timer; k++){ 248 o = this.info.get(k); 249 o.hide = true; 250 hide(o.line, o.fel, this.elem, this.info, true); 251 } 252 }else{ 253 o.hide = true; 254 hide(o.line, o.fel, this.elem, this.info, true); 255 } 256 return this; 257 } 258 259 //標記不可用項 260 _Gui.prototype.showStop = function (){ 261 262 this.name(arguments[0], "_Gui_func_showStop", arguments[1], arguments[2]); 263 264 return this; 265 266 } 267 268 //移除gui 269 _Gui.prototype.remove = function(object){ 270 var o = object ? object : this; 271 this.__proto__.timerAll_old.push(o.timerAll); 272 this.__proto__.objAll.delete(o.timerAll); 273 o.objAll.delete(o.timerAll); 274 tar.remove(o.elem.bindMove, o.elem); 275 delete(o.timerAll); 276 delete(o.elem); 277 delete(o.info); 278 delete(o.timer); 279 return; 280 } 281 282 283 284 285 var tar = new View(), tar_zIndex = {}, _osTitle = null; 286 287 //創建視圖 288 var _start = function (obj, a, b, c, d, id, felem, map, timerAll, objAll){ 289 290 var fel, line, title, m = map.get(id), k, len, _name, isNewObj = false; 291 292 //確認追加 obj 293 if(m){ 294 fel = m.fel; 295 if(!obj){ 296 obj = m.obj; 297 }else{ 298 if(m.objs.has(obj) === false) isNewObj = true; 299 m.obj = obj; 300 } 301 } 302 303 if(typeof(obj) !== "object" || !obj){console.log("引用對象錯誤, 新建塊對象為必須"); return;} 304 305 //確認參數 (target, title, isBind, range || select) || a = {target, title, isBind, range || select} 306 var os = {}, nos = []; 307 if(a !== undefined){nos.push(_getispro(obj, a, nos));} 308 if(b !== undefined){nos.push(_getispro(obj, b, nos));} 309 if(c !== undefined){nos.push(_getispro(obj, c, nos));} 310 if(d !== undefined){nos.push(_getispro(obj, d, nos));} 311 len = nos.length; 312 for(k = 0; k < len; k++){ 313 if(nos[k] === undefined){ 314 if(typeof(a) === "object" && Array.isArray(a) === false){os = a;} 315 }else{ 316 let val; 317 switch(k){ 318 case 0 : val = a; break; 319 case 1 : val = b; break; 320 case 2 : val = c; break; 321 case 3 : val = d; break; 322 default : break; 323 } 324 if(val !== undefined){os[nos[k]] = val;} 325 } 326 } 327 328 //確認對象屬性 os.target (target 如果為obj 則表示 只設置gui, 不添加控制項) 329 var arr = [], T = typeof(os.target), A = Array.isArray(os.target); 330 if(!os.target){for(k in obj){arr.push(k);}} 331 else if(A === true){arr = os.target;} 332 else if(T !== "object"){arr.push(os.target);} 333 else{return;} 334 //boolean, function, number, text, select, color 335 var bs = [], fs = [], ns = [], ts = [], cs = [], ss = []; 336 if(Array.isArray(os.select) == true && arr.length === 1){ 337 ss.push(arr[0]); 338 }else if(typeof(os.select) === "object" && Array.isArray(os.select) == false){ 339 let ks; 340 for(ks in os.select){ 341 len = arr.length; 342 for(k = 0; k < len; k++){ 343 if(ks === arr[k]){ss.push(arr[k]); arr.splice(k, 1);} 344 } 345 } 346 } 347 len = arr.length; 348 for(k = 0; k < len; k++){ 349 T = typeof(obj[arr[k]]); 350 if(T === "boolean"){bs.push(arr[k]);} 351 else if(T === "function"){fs.push(arr[k]);} 352 else if(T === "number"){ns.push(arr[k]);} 353 else if(T === "string"){ 354 if(obj[arr[k]].length === 7 && obj[arr[k]].charAt(0) === "#"){cs.push(arr[k]);}//color 355 else{ts.push(arr[k]);}//string 356 } 357 } 358 var bs_len = bs.length, fs_len = fs.length, ns_len = ns.length, ts_len = ts.length, ss_len = ss.length, cs_len = cs.length; 359 var lens = bs_len + fs_len + ns_len + ts_len + ss_len + cs_len; 360 361 //確認 綁定 362 var isB = false; 363 if(typeof(os.isBind) === "boolean"){isB = os.isBind;} 364 365 //確認 _name 366 if(os.title && lens === 1){_name = os.title; delete(os.title);} 367 368 //確認 新的塊 369 var par = {target:{bs:bs, fs:fs, ns:ns, ts:ts, cs:cs, ss:ss}, select:os.select, range:os.range, title:os.title, isBind:os.isBind}; 370 if(!m){ 371 isNewObj = false; 372 line = _line(id, felem); 373 fel = _cons(line, id, felem, map); 374 title = _title(timerAll, id, _osTitle || os.title, fel);//os.title 375 _osTitle = null; 376 map.set(id, { 377 hide : false, 378 line : line, 379 fel : fel, 380 title : title, 381 obj : obj, 382 par : par, 383 objs : new Map([[obj, { 384 parameter : par, 385 callback : {}, 386 nameEl : {} 387 }]]) 388 }); 389 m = map.get(id); 390 } 391 392 //更新 obj 393 if(isNewObj === true){ 394 m.objs.set(obj, { 395 parameter : par, 396 callback : {}, 397 nameEl : {} 398 }); 399 } 400 401 //更新參數 402 m.par = par; 403 var objs_g = m.objs.get(obj), pars = objs_g.parameter; 404 for(k in os){if(k !== "target"){pars[k] = os[k];}} 405 for(k = 0; k < bs_len; k++){if(pars.target.bs.indexOf(bs[k]) === -1){pars.target.bs.push(bs[k]);}} 406 for(k = 0; k < fs_len; k++){if(pars.target.fs.indexOf(fs[k]) === -1){pars.target.fs.push(fs[k]);}} 407 for(k = 0; k < ns_len; k++){if(pars.target.ns.indexOf(ns[k]) === -1){pars.target.ns.push(ns[k]);}} 408 for(k = 0; k < ts_len; k++){if(pars.target.ts.indexOf(ts[k]) === -1){pars.target.ts.push(ts[k]);}} 409 for(k = 0; k < ss_len; k++){if(pars.target.ss.indexOf(ss[k]) === -1){pars.target.ss.push(ss[k]);}} 410 for(k = 0; k < cs_len; k++){if(pars.target.cs.indexOf(cs[k]) === -1){pars.target.cs.push(cs[k]);}} 411 412 //console.log(objs_g.callback); 413 //創建視圖//os.select os.range os.isBind 414 let che, cli, ran, tex, col, sel; 415 if(bs_len > 0){ che = _check(obj, bs, fel, isB, objs_g.callback, _name); for(k in che.nameEl){objs_g.nameEl[k] = che.nameEl[k];} } 416 if(ts_len > 0){ tex = _text(obj, ts, fel, isB, objs_g.callback, _name); for(k in tex.nameEl){objs_g.nameEl[k] = tex.nameEl[k];} } 417 if(cs_len > 0){ col = _color(obj, cs, fel, isB, objs_g.callback, _name); for(k in col.nameEl){objs_g.nameEl[k] = col.nameEl[k];} } 418 if(ss_len > 0){ sel = _select(obj, ss, os.select, fel, isB, objs_g.callback, _name); for(k in sel.nameEl){objs_g.nameEl[k] = sel.nameEl[k];} } 419 if(ns_len > 0){ ran = _range(obj, ns, os.range || {}, fel, isB, objs_g.callback, timerAll, id, _name); for(k in ran.nameEl){objs_g.nameEl[k] = ran.nameEl[k];} } 420 if(fs_len > 0){ cli = _click(obj, fs, fel, objs_g.callback, _name); for(k in cli.nameEl){objs_g.nameEl[k] = cli.nameEl[k];} } 421 return {nowObject:obj}; 422 } 423 424 //驗證 並 獲取 _start 參數 425 var _getispro = function (obj, cons, nos){ 426 var o_t = typeof(cons), o_a = Array.isArray(cons), r; 427 if(o_t === "string"){ 428 if(obj[cons] !== undefined){ 429 r = "target"; 430 }