使用three.js創建3D機房模型-分享一

来源:http://www.cnblogs.com/yeyunfei/archive/2016/12/17/6189661.html
-Advertisement-
Play Games

序:前段時間公司一次研討會上,一市場部同事展現了同行業其他公司的3D機房,我司領導覺得這個可以研究研究,為了節約成本,我們在網上大量檢索,最後找到一位前輩的博文【TWaver的技術博客】,在那篇博文的評論區終於找到了那位前輩的源碼,可惜下載後發現是壓縮過的.min.js文件。經過各種研究發現,那是人 ...


序:前段時間公司一次研討會上,一市場部同事展現了同行業其他公司的3D機房,我司領導覺得這個可以研究研究,為了節約成本,我們在網上大量檢索,最後找到一位前輩的博文【TWaver的技術博客】,在那篇博文的評論區終於找到了那位前輩的源碼,可惜下載後發現是壓縮過的.min.js文件。經過各種研究發現,那是人家公司自己賣錢的庫,不能完全共用,所以我司決定,派本人研究一下web3D的技術,於是乎便有了下麵的技術分享。

一、本著開源的思想,使用three.js框架,封裝常用的模型庫。先學著那位前輩的樣子,使用ThreeJS畫出類似的效果圖,只是稍微有點醜,看官莫怪。

特此申明:裡面的大部分模型貼圖都是使用的上述前輩的圖片

二、源碼

首先是各種庫的引入

<script src="../webglJS/jquery-2.2.2.js"></script>
<script src="../webglJS/three.min.js"></script>
<script src="../webglJS/stats.min.js"></script>
<script src="../webglJS/OrbitControls.js"></script>
<script src="../webglJS/ThreeBSP.js"></script>
<script src="../webglJS/Tween.js"></script>

上述幾個庫都是網上可以下載到的。

然後是封裝自己的模型庫,這是初始的模型庫,較為簡陋了 ,牛逼的庫都是不斷的迭代個幾百次的,不到的地方還望指正,互相學習共同進步

