Преглед на файлове

调整webgl页面样式&修改截图-丢弃顶部40px区域

zjs_project преди 1 година
родител
ревизия
2df26d7230

+ 6 - 6
src/components/newQCCom/viewShell/viewShell.html

@@ -12,16 +12,16 @@
 		{{pageType==1?'点击进入空间':'单击圆点切换视角'}}
 	</div> -->
 	<!-- 放大缩小操作区域 -->
-	<div class="zoom-view" @click.stop="zoomInOut">
+	<!-- <div class="zoom-view" @click.stop="zoomInOut">
 		<img class="icon" :src="styleType==2?'https://dm.static.elab-plus.com/miniProgram/iconfont/zoomin.png':'https://dm.static.elab-plus.com/miniProgram/iconfont/zoomout.png'" mode="widthFix"/>
-	</div>
+	</div> -->
 	<!-- 微信客服 -->
-	<div class="connect-view columns" v-if="connectUsImg"
+	<!-- <div class="connect-view columns" v-if="connectUsImg"
 		@click="mynavigateFuc" data-jumptype="50">
 		<img class="defaultHead" :src="connectUsImg" mode="widthFix"/>
-	</div>
-	<!-- 手势操作区域 -->
-	<div v-if="showSignscoll" class="shell-signscoll rows justify-center" @click="upScrollOrDown" @touchstart="mytouchstart" @touchmove="mytouchmove" @touchend="mytouchend">
+	</div> -->
+	<!-- 手势操作区域  @click="upScrollOrDown" @touchstart="mytouchstart" @touchmove="mytouchmove" @touchend="mytouchend" -->
+	<div v-if="showSignscoll" class="shell-signscoll rows justify-center">
 		<div class="signscoll-block"></div>
 	</div>
 	<!-- 精细化视图 -->

+ 1 - 1
src/components/newQCCom/viewShell/viewShell.vue

@@ -32,7 +32,7 @@
 				shellHeight:'200px',
 				isShare: false,
 				shareVideoItem:null,
-				styleType:1,	//当前底部组件的状态
+				styleType:2,	//当前底部组件的状态
 				seedItem:null,	//当前选中的种子户型
 				showSignscoll:true,	//是否显示手势操作区域
 				selectSpace:null,//用户选择的空间

+ 57 - 0
src/mixins/floorMethod.js

@@ -36,6 +36,63 @@ export default {
 				this.loaderGraseSpace(list);//加载草地的模型-所有地块都添加,填补房间里面的
 			}
 		},
