Kaynağa Gözat

fix: 标尺加完了

xzw 1 yıl önce
ebeveyn
işleme
dccdc29e45

+ 87 - 18
src/custom/modules/clipModel/Clip.js

@@ -540,10 +540,48 @@ var Clip = {
     },
     
     
-    screenshot: async ()=>{ //测绘图下载。顶视图|侧视图
+    
+    
+    getRulerBound(){//坐标尺边界
+        let camera = viewer.mainViewport.camera
+        if(!camera.isOrthographicCamera)return
+        let w = camera.right / camera.zoom //half
+        let h = camera.top / camera.zoom
+        
+       
+        let points = []
+        var boundAtCamera = new THREE.Box3() 
+        Clip.box.children[0].geometry.vertices.forEach(e=>{ //模仿getPosWithFullBound
+            let p = e.clone().applyMatrix4(Clip.box.matrixWorld)
+            points.push(p)
+            let p1 = p.clone().applyMatrix4(camera.matrixWorldInverse);
+            boundAtCamera.expandByPoint(p1)
+        }) 
+        //需要找出clipbox的bound的左上角,它在标尺中是原点
+        let ClipBoxLeftTop = new THREE.Vector2(boundAtCamera.min.x, boundAtCamera.max.y) //相对于相机的位置
+        let camPos = new THREE.Vector2(-ClipBoxLeftTop.x, ClipBoxLeftTop.y)//由于ClipBoxLeftTop要变换到原点,所以相机位置就成了ClipBoxLeftTop的相反数, 但因是从上到下所以y再乘-1
+         
+         
+         
+        let bound_ = {
+            left: camPos.x - w,
+            right: camPos.x + w,
+            bottom: camPos.y + h,       //注意从上到下增大
+            top: camPos.y - h,
+        }
+        //console.log(bound)
+
+        return bound_ 
+    },
+    
+    
+    
+    screenshot: async (rulerBound, rulerMargin )=>{ //测绘图下载。顶视图|侧视图
         return new Promise((resolve,reject)=>{ 
             if(Clip.screenshoting )return reject()
              
+            
+         
             let visiPointclouds = viewer.scene.pointclouds.filter(e=> Potree.Utils.getObjVisiByReason(e, 'datasetSelection'))
             let camera = viewer.mainViewport.camera
             //if(Clip.activeViewName == 'mainView')return reject()
@@ -628,11 +666,17 @@ var Clip = {
             
             console.log({wc,hc,w,h})
             
+            let meterPerPixel = boundSize.x / w
+            let text = `1 : ${(meterPerPixel).toFixed(4)}(像素 : 米)`
             
-            let text = `1 : ${(boundSize.x / w).toFixed(4)}(像素 : 米)`
-            
+            let beforeScreenshot = ()=>{
+                if(rulerBound){
+                    let ruler = Clip.getRulerBound()
+                    Object.assign(rulerBound,ruler)
+                }
+            } 
             
-            let {getImagePromise, finishPromise} = viewer.startScreenshot({ type: 'default', bgOpacity:0, focusObjectInfo, maxTimeForPointLoad : 3e5, pointDensity:'screenshot2', splitRenderInfo }, w, h, 1 )
+            let {getImagePromise, finishPromise} = viewer.startScreenshot({ type: 'default', bgOpacity:0,   focusObjectInfo, maxTimeForPointLoad : 3e5, pointDensity:'screenshot2', splitRenderInfo, beforeScreenshot }, w, h, 1 )
             finishPromise.done(({dataUrl}) => {
                  
                 viewer.inputHandler.toggleSelection(Clip.box);
@@ -643,28 +687,53 @@ var Clip = {
                 img.onload = async ()=>{//加上标尺比例水印
                 
                     //固定文字大小和边距像素    //如果有一边过小,可能超出画面外,暂时不管这种可能
-                    const Margin = 30
-                    let topRatioToImg = THREE.Math.clamp(  Margin / h  , 0.006,0.10) //clamp:当图片过大时,label间距像素放大一点,反之缩小一点
-                    let leftRatioToImg = THREE.Math.clamp(  Margin / w  , 0.006,0.05)  
-                
-                    let labelInfo = {
-                        topRatioToImg, leftRatioToImg,  
-                        textColor: { r: 255, g: 255, b: 255, a: 1 }, 
-                        textBorderColor : { r: 30, g: 30, b: 30, a: 1 },
-                        textBorderThick :  1,
-                        fontsize: math.linearClamp(w, [100, 700, 4096, 8192], [12, 20, 30, 40])
+                    const fontsize = math.linearClamp(w, [100, 700, 8000], [12, 20, 30])
+                    
+                    const marginSelf = {//img外的margin(标尺内)
+                        left :  rulerBound ? 76 : 40,
+                        right :  rulerBound ? 30 : 40,
+                        bottom :  rulerBound ? 20 + fontsize*2 : 40 + fontsize*2,
+                        top :  rulerBound ? 60 : 40,
                     }
+                    //const Margin = rulerMargin + marginSelf
                     
-                    let m = leftRatioToImg * w
-                    labelInfo.bgMargin = {left:m ,  top : topRatioToImg * h * 2 + labelInfo.fontsize,  right: m,  bottom:m } 
                     
+                    //文字的边距
+                    let bottomRatioToImg = - Math.min(fontsize*2.5,   rulerBound ? marginSelf.bottom : marginSelf.bottom*0.9 ) / h//- (marginSelf.bottom - fontsize)/ h  //在img之下. text底部到img底部的距离
+                    //let leftRatioToImg = Margin / w  
                     
+                     
+                    let labelInfo = {
+                        bottomRatioToImg, horizonCenter:true,//leftRatioToImg,  
+                        textColor: rulerBound ? {r: 0, g: 0, b: 0, a: 1} : { r: 255, g: 255, b: 255, a: 1 }, 
+                        textBorderColor : { r: 30, g: 30, b: 30, a: 1 },
+                        textBorderThick : rulerBound ? 0 : 1 ,
+                        fontsize,
+                        fontWeight: rulerBound ? 'normal':'Bold',
+                        outputCanvas : !!rulerBound,
+                        bgColor: rulerBound ? {r:255,g:255,b:255,a:255}:null
+                    }
+                     
+                    labelInfo.bgMargin = {//img外需要多少margin
+                        left: marginSelf.left + rulerMargin,  //rulerMargin是在标尺外的margin
+                        bottom : marginSelf.bottom  + rulerMargin,  
+                        right: marginSelf.right + rulerMargin,  
+                        top: marginSelf.top + rulerMargin
+                    } 
+                    
+                    if(rulerBound){//因为margin 扩大bound 
+                        rulerBound.left -= marginSelf.left * meterPerPixel
+                        rulerBound.right += marginSelf.right * meterPerPixel 
+                        rulerBound.top -= marginSelf.top * meterPerPixel 
+                        rulerBound.bottom += marginSelf.bottom * meterPerPixel 
+                    }
                     
                     //console.log('topRatioToImg',topRatioToImg,'leftRatioToImg',leftRatioToImg,'fontsize', labelInfo.fontsize)
                     
                     
                  
-                    let finalDataUrl = await Potree.Utils.imgAddText(img, text , labelInfo )
+                    let result = await Potree.Utils.imgAddText(img, text , labelInfo )
+                    
                     
                     //Common.downloadFile(finalDataUrl, 'screenshot11.png') 
                      
@@ -672,7 +741,7 @@ var Clip = {
                     Clip.screenshoting = false
                     viewer.viewports = [viewer.mainViewport]
                     
-                    resolve(finalDataUrl) 
+                    resolve(result) 
                 }
                 
                 

+ 5 - 2
src/custom/potree.shim.js

@@ -927,9 +927,12 @@ Utils.imgAddText = async (img, text, labelInfo)=>{
     
     return new Promise((resolve,reject)=>{ 
         labelImg.onload = ()=>{
-            let src = Common.imgAddLabel(img,labelImg,labelInfo)
+            if(labelInfo.horizonCenter){//水平居中(对img来说)  
+                labelInfo.leftRatioToImg = 0.5 - (labelImg.width / img.width)/2
+            }  
+            let result = Common.imgAddLabel(img,labelImg,labelInfo)
             label.dispose()
-            resolve(src) 
+            resolve(result) 
         }  
     }) 
      

+ 27 - 15
src/custom/utils/Common.js

@@ -480,41 +480,53 @@ var Common = {
       
     imgAddLabel : function (img, labelImg, labelInfo = {}) {
         //图上加另一张小图,用于添加水印
-
-        let canvas = document.createElement('canvas')
+        let canvas
+        if(img instanceof Image){
+            canvas = document.createElement('canvas')
+        }else{
+            canvas = img
+        }
+          
         let context = canvas.getContext('2d')
         let marginLeft = labelInfo.bgMargin && labelInfo.bgMargin.left || 0 
         let marginRight = labelInfo.bgMargin && labelInfo.bgMargin.right || 0 
         let marginTop = labelInfo.bgMargin && labelInfo.bgMargin.top || 0 
         let marginBottom = labelInfo.bgMargin && labelInfo.bgMargin.bottom || 0 
         
-        
-        let width = img.width + marginLeft + marginRight
-        let height = img.height + marginTop + marginBottom
-        context.canvas.width = width
-        context.canvas.height = height
-        context.drawImage(img, marginLeft, marginTop, img.width, img.height)
-
+        if(img instanceof Image){//如果img是canvas,说明已绘制在canvas上了就不用绘制了
+            let width = img.width + marginLeft + marginRight
+            let height = img.height + marginTop + marginBottom
+            canvas.width = width
+            canvas.height = height 
+            if(labelInfo.bgColor){
+                context.fillStyle = 'rgba(' + labelInfo.bgColor.r + ',' + labelInfo.bgColor.g + ',' + labelInfo.bgColor.b + ',' + labelInfo.bgColor.a + ')';
+                context.fillRect(0,0,width,height); 
+            }
+            context.drawImage(img, marginLeft, marginTop, img.width, img.height)
+        }
         let labelWidth = labelInfo.widthRatioToImg ? img.width * labelInfo.widthRatioToImg : labelImg.width //widthRatioToImg:label的width占img的width的比例
         let labelHeight = (labelWidth * labelImg.height) / labelImg.width
 
-        if (!labelInfo.leftRatioToImg && labelInfo.rightRatioToImg) {
+        if (labelInfo.leftRatioToImg == void 0 && labelInfo.rightRatioToImg != void 0) {
             labelInfo.leftRatioToImg = 1 - labelInfo.rightRatioToImg - (labelInfo.widthRatioToImg || labelImg.width / img.width)
         }
-        if (!labelInfo.topRatioToImg && labelInfo.bottomRatioToImg) {
+        if (labelInfo.topRatioToImg == void 0 && labelInfo.bottomRatioToImg != void 0) {
             labelInfo.topRatioToImg = 1 - labelInfo.bottomRatioToImg - labelHeight / img.height
         }
 
-        let labelLeft = img.width * labelInfo.leftRatioToImg //leftRatioToImg:label的left占img的width的比例
-        let labelTop = img.height * labelInfo.topRatioToImg //topRatioToImg:label的top占img的height的比例
+        let labelLeft = img.width * labelInfo.leftRatioToImg + marginLeft //leftRatioToImg:label的left占img的width的比例
+        let labelTop = img.height * labelInfo.topRatioToImg + marginTop //topRatioToImg:label的top占img的height的比例
 
         context.globalAlpha = labelInfo.opacity != void 0 ? labelInfo.opacity : 1
         context.drawImage(labelImg, labelLeft, labelTop, labelWidth, labelHeight)
-
+        
+        if(labelInfo.outputCanvas){
+            return canvas
+        }
 
         var dataUrl = canvas.toDataURL('image/png', labelInfo.compressRatio)
         //Common.downloadFile(dataUrl, 'screenshot.png')
-        context.clearRect(0,0,width,height)
+        context.clearRect(0,0,canvas.width,canvas.height)
         return dataUrl
 
  

+ 7 - 2
src/custom/viewer/ViewerNew.js

@@ -3747,6 +3747,7 @@ export class Viewer extends ViewerBase{
             {//恢复:
                 
                 this.backgroundOpacity = oldStates.bgOpacity;
+                this.background = oldStates.background;
                 this.pauseTestMaxLevel = false
                 
                 
@@ -3827,7 +3828,8 @@ export class Viewer extends ViewerBase{
         let viewports = [],  oldStates = {
             viewports:[],
             pano: Potree.settings.displayMode == 'showPanos' ? viewer.images360.currentPano : null,
-            bgOpacity : this.backgroundOpacity
+            bgOpacity : this.backgroundOpacity,
+            background: this.background
         }
         if(!info.type.includes('prism2d')){
             viewports.push(mainViewport)
@@ -3858,7 +3860,10 @@ export class Viewer extends ViewerBase{
          
         
         if(info.bgOpacity != void 0){
-            this.backgroundOpacity = info.bgOpacity
+            this.backgroundOpacity = info.bgOpacity 
+        }
+        if(info.background != void 0){
+            this.background = info.background 
         }
          
         Potree.settings.pointDensity = info.pointDensity || 'screenshot'