--這裡封裝一下 就叫做msj3D.js--

   1 /*
   2 作者:yeyunfei
   3 創建時間:2016-11-28
   4 版本:V16.11.01.bug
   5 功能描述:用戶創建web版組態
   6 
   7 使用方式
   8 var msjstation=new msj3D();
   9 msjstation.initmsj3D('divid',{...},[datajson]);
  10 msjstation.start();
  11 */
  12 function msj3D() { }
  13 var msj3DObj = null;
  14 msj3D.prototype.start = function () {
  15     //此處用於判斷瀏覽器
  16     
  17     //開始
  18     var _this = this;
  19     msj3DObj = _this;
  20     _this.initThree(_this.fId);
  21     _this.initCamera();
  22     _this.initScene();
  23     _this.initHelpGrid();
  24     _this.initLight();
  25     _this.addTestObj();
  26     //添加3D對象
  27     $.each(_this.objList, function (index,_obj) {
  28         _this.InitAddObject(_obj);
  29     });
  30     _this.initMouseCtrl();
  31     //創建按鈕
  32     _this.addBtns(_this.btns);
  33 
  34     _this.animation();
  35   
  36 }
  37 /*
  38 方法:初始化
  39 fid 畫布所屬div的Id
  40 option:參數 {
  41             antialias:true,//抗鋸齒效果為設置有效
  42             clearCoolr:0xFFFFFF,
  43             showHelpGrid:false,//是否顯示網格線
  44                 }
  45 */
  46 msj3D.prototype.initmsj3D = function (_fId, _option,_datajson) {
  47     //參數處理
  48     this.option = new Object();
  49     this.option.antialias = _option.antialias || true;//刷新色
  50     this.option.clearCoolr = _option.clearCoolr || 0x1b7ace;//刷新色
  51     this.option.showHelpGrid = _option.showHelpGrid || false;//刷新色
  52     //對象
  53     this.fId = _fId;
  54     this.width = $("#" + _fId).width();
  55     this.height = $("#" + _fId).height();
  56     this.renderer = null;//渲染器
  57     this.camera = null;//攝像機
  58     this.scene = null;//場景
  59     this.SELECTED=null;
  60     this.objects = [];
  61     this.mouseClick = new THREE.Vector2();
  62     this.raycaster = new THREE.Raycaster();
  63     this.controls = null;//滑鼠控制器
  64     this.objList = _datajson.objects;//對象列表
  65     this.eventList = _datajson.events;//事件對象列表
  66     this.btns = _datajson.btns;//按鈕列表
  67     var _this = this;
  68 }
  69 //初始化渲染器
  70 msj3D.prototype.initThree = function () {
  71     var _this = this;
  72     _this.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: _this.option.antialias });
  73     _this.renderer.setSize(_this.width, _this.height);
  74     $("#" + _this.fId).append(_this.renderer.domElement);
  75     _this.renderer.setClearColor(_this.option.clearCoolr, 1.0);
  76     _this.renderer.shadowMap.enabled = true;//
  77     _this.renderer.shadowMapSoft = true;
  78     //事件
  79     _this.renderer.domElement.addEventListener('mousedown', _this.onDocumentMouseDown, false);
  80     _this.renderer.domElement.addEventListener('mousemove', _this.onDocumentMouseMove, false);
  81 }
  82 //初始化攝像機
  83 msj3D.prototype.initCamera = function () {
  84     var _this = this;
  85     _this.camera = new THREE.PerspectiveCamera(45, _this.width / _this.height, 1, 100000);
  86     _this.camera.name = 'mainCamera';
  87     _this.camera.position.x =0;
  88     _this.camera.position.y =1000;
  89     _this.camera.position.z =-1800;
  90     _this.camera.up.x = 0;
  91     _this.camera.up.y =1;
  92     _this.camera.up.z =0;
  93     _this.camera.lookAt({ x: 0, y: 0, z: 0 });
  94     _this.objects.push(_this.camera);
  95 }
  96 //創建場景
  97 msj3D.prototype.initScene=function() {
  98     var _this = this;
  99     _this.scene = new THREE.Scene();
 100 }
 101 //添加對象
 102 msj3D.prototype.addObject = function (_obj) {
 103     var _this = msj3DObj;
 104     _this.objects.push(_obj);
 105     _this.scene.add(_obj);
 106 }
 107 //創建網格線
 108 msj3D.prototype.initHelpGrid = function () {
 109     var _this = this;
 110     if (_this.option.showHelpGrid) {
 111         var helpGrid = new THREE.GridHelper(1000, 50);
 112         _this.scene.add(helpGrid);
 113     }
 114 }
 115 //燈光佈置
 116 msj3D.prototype.initLight = function () {
 117     /*
 118     AmbientLight: 環境光,基礎光源,它的顏色會被載入到整個場景和所有對象的當前顏色上。
 119 PointLight:點光源,朝著所有方向都發射光線
 120 SpotLight :聚光燈光源:類型臺燈,天花板上的吊燈,手電筒筒等
 121 DirectionalLight:方向光,又稱無限光,從這個發出的光源可以看做是平行光.
 122     */
 123     var _this = this;
 124     var light = new THREE.AmbientLight(0xcccccc);
 125     light.position.set(0, 0,0);
 126     _this.scene.add(light);
 127     var light2 = new THREE.PointLight(0x555555);
 128     light2.shadow.camera.near =1;
 129     light2.shadow.camera.far = 5000;
 130     light2.position.set(0, 350, 0);
 131     light2.castShadow = true;//表示這個光是可以產生陰影的
 132     _this.scene.add(light2);
 133 
 134 }
 135 //創建滑鼠控制器
 136 msj3D.prototype.initMouseCtrl=function() {
 137     var _this = this;
 138     _this.controls = new THREE.OrbitControls(_this.camera);
 139     _this.controls.addEventListener('change', _this.updateControls);
 140 }
 141 //控制器回調
 142 msj3D.prototype.updateControls = function () {
 143     
 144    //controls.update();
 145 }
 146 //迴圈渲染界面
 147 msj3D.prototype.animation = function () {
 148     var _this = msj3DObj;
 149     if (TWEEN != null && typeof (TWEEN) != 'undefined') {
 150         TWEEN.update();
 151     }
 152     requestAnimationFrame(_this.animation);
 153     _this.renderer.render(_this.scene, _this.camera);
 154 }
 155 
 156 /*
 157 添加對象
 158 */
 159 msj3D.prototype.InitAddObject = function (_obj) {
 160     var _this = this;
 161     if (_obj.show == null || typeof (_obj.show) == 'undefined' || _obj.show) {
 162         var _tempObj = null;
 163         switch (_obj.objType) {
 164             case 'cube':
 165                 _tempObj = _this.createCube(_this, _obj);
 166                 _this.addObject(_tempObj);
 167                 break;
 168             case 'floor':
 169                 _tempObj = _this.CreateFloor(_obj)
 170                 _this.addObject(_tempObj);
 171                 break;
 172             case 'wall':
 173                 _this.CreateWall(_this,_obj);
 174                 break;
 175             case 'plane':
 176                 _tempObj = _this.createPlaneGeometry(_this, _obj);
 177                 _this.addObject(_tempObj);
 178                 break;
 179             case 'glasses':
 180                 _this.createGlasses(_this, _obj);
 181                 break;
 182             case 'emptyCabinet':
 183                 _tempObj = _this.createEmptyCabinet(_this, _obj);
 184                 _this.addObject(_tempObj);
 185                 break;
 186             case 'cloneObj':
 187                 _tempObj = _this.commonFunc.cloneObj(_obj.copyfrom, _obj);
 188                 _this.addObject(_tempObj);
 189                 break;
 190         }
 191     }
 192 }
 193 
 194 //創建地板
 195 msj3D.prototype.CreateFloor = function (_obj) {
 196     var _this = this;
 197     var _cube = _this.createCube(_this, _obj);
 198     return _cube;
 199 }
 200 //創建牆體
 201 msj3D.prototype.CreateWall = function (_this, _obj) {
 202     if (_this == null) {
 203          _this = this;
 204     }
 205     var _commonThick = _obj.thick || 40;//牆體厚度
 206     var _commonLength = _obj.length || 100;//牆體厚度
 207     var _commonHeight = _obj.height || 300;//強體高度
 208     var _commonSkin = _obj.style.skinColor || 0x98750f;
 209     //建立牆面
 210     $.each(_obj.wallData, function (index, wallobj) {
 211         var wallLength = _commonLength;
 212         var wallWidth = wallobj.thick||_commonThick;
 213         var positionX = ((wallobj.startDot.x||0) + (wallobj.endDot.x||0)) / 2;
 214         var positionY = ((wallobj.startDot.y || 0) + (wallobj.endDot.y || 0)) / 2;
 215         var positionZ = ((wallobj.startDot.z || 0) + (wallobj.endDot.z || 0)) / 2;
 216         //z相同 表示x方向為長度
 217         if (wallobj.startDot.z == wallobj.endDot.z) {
 218             wallLength = Math.abs(wallobj.startDot.x - wallobj.endDot.x);
 219             wallWidth = wallobj.thick || _commonThick;
 220         } else if (wallobj.startDot.x == wallobj.endDot.x) {
 221             wallLength = wallobj.thick || _commonThick;
 222             wallWidth = Math.abs(wallobj.startDot.z - wallobj.endDot.z);
 223         }
 224         var cubeobj = {
 225             length: wallLength,
 226             width: wallWidth,
 227             height: wallobj.height || _commonHeight,
 228             rotation: wallobj.rotation,
 229             x: positionX,
 230             y: positionY,
 231             z: positionZ,
 232             uuid: wallobj.uuid,
 233             name:wallobj.name,
 234             style: {
 235                 skinColor: _commonSkin,
 236                 skin:wallobj.skin 
 237             }
 238         }
 239         var _cube = _this.createCube(_this, cubeobj);
 240         if (_this.commonFunc.hasObj(wallobj.childrens) && wallobj.childrens.length > 0) {
 241             $.each(wallobj.childrens, function (index, walchildobj) {
 242                 var _newobj = null;
 243                 _newobj = _this.CreateHole(_this, walchildobj);
 244                 _cube = _this.mergeModel(_this, walchildobj.op, _cube, _newobj);
 245             });
 246         }
 247         _this.addObject(_cube);
 248     });
 249 }
 250 //挖洞
 251 msj3D.prototype.CreateHole = function (_this, _obj) {
 252     if (_this == null) {
 253         _this = this;
 254     }
 255     var _commonThick =  40;//牆體厚度
 256     var _commonLength =  100;//牆體厚度
 257     var _commonHeight =  300;//強體高度
 258     var _commonSkin = 0x98750f;
 259     //建立牆面
 260         var wallLength = _commonLength;
 261         var wallWidth = _obj.thick || _commonThick;
 262         var positionX = ((_obj.startDot.x || 0) + (_obj.endDot.x || 0)) / 2;
 263         var positionY = ((_obj.startDot.y || 0) + (_obj.endDot.y || 0)) / 2;
 264         var positionZ = ((_obj.startDot.z || 0) + (_obj.endDot.z || 0)) / 2;
 265         //z相同 表示x方向為長度
 266         if (_obj.startDot.z == _obj.endDot.z) {
 267             wallLength = Math.abs(_obj.startDot.x - _obj.endDot.x);
 268             wallWidth = _obj.thick || _commonThick;
 269         } else if (_obj.startDot.x == _obj.endDot.x) {
 270             wallLength = _obj.thick || _commonThick;
 271             wallWidth = Math.abs(_obj.startDot.z - _obj.endDot.z);
 272         }
 273         var cubeobj = {
 274             length: wallLength,
 275             width: wallWidth,
 276             height: _obj.height || _commonHeight,
 277             rotation: _obj.rotation,
 278             x: positionX,
 279             uuid: _obj.uuid,
 280             name: _obj.name,
 281             y: positionY,
 282             z: positionZ,
 283             style: {
 284                 skinColor: _commonSkin,
 285                 skin: _obj.skin
 286             }
 287         }
 288         var _cube = _this.createCube(_this, cubeobj);
 289         return _cube;
 290 }
 291 //模型合併 使用ThreeBSP插件mergeOP計算方式 -表示減去 +表示加上 
 292 msj3D.prototype.mergeModel = function (_this, mergeOP, _fobj, _sobj) {
 293     if (_this == null) {
 294         _this = this;
 295     }
 296     var fobjBSP = new ThreeBSP(_fobj);
 297     var sobjBSP = new ThreeBSP(_sobj);
 298    // var sobjBSP = new ThreeBSP(_sobj);
 299     var resultBSP = null; 
 300     if (mergeOP == '-') {
 301         resultBSP = fobjBSP.subtract(sobjBSP);
 302     } else if (mergeOP == '+') {
 303         var subMesh = new THREE.Mesh(_sobj);
 304         _sobj.updateMatrix();
 305         _fobj.geometry.merge(_sobj.geometry, _sobj.matrix);
 306         return _fobj;
 307        // resultBSP = fobjBSP.union(sobjBSP);
 308     } else if (mergeOP == '&') {//交集
 309         resultBSP = fobjBSP.intersect(sobjBSP);
 310     } else {
 311         _this.addObject(_sobj);
 312         return _fobj;
 313     }
 314     var cubeMaterialArray = [];
 315     for (var i = 0; i < 1; i++) {
 316         cubeMaterialArray.push(new THREE.MeshLambertMaterial({
 317             //map: _this.createSkin(128, 128, { imgurl: '../datacenterdemo/res2/'+(i%11)+'.jpg' }),
 318             vertexColors: THREE.FaceColors
 319         }));
 320     }
 321     var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray);
 322     var result = resultBSP.toMesh(cubeMaterials);
 323     result.material.shading = THREE.FlatShading;
 324     result.geometry.computeFaceNormals();
 325     result.geometry.computeVertexNormals();
 326     result.uuid= _fobj.uuid+mergeOP+_sobj.uuid;
 327     result.name=_fobj.name+mergeOP+_sobj.name;
 328     result.material.needsUpdate = true;
 329     result.geometry.buffersNeedUpdate = true;
 330     result.geometry.uvsNeedUpdate = true;
 331     var _foreFaceSkin = null;
 332     for (var i = 0; i < result.geometry.faces.length; i++) {
 333         var _faceset = false;
 334         for (var j = 0; j < _fobj.geometry.faces.length; j++) {
 335             if (result.geometry.faces[i].vertexNormals[0].x === _fobj.geometry.faces[j].vertexNormals[0].x
 336                 && result.geometry.faces[i].vertexNormals[0].y === _fobj.geometry.faces[j].vertexNormals[0].y
 337                 && result.geometry.faces[i].vertexNormals[0].z === _fobj.geometry.faces[j].vertexNormals[0].z
 338                  && result.geometry.faces[i].vertexNormals[1].x === _fobj.geometry.faces[j].vertexNormals[1].x
 339                 && result.geometry.faces[i].vertexNormals[1].y === _fobj.geometry.faces[j].vertexNormals[1].y
 340                 && result.geometry.faces[i].vertexNormals[1].z === _fobj.geometry.faces[j].vertexNormals[1].z
 341                 && result.geometry.faces[i].vertexNormals[2].x === _fobj.geometry.faces[j].vertexNormals[2].x
 342                 && result.geometry.faces[i].vertexNormals[2].y === _fobj.geometry.faces[j].vertexNormals[2].y
 343                 && result.geometry.faces[i].vertexNormals[2].z === _fobj.geometry.faces[j].vertexNormals[2].z) {
 344                 result.geometry.faces[i].color.setHex(_fobj.geometry.faces[j].color.r * 0xff0000 + _fobj.geometry.faces[j].color.g * 0x00ff00 + _fobj.geometry.faces[j].color.b * 0x0000ff);
 345                 _foreFaceSkin = _fobj.geometry.faces[j].color.r * 0xff0000 + _fobj.geometry.faces[j].color.g * 0x00ff00 + _fobj.geometry.faces[j].color.b * 0x0000ff;
 346                 _faceset =true;
 347             }
 348         }
 349         if (_faceset == false){
 350             for(var j = 0; j < _sobj.geometry.faces.length; j++) {
 351                 if (result.geometry.faces[i].vertexNormals[0].x === _sobj.geometry.faces[j].vertexNormals[0].x
 352                     && result.geometry.faces[i].vertexNormals[0].y === _sobj.geometry.faces[j].vertexNormals[0].y
 353                     && result.geometry.faces[i].vertexNormals[0].z === _sobj.geometry.faces[j].vertexNormals[0].z
 354                      && result.geometry.faces[i].vertexNormals[1].x === _sobj.geometry.faces[j].vertexNormals[1].x
 355                     && result.geometry.faces[i].vertexNormals[1].y === _sobj.geometry.faces[j].vertexNormals[1].y
 356                     && result.geometry.faces[i].vertexNormals[1].z === _sobj.geometry.faces[j].vertexNormals[1].z
 357                     && result.geometry.faces[i].vertexNormals[2].x === _sobj.geometry.faces[j].vertexNormals[2].x
 358                     && result.geometry.faces[i].vertexNormals[2].y === _sobj.geometry.faces[j].vertexNormals[2].y
 359                     && result.geometry.faces[i].vertexNormals[2].z === _sobj.geometry.faces[j].vertexNormals[2].z
 360                     && result.geometry.faces[i].vertexNormals[2].z === _sobj.geometry.faces[j].vertexNormals[2].z) {
 361                     result.geometry.faces[i].color.setHex(_sobj.geometry.faces[j].color.r * 0xff0000 + _sobj.geometry.faces[j].color.g * 0x00ff00 + _sobj.geometry.faces[j].color.b * 0x0000ff);
 362                     _foreFaceSkin = _sobj.geometry.faces[j].color.r * 0xff0000 + _sobj.geometry.faces[j].color.g * 0x00ff00 + _sobj.geometry.faces[j].color.b * 0x0000ff;
 363                     _faceset = true;
 364                 }
 365             }
 366         }
 367         if (_faceset == false) {
 368             result.geometry.faces[i].color.setHex(_foreFaceSkin);
 369         }
 370     // result.geometry.faces[i].materialIndex = i
 371     }
 372     result.castShadow = true;
 373     result.receiveShadow = true;
 374     return result;
 375 }
 376 //創建盒子體
 377 msj3D.prototype.createCube = function (_this, _obj) {
 378     if (_this == null) {
 379         _this = this;
 380     }
 381     var _length = _obj.length || 1000;//預設1000
 382     var _width = _obj.width || _length;
 383     var _height = _obj.height || 10;
 384     var _x = _obj.x || 0, _y = _obj.y || 0, _z = _obj.z || 0;
 385     var skinColor = _obj.style.skinColor || 0x98750f;
 386     var cubeGeometry = new THREE.CubeGeometry(_length, _height, _width, 0, 0, 1);
 387 
 388     //六面顏色
 389     for (var i = 0; i < cubeGeometry.faces.length; i += 2) {
 390         var hex = skinColor || Math.random() * 0x531844;
 391         cubeGeometry.faces[i].color.setHex(hex);
 392         cubeGeometry.faces[i + 1].color.setHex(hex);
 393     }
 394     //六面紋理
 395     var skin_up_obj = {
 396         vertexColors: THREE.FaceColors
 397     }
 398     var skin_down_obj = skin_up_obj,
 399         skin_fore_obj = skin_up_obj,
 400         skin_behind_obj = skin_up_obj,
 401         skin_left_obj = skin_up_obj,
 402         skin_right_obj = skin_up_obj;
 403     var skin_opacity = 1;
 404     if (_obj.style != null && typeof (_obj.style) != 'undefined'
 405         && _obj.style.skin != null && typeof (_obj.style.skin) != 'undefined') {
 406         //透明度
 407         if (_obj.style.skin.opacity != null && typeof (_obj.style.skin.opacity) != 'undefined') {
 408             skin_opacity = _obj.style.skin.opacity;
 409             console.log(skin_opacity)
 410         }
 411         //
 412         skin_up_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_up, cubeGeometry, 4);
 413         //
 414         skin_down_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_down, cubeGeometry, 6);
 415         //
 416         skin_fore_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_fore, cubeGeometry, 0);
 417         //
 418         skin_behind_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_behind, cubeGeometry, 2);
 419         //
 420         skin_left_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_left, cubeGeometry, 8);
 421         //
 422         skin_right_obj = _this.createSkinOptionOnj(_this, _length, _width, _obj.style.skin.skin_right, cubeGeometry, 10);
 423     }
 424     var cubeMaterialArray = [];
 425     cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_fore_obj));
 426     cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_behind_obj));
 427     cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_up_obj));
 428     cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_down_obj));
 429     cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_right_obj));
 430     cubeMaterialArray.push(new THREE.MeshLambertMaterial(skin_left_obj));
 431     var cubeMaterials = new THREE.MeshFaceMaterial(cubeMaterialArray);
 432     cube = new THREE.Mesh(cubeGeometry, cubeMaterials);
 433     cube.castShadow = true;
 434     cube.receiveShadow = true;
 435     cube.uuid = _obj.uuid;
 436     cube.name = _obj.name;
 437     cube.position.set(_x, _y, _z);
 438     if (_obj.rotation != null && typeof (_obj.rotation) != 'undefined' && _obj.rotation.length > 0) {
 439         $.each(_obj.rotation, function (index, rotation_obj) {
 440             switch (rotation_obj.direction) {
 441                 case 'x':
 442                     cube.rotateX(rotation_obj.degree);
 443                     break;
 444                 case 'y':
 445                     cube.rotateY(rotation_obj.degree);
 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.功能 解決javascript回調地獄 安裝eventProxy 2.常用方法 ①解決回調方法 emit:觸發事件 after all:告訴它你要監聽哪些事件,並給它一個回調函數。ep.all('event1', 'event2', function (result1, result2) {}) ...
  • Javascript中有'=='和' '兩種相等比較,後者是全等,會判斷數據類型,前者是相等,在比較時,會發生隱式轉換。 如果將兩個對象做'=='比較,結果會如何呢? 比如有如下兩個對象: 可以看到,哪怕兩個對象的屬性完全一樣,無論是'=='或者' ',返回都是false。 原因:對象通過指針指向的 ...
  • 1.map 2.remove 移除數組 array 中滿足 predicate 條件的所有元素 ,返回的是被移除元素數組. 3.uniq 唯一 ...
  • 1.find 2.findIndex _.findIndex(array, [predicate=_.identity], [thisArg])該方法類似 _.find,區別是該方法返回的是符合 predicate條件的第一個元素的索引,而不是返回元素本身. 參數 predicate 提供的是一個屬 ...
  • scroll事件實現監控滾動條並分頁顯示示例(zepto.js ) 需求:在APP落地頁上的底部位置顯示此前其他用戶的購買記錄,要求此div盒子只顯示3條半,但一頁有10條,div內的滑動條滑到一頁底部自動載入下一頁併發載入埋點。 實現:首先理解三個概念,分別是contentH,viewH,scro ...
  • 本篇文章是講解了一個demo實例,就是怎樣獲取類的結構,以及應該註意的事項,若有什麼建議或意見歡迎前來打擾。 ...
  • 除了可以為元素添加樣式外,還可用來查詢元素,某樣式值alert($('.cls1').css('width')); //100px(返回帶單位的值)註意:原生CSS樣式中有-的去掉並且將後面的單詞第一個字母大寫 alert($('.box').width( )); alert($('.box').h ...
  • 直接進入主題! 一、脫離文檔流元素的居中 方法一:margin:auto法 CSS代碼: HTML代碼: 效果圖: 當一個元素絕對定位時,它會根據第一個不是static定位的祖先元素定位,因此這裡的img根據外層div定位。 方法二:負margin法 CSS代碼: HTML代碼: 效果圖: 這裡,我 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...