+        //获取所有空间的中心点-水平面
+        getAllSpaceCenter(list){
+            if(!list || list.length==0){
+                return false;
+            }
+            let xmin = null;
+            let xmax = null;
+            let zmin = null;
+            let zmax = null;
+            list.forEach(obj=>{
+                let positionX = obj.centerX / 100;
+                let positionY = -obj.centerY / 100;
+                let width = obj.spaceWidth / 100;
+                let height = obj.spaceHeight / 100;
+                let x1 = positionX - width/2;//X 轴负方向
+                let x2 = positionX + width/2;//X 轴正方向
+                let z1 = positionY - height/2;//Z 轴负方向
+                let z2 = positionY + height/2;//Z 轴正方向
+                if(!xmax){
+                    xmax = x2;
+                }
+                if(!xmin){
+                    xmin = x1;
+                }
+                if(!zmax){
+                    zmax = z2;
+                }
+                if(!zmin){
+                    zmin = z1;
+                }
+                
+                if(x2 >= xmax){
+                    xmax = x2;
+                }
+                if(x1 <= xmin){
+                    xmin = x1;
+                }
+                if(z2 >= zmax){
+                    zmax = z2;
+                }
+                if(z1 <= zmin){
+                    zmin = z1;
+                }
+            })
+            let position = new THREE.Vector3();//当前几何体的位置参数
+            let positionX = (xmin + xmax)/2;
+            let positionY = (zmin + zmax)/2;
+            position.set(positionX, 0, positionY);
+            // const pointLight = new THREE.PointLight( 0xff0000, 1, 100 );
+            // pointLight.position.set(positionX, 0, positionY);
+            // this.scene.add( pointLight );
+            // const sphereSize = 1;
+            // const pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize );
+            // this.scene.add( pointLightHelper );
+            console.warn("***getAllSpaceCenter****",xmin,xmax,zmin,zmax);
+            return position;
+        },
 		loaderCommonSpace(gltfSpaceUrl,list,type=1){
 			var that = this;
 			this.loader.load(gltfSpaceUrl,  ( gltf ) => {

+ 6 - 0
src/pages/webgl_rxdz_test/webgl_rxdz_test.html

@@ -15,6 +15,10 @@
 			</div>
 		</div>
 	</div>
+    <!-- 定位视图 -->
+    <div class="location-view rows justify-center" @click.stop="locationHandle">
+        <span class="iconfont icon-pipei" style="color: #000;font-size: 44rpx;"></span>
+    </div>
     <div id="mapDiv" ref="webgl"></div>
 	<canvas id="glcanvas" width="100vw" height="100vh" ref="glcanvas"
 	 :style="{'height':canvasHeight+'px'}">
@@ -34,4 +38,6 @@
 	<!-- <div id="labels"></div> -->
 	<!-- 左侧操作区域 -->
 	<!-- <left-operate-comp @operateHandle="operateHandle"></left-operate-comp> -->
+    <!-- 生成截屏的画布对象 -->
+    <canvas id="canvas" type="2d" :style="{'height':'200px','top':'200px'}"></canvas>
 </div>

+ 10 - 0
src/pages/webgl_rxdz_test/webgl_rxdz_test.scss

@@ -54,6 +54,16 @@ canvas { width:100vw; height:calc(100vh - 200px);z-index: 10; }
 	position: absolute;
 	left:0px;
 }
+.location-view{
+    position: absolute;
+    top: 100px;
+    right: 20px;
+    width: 80px;
+    height: 80px;
+    border-radius: 24px;
+    background: radial-gradient(50.00% 50.00% at 50.00% 50.00%, #fff 0%, #f7f7f7 67.98%, #fff 100%);
+    border: 2px solid #d6d6d6;
+}
 .area-view{
 	position: absolute;
 	top:10px;

+ 72 - 13
src/pages/webgl_rxdz_test/webgl_rxdz_test.vue

@@ -85,6 +85,7 @@
 				curHouseObj: null,
 				controlStarPosition : { x:0, y:0, z:0},	//控制器初始位置
 				cameraStarPosition : { x:0, y:30, z:0}	,//摄像头初始位置
+                allSpaceCenter:null,//所有空间的中心点-水平面
 				// cameraLastPosition: null,		//摄像头上一次移动到的位置
 				// controlLastPosition: null,		//观察点上一次移动到的位置
 				canvasHeight:200,	//canvas视图的高度-计算得出
@@ -126,7 +127,7 @@
 				overChange:false,	//是否形变中
 				isIOS:false,	//是否ios手机。默认不是
 				currentChangeSpaceId:null,	//当前变化的空间id
-				styleType:1,
+				styleType:2,
 				sumArea:0,	//总面积
 				changeArea:0,	//当次变化的面积
 				fixedArea:0,	//初始面积值
@@ -202,8 +203,7 @@
 				screenHeight = Math.min(window.innerHeight,window.screen.height)
 			}
 			let unit = screenWidth / 750;//单位rpm 对应 px 的值
-			that.canvasHeight = screenHeight - (200 * unit) + (20 * unit);
-			
+			that.canvasHeight = screenHeight - (600 * unit) + (20 * unit);
 			const container = this.$refs.webgl;
             const canvas3d = this.canvas = this.$refs.glcanvas;
 			
@@ -232,10 +232,12 @@
 			this.tweenCameraAnmaChange = tweenCameraAnmaChange;
 			this.gradientResize = gradientResize;
 			this.moveMeshCenterHandle = moveMeshCenterHandle;
+            this.movePositionHandle = movePositionHandle;
 			this.starRender = starRender;//对外暴露启动渲染的方法
 			this.stopRender = stopRender;//对外暴露停止渲染的方法
 			this.cameraInit = cameraInit;
 			this.resetControl = resetControl;
+            this.setControlTarget = setControlTarget;
 			if(this.curHouseObj){
 				this.houseInit()
 			}
@@ -318,6 +320,7 @@
 				controls.maxPolarAngle = Math.PI / 2; // 默认Math.PI,即可以向下旋转到的视角。
 				controls.target.set(that.controlStarPosition.x, that.controlStarPosition.y, that.controlStarPosition.z);
 				controls.enableZoom = true;//启用摄像机的缩放
+				controls.enablePan  = false;//启用或禁用摄像机平移,默认为true
 				
 				// 监听相机移动事件-限制只能在当前空间范围内移动
 				// controls.addEventListener('change', () => {
@@ -342,6 +345,12 @@
             //初始状态
             function resetControl(){
             	controls.reset();
+            }
+            //设置控制器的焦点
+            function setControlTarget(target){
+                if(target.isVector3){
+                    controls.target = target;
+                }
             }
 			function onWindowResize() {
 			    camera.aspect = screenWidth / that.canvasHeight;
@@ -446,7 +455,31 @@
 					// updateLables();
 				},1001);//动画结束后回复原始状态
 			}
-			
+			//把摄像机移动到目标点位
+			function movePositionHandle(position = null, height=null){
+				let cameraNewPosition ={};
+				let targetNewPosition ={};
+				let oldUp = {};
+				let newUp = {};
+                let cy = height ? height : camera.position.y;
+				let _juli = cy * Math.tan(Math.PI / 8);
+				cameraNewPosition = {
+					x:position.x,
+					y:cy, 
+					z:position.z + _juli,//增加偏差,防止极点翻转问题?不知道为啥会有用
+				}
+				//新的观察点的位置-取模型的中心点坐标,加上高度,由于模型都是贴地的,所以高度设置为0
+				targetNewPosition = {
+					x:position.x,
+					y:position.y, 
+					z:position.z
+				}
+				oldUp = camera.up;//俯视状态
+				newUp = camera.up;
+				// console.warn("**movePositionHandle***",position,JSON.stringify(camera.position),JSON.stringify(controls.target)
+				// ,cameraNewPosition,targetNewPosition,JSON.stringify(camera.up))
+				tweenCamera(camera.position,controls.target,cameraNewPosition,targetNewPosition,oldUp,newUp,1000);
+			}
             // oldP  相机原来的位置
             // oldT  target原来的位置
             // newP  相机新的位置
@@ -455,9 +488,9 @@
 				if(JSON.stringify(oldP) == JSON.stringify(newP) && JSON.stringify(oldT) == JSON.stringify(newT)){
 					return false;
 				}
-				if (!chooseMesh) {
-					return false;
-				}
+				// if (!chooseMesh) {
+				// 	return false;
+				// }
 				tweenCameraAnma = true;
 				var tween = new TWEEN.Tween({
 					x1: oldP.x, // 相机x
@@ -512,7 +545,7 @@
 				// let _timeStep = 20;//单位 毫秒
 				// let unit = screenWidth / 750;//单位rpm 对应 px 的值
 				// that.canvasHeight = screenHeight - (200 * unit) + (20 * unit);
-				
+				return false;//不在执行变化
 				let unit = screenWidth / 750;//单位rpx 对应 px 的值
 				let _height = startHeight - endHeight;//高度变化-单位rpx
 				let _jisua = that.canvasHeight;
@@ -615,9 +648,27 @@
 				requestId = requestAnimationFrame(render, canvas3d);
 				renderer.render(scene, camera);//单次渲染
 				if (that.screenshotResolve) {
-					stopRender();
-					that.screenshotResolve()
-					that.screenshotResolve = null;//释放Promise
+					// stopRender();
+					// that.screenshotResolve()
+					// that.screenshotResolve = null;//释放Promise
+                    // 上述代码是全canvas截图,下述代码是canvas部分截图
+                    let gl = renderer.getContext();
+                    let pix = window.devicePixelRatio;
+                    let width = parseInt(screenWidth*pix);
+                    let height = parseInt((that.canvasHeight - 40)*pix);//丢弃上面高度为40px 的区域
+                    let pixelData = new Uint8Array(width * height * 4);
+                    if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) {
+                    	// gl.readPixels(0, 0, frameBuffer.x, frameBuffer.y, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
+                    	gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixelData);
+                    	// 确保有像素,微信小程序安卓在进入子页面返回本页面后,再一次readPixels稳定无像素
+                    	if (pixelData.some(i => i !== 0)) {
+                    		stopRender();
+                    		console.warn("***screenshotResolve-pixelData***");
+                    		that.screenshotResolve({pixelData, width, height})
+                    		that.screenshotResolve = null;//释放Promise
+                    		pixelData = null;//清空内存中的数据
+                    	}
+                    }
 				}
             }
 			
@@ -815,6 +866,9 @@
 				
 				this.changeSpaceColor(data.spaceId,1);//设置选中空间的颜色
 				this.moveMeshCenter(space);
+                // setTimeout(()=>{
+                //     this.setControlTarget(this.allSpaceCenter)
+                // },1100)
 			},
 			//具体空间面积变化-拖动产生的
 			//data = {
@@ -1681,6 +1735,9 @@
 					this.moveMeshCenterHandle(obj,type);
 				}
 			},
+            locationHandle(){
+                this.movePositionHandle(this.allSpaceCenter,this.cameraStarPosition.y);//把摄像机移动到所有模型的中心点(水平面中心)
+            },
             // 绘制地板
             async loadSpace(){
 				this.spaceList = [];
@@ -1715,6 +1772,7 @@
                         this.curSpaceObj = this.spaceList[0];
                     }
                 }
+                this.allSpaceCenter = this.getAllSpaceCenter(this.spaceList);//获取所有空间的中心点
                 console.log("该户型空间数据:", this.spaceList, this.layoutIds,type);
                 console.log("当前选中的空间:", this.curSpaceObj,this.curHouseObj);
 				this.spaceListBackup = JSON.parse(JSON.stringify(this.spaceList));
@@ -1814,13 +1872,14 @@
 				});
 				Promise.all(promise_list).then(()=>{
 					let endTime = new Date().getTime();
-					console.log("模型全部加载完成,时间:",endTime - startTime);
+					console.log("模型全部加载完成,时间:",endTime - startTime,this.allSpaceCenter);
 					this.progress = 100;
 					// this.$refs.myLoading.showLoading("加载中..." + this.progress + '%')
 					// 设置空间数组的墙体信息
 					// this.setSpaceListWallInfo();
 					this.$nextTick(()=>{
-						this.moveMeshCenter(this.curSpaceObj);
+                        this.movePositionHandle(this.allSpaceCenter);//把摄像机移动到所有模型的中心点(水平面中心)
+						// this.moveMeshCenter(this.curSpaceObj);
 						// this.myLoadingStatus = false;
 						// this.$refs.myLoading.hideLoading();
 						setTimeout(()=>{