xzw преди 3 години
родител
ревизия
5f9e6d0216

+ 17 - 10
SuperTwo762/js/main_2020_show.js

@@ -31463,22 +31463,29 @@ window.Modernizr = function(n, e, t) {
             }
             ,
             
-            getVisiblePano : function(position, options={}){//add
+            getVisiblePano : function(positions = [], options={}){//add
                 var visiblePanos = []; 
-                var B = position.clone(); 
+               
                 var panos = options.panos ||  player.model.panos.list;
-                 
+                options.posAtPanos = options.posAtPanos  || {}//在不同漫游点的positions
                 panos.forEach((pano)=>{
                     if(!pano.isAligned())return;
                     var A = pano.position.clone();
-                      
-                    var ray = new THREE.Raycaster(A.clone(), B.clone().sub(A).normalize(), 0, A.distanceTo(B) - (options.tolerance||0) ) 
-                    var o = ray.intersectObjects(options.model || player.model.colliders, true);
-                     
-                     
-                    if (!o || !o.length)visiblePanos.push(pano );
-                     
+                    var posB = options.posAtPanos[pano.id] || positions;
+                    var posLength = posB.length
                     
+                    for(let i=0;i<posLength;i++){
+                        
+                        var B = posB[i];
+                        var ray = new THREE.Raycaster(A.clone(), B.clone().sub(A).normalize(), 0, A.distanceTo(B) - (options.tolerance||0) ) 
+                        var o = ray.intersectObjects(options.model || player.model.colliders, true);
+                    
+                        if (!o || !o.length){ //只要有一点可见,就算整体可见
+                            visiblePanos.push(pano );
+                            break;
+                        }
+                    }    
+                     
                 })  	  
              
                 return visiblePanos

+ 7 - 1
SuperTwo791/js/main_2020_show.js

@@ -15706,7 +15706,7 @@ window.Modernizr = function(n, e, t) {
             }else{
                 u.texture1.value = defaultTex1;
                 u.texture2.value = defaultTex2;
-                console.log(this.sid)
+            
             }  
         }
         
@@ -22489,6 +22489,12 @@ window.Modernizr = function(n, e, t) {
                                 }else{
                                     overlay.videoControl(false) 
                                 }
+                            }else if(this.animateInfo){ 
+                                if(this.visible && this.inSight()){
+                                    GifTexDeal.start(this.animation)
+                                }else{
+                                    GifTexDeal.stop(this.animation)
+                                } 
                             }
                         })
                         

+ 114 - 0
SuperTwo791/js/manage.js

@@ -413,6 +413,120 @@ function hotMatcher(data){
 
 
 
+var GifTexDeal = {
+    
+    animateObjects : [], 
+     
+    addAnimation : function(texture, owner, info, id){
+        var object = {
+            texture,
+            owner,
+            info,
+            id 
+        }
+        this.setRepeart(object)
+        this.animateObjects.push(object)
+        return object
+    },
+    remove : function(object){
+        var index = this.animateObjects.indexOf(object) 
+        if(index>-1){
+            this.stop(object)
+            object.texture.repeat.set(1,1) 
+            this.animateObjects.splice(index, 1)
+        }
+    },
+    setRepeart : function(object){
+        object.texture.repeat.set(1/object.info.cellXcount, 1/object.info.cellYcount)
+    },
+    start: function(object){ 
+        /* var b = this
+          , offset = this.cursor.material.map.offset
+          , f = function(a) {
+            return Math.floor(17 * a) / 17   //对应17个精灵图片段
+        };
+        b.canStartAnimation = !1,
+        this.cursorAnimate = new TWEEN.Tween(offset).to({
+            x: 1    //100%
+        }, 1e3).onStart(function() {
+            b.canStartAnimation = !1
+        }).onStop(function() {
+            b.canStartAnimation = !0,
+            this.x = 0,
+            offset.x = 0
+        }).onUpdate(function() {}).onComplete(function() {
+            done(),
+            offset.x = 0,
+            setTimeout(function() {
+                b.canStartAnimation = !0
+            }, 1500)
+        }),
+        this.cursorAnimate.easing(f),
+        this.cursorAnimate.start()
+ */ 
+          
+        if(!object || object.started)return;
+        var count = object.info.cellXcount * object.info.cellYcount
+        
+        if(count == 1 )return;
+        
+        transitions.start( (progress)=>{
+            var index = Math.floor(count * progress);
+            var indexX =  index % object.info.cellXcount
+            var indexY =  object.info.cellYcount - Math.floor(index / object.info.cellXcount ) - 1;  //uv.offset.y是从下到上的
+            object.texture.offset.x = indexX / object.info.cellXcount;
+            object.texture.offset.y = indexY / object.info.cellYcount;
+            
+            //console.log(object.id + " : "+ object.texture.offset.toArray())
+        } , object.info.duration, ()=>{//done
+            object.started = false
+            object.texture.offset.x = 0;
+            object.texture.offset.y = 0;
+            this.start(object)
+        }, 0 ,null, object.id, "gif_"+object.id); 
+
+        object.started = true
+
+    },
+    
+    startAnimations : function(o={}){
+        this.animateObjects.forEach(e=>{this.start(e)})
+
+    }
+    ,
+    stop: function(object){ 
+        if(!object || !object.started)return;
+        transitions.cancelById("gif_"+object.id);
+        object.texture.offset.set(0,0)    
+        object.started = false
+    }
+}
+
+var CloneObject = function(copyObj, result, isSimpleCopy) {
+    //isSimpleCopy只复制最外层
+    //复制json		result的可能:普通数字或字符串、普通数组、复杂对象
+    if(!copyObj)return null
+    result = result || {};
+    if (copyObj instanceof Array) {
+        if (copyObj[0]instanceof Object) {
+            //不支持含有 [[Object]] 这样二级数组里面还是复杂数据的,普通和复杂的数据混合可能也不支持
+            console.error("不支持含有 [[Object]] 这样二级数组里面还是复杂数据的...")
+        }
+        return copyObj.slice(0);
+        //如果是数组,直接复制返回(排除数组内是object
+    }
+    for (var key in copyObj) {
+        if (copyObj[key]instanceof Object && !isSimpleCopy)
+            result[key] = CloneObject(copyObj[key]);
+        else
+            result[key] = copyObj[key];
+        //如果是函数类同基本数据,即复制引用
+    }
+    return result;
+}
+;
+
+
 
 //兼容一代的場景
 //請求地址統一管理

+ 20 - 1
SuperTwo791/js/overlay.js

@@ -251,6 +251,18 @@ var initOverlay = function(THREE) {
         this.updateMatrixWorld()
         this.getVisiblePanos()
 
+        {//gif
+            if(this.animation){
+                GifTexDeal.remove(this.animation)
+            }
+            this.animateInfo = CloneObject(info.animateInfo) 
+            if(this.animateInfo && plane.material.map){
+                this.animation = GifTexDeal.addAnimation(plane.material.map, this, this.animateInfo, this.sid )
+                this.visible && this.inSight() && GifTexDeal.start(this.animation)
+            }    
+        }
+        
+        
     }
 
 
@@ -448,7 +460,7 @@ var initOverlay = function(THREE) {
         var plane = this.plane;
 
         plane.material.map = Texture.load(this.file, ()=>{
-            plane.material.needsUpdate = true
+            
             if (this._loadDones) {
                 this._loadDones.forEach(e=>e())
                 this._loadDones = null
@@ -456,6 +468,13 @@ var initOverlay = function(THREE) {
             setTimeout(Overlay.loadNext, 50)
             plane.material.opacity = 1;
             console.log('overlay loaded: ' + this.sid)
+            
+            if(this.animateInfo){
+                this.animation = GifTexDeal.addAnimation(plane.material.map, this, this.animateInfo, this.sid )
+                this.visible && this.inSight() && GifTexDeal.start(this.animation)
+            }
+            
+            plane.material.needsUpdate = true
         })
         plane.material.map.wrapS = plane.material.map.wrapT = THREE.ClampToEdgeWrapping;
         plane.material.map.minFilter = THREE.LinearFilter;

+ 17 - 1
edit-backstage/css/lzb.css

@@ -305,10 +305,11 @@ ul.MenuOptions li.chosen {
 }
 
 .toolRight .editText {
-    height: 200px !important;
+    min-height: 200px !important;
     line-height: 130% !important;
     padding: 10px;
     text-align: justify;
+    resize: vertical;
 }
 
 @keyframes warnFlash {
@@ -1921,4 +1922,19 @@ ul.MenuOptions li.chosen {
     width: 45px !important;
     height: 45px !important;
     margin:1px;
+}
+
+
+.toolRight #gifInfoEdit{
+    text-align : left; 
+}
+.toolRight #gifInfoEdit input {
+    width: 49px;
+    height:25px;
+    margin:0 4px;
+    padding: 0 1px;
+    text-align: center;
+}
+.toolRight #gifInfoEdit span {
+    margin:0 3px;  
 }

+ 25 - 4
edit-backstage/edit_zh.html

@@ -938,7 +938,7 @@
                                 <span>热点大小 (初始值为1)</span>
                             </div>
                             <ul id="hotIconScale" class="clearfix hotStyle-item colorWrap">
-                                <input class="" type="number" placeholder="请输入热点大小比例" value="1" max="1.5" min="0.1"
+                                <input class="" type="number" placeholder="请输入热点大小比例" value="1" max="100" min="0.1"
                                     step="0.1">
                             </ul>
                         </li>
@@ -1050,7 +1050,7 @@
                                     </ul>
                                     <div id="userHotScale" class="hide">
                                         <ul id="hotIconScale_2" class="clearfix hotStyle-item colorWrap">
-                                            <input class="" type="number" placeholder="请输入热点大小比例" value="1" max="1.5" min="0.1" step="0.1">
+                                            <input class="" type="number" placeholder="请输入热点大小比例" value="1" max="100" min="0.1" step="0.1">
                                         </ul>
                                     </div>
                                 </li>
@@ -1673,8 +1673,29 @@
                                 </ul>
                                 
                             </li>
-
-
+                            <li id="gifEdit">
+                                <div class="itemTitle">
+                                    <span data-lang="">设置动画</span> 
+                                </div>
+                                
+                                <ul id="gifSwitch" class="switch clearfix hotStyle-item colorWrap">
+                                    <label><input class="mui-switch mui-switch-animbg" type="checkbox">
+                                        是否开启
+                                    </label> 
+                                </ul>
+                                
+                                <div id="gifInfoEdit" style='display:none'>
+                                    横向 <input id="gifXCount"></input> 张 ( 宽<input id="gifCellWidth">px )<br>
+                                    纵向 <input id="gifYCount"></input> 张 ( 高<input id="gifCellHeight">px )<br>
+                                    共<span id='gifFrameCount'></span>帧,总宽<span id='gifImgWidth'></span>px, 总高<span id='gifImgHeight'></span>px<br>
+                                    时长 <input id="gifDuration"></input> 秒( 帧率 <input id="gifFps" style=></input> )<br>
+                                    
+                                    <!-- <input  class="editCheckbox" type="checkbox" value="loadlogo" id="loopGif"></input> -->
+                                </div>
+                                
+                                <label class="remark">注:1 精灵贴图的排列顺序为从左到右、从上到下。   2 图片最长边尽量不大于2048px,因部分手机gpu性能有限。 </label>
+                                
+                            </li>
 
                             <li>
                                 <div class="itemTitle">

+ 0 - 252
edit-backstage/js/css/cropper.min.css

@@ -1,252 +0,0 @@
-/*!
- * Cropper v3.1.3
- * https://github.com/fengyuanchen/cropper
- *
- * Copyright (c) 2014-2017 Chen Fengyuan
- * Released under the MIT license
- *
- * Date: 2017-10-21T10:03:37.133Z
- */.cropper-container {
- direction:ltr;
- font-size:0;
- line-height:0;
- position:relative;
- -ms-touch-action:none;
- touch-action:none;
- -webkit-user-select:none;
- -moz-user-select:none;
- -ms-user-select:none;
- user-select:none
-}
-.cropper-container img {
- display:block;
- height:100%;
- image-orientation:0deg;
- max-height:none!important;
- max-width:none!important;
- min-height:0!important;
- min-width:0!important;
- width:100%
-}
-.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box {
- bottom:0;
- left:0;
- position:absolute;
- right:0;
- top:0
-}
-.cropper-canvas,.cropper-wrap-box {
- overflow:hidden
-}
-.cropper-drag-box {
- background-color:#fff;
- opacity:0
-}
-.cropper-modal {
- background-color:#000;
- opacity:.5
-}
-.cropper-view-box {
- display:block;
- height:100%;
- outline-color:rgba(51,153,255,.75);
- outline:1px solid #39f;
- overflow:hidden;
- width:100%
-}
-.cropper-dashed {
- border:0 dashed #eee;
- display:block;
- opacity:.5;
- position:absolute
-}
-.cropper-dashed.dashed-h {
- border-bottom-width:1px;
- border-top-width:1px;
- height:33.33333%;
- left:0;
- top:33.33333%;
- width:100%
-}
-.cropper-dashed.dashed-v {
- border-left-width:1px;
- border-right-width:1px;
- height:100%;
- left:33.33333%;
- top:0;
- width:33.33333%
-}
-.cropper-center {
- display:block;
- height:0;
- left:50%;
- opacity:.75;
- position:absolute;
- top:50%;
- width:0
-}
-.cropper-center:after,.cropper-center:before {
- background-color:#eee;
- content:" ";
- display:block;
- position:absolute
-}
-.cropper-center:before {
- height:1px;
- left:-3px;
- top:0;
- width:7px
-}
-.cropper-center:after {
- height:7px;
- left:0;
- top:-3px;
- width:1px
-}
-.cropper-face,.cropper-line,.cropper-point {
- display:block;
- height:100%;
- opacity:.1;
- position:absolute;
- width:100%
-}
-.cropper-face {
- background-color:#fff;
- left:0;
- top:0
-}
-.cropper-line {
- background-color:#39f
-}
-.cropper-line.line-e {
- cursor:e-resize;
- right:-3px;
- top:0;
- width:5px
-}
-.cropper-line.line-n {
- cursor:n-resize;
- height:5px;
- left:0;
- top:-3px
-}
-.cropper-line.line-w {
- cursor:w-resize;
- left:-3px;
- top:0;
- width:5px
-}
-.cropper-line.line-s {
- bottom:-3px;
- cursor:s-resize;
- height:5px;
- left:0
-}
-.cropper-point {
- background-color:#39f;
- height:5px;
- opacity:.75;
- width:5px
-}
-.cropper-point.point-e {
- cursor:e-resize;
- margin-top:-3px;
- right:-3px;
- top:50%
-}
-.cropper-point.point-n {
- cursor:n-resize;
- left:50%;
- margin-left:-3px;
- top:-3px
-}
-.cropper-point.point-w {
- cursor:w-resize;
- left:-3px;
- margin-top:-3px;
- top:50%
-}
-.cropper-point.point-s {
- bottom:-3px;
- cursor:s-resize;
- left:50%;
- margin-left:-3px
-}
-.cropper-point.point-ne {
- cursor:ne-resize;
- right:-3px;
- top:-3px
-}
-.cropper-point.point-nw {
- cursor:nw-resize;
- left:-3px;
- top:-3px
-}
-.cropper-point.point-sw {
- bottom:-3px;
- cursor:sw-resize;
- left:-3px
-}
-.cropper-point.point-se {
- bottom:-3px;
- cursor:se-resize;
- height:20px;
- opacity:1;
- right:-3px;
- width:20px
-}
-@media (min-width:768px) {
- .cropper-point.point-se {
-  height:15px;
-  width:15px
- }
-}
-@media (min-width:992px) {
- .cropper-point.point-se {
-  height:10px;
-  width:10px
- }
-}
-@media (min-width:1200px) {
- .cropper-point.point-se {
-  height:5px;
-  opacity:.75;
-  width:5px
- }
-}
-.cropper-point.point-se:before {
- background-color:#39f;
- bottom:-50%;
- content:" ";
- display:block;
- height:200%;
- opacity:0;
- position:absolute;
- right:-50%;
- width:200%
-}
-.cropper-invisible {
- opacity:0
-}
-.cropper-bg {
- background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")
-}
-.cropper-hide {
- display:block;
- height:0;
- position:absolute;
- width:0
-}
-.cropper-hidden {
- display:none!important
-}
-.cropper-move {
- cursor:move
-}
-.cropper-crop {
- cursor:crosshair
-}
-.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point {
- cursor:not-allowed
-}
-/*# sourceMappingURL=cropper.min.css.map */

Файловите разлики са ограничени, защото са твърде много
+ 0 - 3241
edit-backstage/js/css/edit.js


Файловите разлики са ограничени, защото са твърде много
+ 0 - 1788
edit-backstage/js/css/lzb.css


+ 280 - 54
edit-backstage/js/edit.js

@@ -1520,7 +1520,7 @@ Hotpoint.prototype.inputList = function(text, val) {
 }
 //添加热点模型
 Hotpoint.prototype.addModel = function() {
-    var text = this.inputList("请填写模型链接");
+    var text = this.inputList("请填写模型链接(https开头)");
     this.hotpointDetail.find(".model .add").on('click', function() {
         $(this).closest(".model").find(".list").append(text)
     });
@@ -3458,6 +3458,14 @@ var EditOverlay = {
                     //$('#overlayUpload .preview').css('background-image',"").append($(video));
                    
                     this.useImgRatio()
+                    this.updateGifPanel(this.editPlane)
+                    
+                    if(this.editPlane.animateInfo){
+                        GifTexDeal.remove(this.editPlane.animation)
+                        this.editPlane.animation = GifTexDeal.addAnimation(this.editPlane.plane.material.map, this.editPlane, this.editPlane.animateInfo, this.editPlane.sid)
+                        GifTexDeal.start(this.editPlane.animation)
+                    }
+                   
                     //自适应比例 
                     this.editPlane.file = photo.file;
                     plane.material.opacity = 1;
@@ -3478,11 +3486,190 @@ var EditOverlay = {
             else {
                 this.getOverlayInfo(overlay)
             }
-              
             this.addToList(overlay)
-        }
-        )
+        } )
         
+        $("#gifSwitch input").on("change",  (e)=>{
+            var on = $("#gifSwitch input").is(':checked');
+            $("#gifInfoEdit").css({display: on ? 'block' : 'none'})
+            if(on){
+                EditOverlay.editPlane.animateInfo = {
+                    cellXcount : parseInt($("#gifXCount").val()),
+                    cellYcount : parseInt($("#gifYCount").val()),
+                    loop : true,
+                    duration : parseFloat($("#gifDuration").val()) * 1000
+                }  
+                EditOverlay.editPlane.animation = GifTexDeal.addAnimation(EditOverlay.editPlane.plane.material.map, EditOverlay.editPlane, EditOverlay.editPlane.animateInfo, EditOverlay.editPlane.sid)       
+                GifTexDeal.start(EditOverlay.editPlane.animation)
+            }else{
+                GifTexDeal.remove(EditOverlay.editPlane.animation) 
+                EditOverlay.editPlane.animateInfo = null
+            }
+        })  
+
+        
+        {//gif动画  input
+        
+            let strictInputNum = function(e, precision, min=0,max){//precision:保留小数位数
+                var value = e.target.value.trim(); 
+                var lastOne = value[value.length-1];
+                var preContent = value.substr(0,value.length-1)
+                var hasPoint = precision > 0 && lastOne == '.' ; 
+                 
+                var a = Math.pow(10, precision)
+                value = parseFloat(value) || 0;
+                if(isNaN(value)){
+                    e.target.value = preContent //还原
+                    return
+                }
+                e.target.value =  Math.max(min, parseInt(value * a) / a )
+                
+                hasPoint && (e.target.value += '.')//补小数点
+            }
+            let changeAnimation = function(){
+                GifTexDeal.setRepeart(EditOverlay.editPlane.animation)
+               
+            }
+            let restartAnimation = function(){
+                GifTexDeal.stop(EditOverlay.editPlane.animation)
+                GifTexDeal.start(EditOverlay.editPlane.animation)
+            }
+            let changeFrameCount = function(){
+                var a = EditOverlay.editPlane.animateInfo
+                var frameCount = a.cellXcount * a.cellYcount
+                $("#gifFrameCount").text(frameCount)
+                var fps = parseFloat($("#gifFps").val())
+                a.duration = frameCount / fps * 1000
+                $("#gifDuration").val(toPrecision(a.duration/1000, 2))
+                 
+            }
+            
+            let gifXCountFun = function(value){
+                EditOverlay.editPlane.animateInfo.cellXcount = value 
+                var gifImgWidth = parseFloat($("#gifImgWidth").text())
+                var gifCellWidth = toPrecision(gifImgWidth / EditOverlay.editPlane.animateInfo.cellXcount,1);
+                $("#gifCellWidth").val(gifCellWidth)
+                changeFrameCount()
+                changeAnimation()
+            }
+           
+            $("#gifXCount").on('input',(e)=>{
+                strictInputNum(e, 0) 
+                gifXCountFun(parseFloat(e.target.value))
+                
+            })
+            $("#gifXCount").on('change',(e)=>{
+                strictInputNum(e, 0, 1) 
+                gifXCountFun(parseFloat(e.target.value))
+                restartAnimation()
+            })
+            
+            
+            let gifYCountFun = function(value){
+                EditOverlay.editPlane.animateInfo.cellYcount = value 
+                var gifImgHeight = parseFloat($("#gifImgHeight").text())
+                var gifCellHeight = toPrecision(gifImgHeight / EditOverlay.editPlane.animateInfo.cellYcount,1);
+                $("#gifCellHeight").val(gifCellHeight)
+                changeFrameCount()
+                changeAnimation()
+            }
+            $("#gifYCount").on('input',(e)=>{
+                strictInputNum(e, 0)
+                gifYCountFun(parseFloat(e.target.value))
+            })
+            $("#gifYCount").on('change',(e)=>{
+                strictInputNum(e, 0, 1)
+                gifYCountFun(parseFloat(e.target.value))
+                changeAnimation()
+                restartAnimation()
+            })
+          
+          
+            let gifCellWidthFun = function(value){
+                var gifCellWidth = value;
+                var gifImgWidth = parseFloat($("#gifImgWidth").text())
+                var cellXcount = toPrecision(gifImgWidth / gifCellWidth,2);
+                $("#gifXCount").val(cellXcount)
+                changeAnimation()
+            }
+            $("#gifCellWidth").on('input',(e)=>{
+                strictInputNum(e, 0)
+                gifCellWidthFun(parseFloat(e.target.value))
+                
+            })
+            $("#gifCellWidth").on('change',(e)=>{
+                strictInputNum(e, 0, 1)
+                gifCellWidthFun(parseFloat(e.target.value))
+                var cellXcount = $("#gifXCount").val();
+                var cellXcountInt = Math.round(cellXcount)
+                if(cellXcountInt != cellXcount){
+                    $("#gifXCount").val(cellXcountInt)
+                    gifXCountFun(cellXcountInt)
+                    changeAnimation()
+                }
+                restartAnimation()
+            }) 
+            
+            
+            let gifCellHeightFun = function(value){
+                var gifCellHeight = parseFloat(e.target.value);
+                var gifImgHeight = parseFloat($("#gifImgHeight").text())
+                var cellYcount = toPrecision(gifImgHeight / gifCellHeight,2);
+                $("#gifYCount").val(cellYcount) 
+                
+            } 
+            $("#gifCellHeight").on('input',(e)=>{
+                strictInputNum(e, 0)
+                gifCellHeightFun(parseFloat(e.target.value))
+                
+            })
+            $("#gifCellHeight").on('change',(e)=>{
+                strictInputNum(e, 0, 1)
+                gifCellHeightFun(parseFloat(e.target.value))
+                var cellYcount = $("#gifYCount").val();
+                var cellYcountInt = Math.round(cellYcount)
+                if(cellYcountInt != cellYcount){
+                    $("#gifYCount").val(cellYcountInt)
+                    gifYCountFun(cellYcountInt)
+                    changeAnimation()
+                }  
+                restartAnimation()        
+            })
+             
+             
+            let gifDurationFun = function(value){
+                var a = EditOverlay.editPlane.animateInfo 
+                let frameCount = a.cellXcount * a.cellYcount
+                a.duration = value
+                $("#gifFps").val(toPrecision(frameCount / a.duration * 1000, 1))
+            } 
+            $("#gifDuration").on('input',(e)=>{
+                strictInputNum(e, 1);
+                gifDurationFun(parseFloat(e.target.value) * 1000)
+            })
+            $("#gifDuration").on('change',(e)=>{
+                strictInputNum(e, 1, 0.01);
+                gifDurationFun(parseFloat(e.target.value) * 1000)
+                restartAnimation()
+            })
+            
+            var gifFpsFun = function(e){
+                strictInputNum(e, 0, 1);
+                var fps = parseFloat(e.target.value)
+                var a = EditOverlay.editPlane.animateInfo 
+                let frameCount = a.cellXcount * a.cellYcount
+                a.duration = frameCount / fps * 1000
+                $("#gifDuration").val(toPrecision(a.duration / 1000, 2))
+            }
+            $("#gifFps").on('input',(e)=>{
+                gifFpsFun(e)
+                
+            })
+            $("#gifFps").on('change',(e)=>{
+                gifFpsFun(e)
+                restartAnimation()
+            })
+        }
         
         
     },
@@ -3501,7 +3688,9 @@ var EditOverlay = {
     switchEditType : function(type){
         this.editType = type;
         $('#overlayUpload [name="upload"] button').text(type == 'video' ? "上传视频" : "上传图片")  
-        $('#overlayUpload .preview span').text(type == 'video' ? "支持MP4、MOV等,<20M" : "支持jpg、png等,<20M");
+        $('#overlayUpload .preview span').eq(0).text(type == 'video' ? "支持MP4、MOV等,<20M" : "支持jpg、png等,<20M");
+        if(type != 'photo' || !this.editPlane) $('#overlayProp #gifEdit').css({display: 'none'})
+         
     },
     beginToAddPlane: function(event) {
         this.switchEditType($(event.target).attr("data-type"))   
@@ -3566,26 +3755,17 @@ var EditOverlay = {
         });
         $('#overlayUpload .preview [attr-type="width"]').text(toPrecision(overlay.width, 2))
         $('#overlayUpload .preview [attr-type="height"]').text(toPrecision(overlay.height, 2))
-
+        $("#gifSwitch input").prop('checked', !!overlay.animateInfo);
+        $("#gifInfoEdit").css({display: !!overlay.animateInfo ? 'block' : 'none'})
     },
-    updateOverlayPanel: function(overlay) {
-        this.editPlane = overlay;
-        overlay.requestDownload()
-        
-        if(overlay._loadDones){
-            $('.waiting').addClass('showloading');
-            overlay._loadDones.push(()=>{
-                $('.waiting').removeClass('showloading');
-            })
-        }
-        
-        
-        
+    
+    
+    updateOverlayPreview : function(overlay){
         var plane = overlay.plane
         var src = plane.material.map && (plane.material.map.image ? plane.material.map.image.src : overlay.fileSrc );
         $('#overlayUpload .preview video').remove();
         
-        overlay.overlayType && this.switchEditType(overlay.overlayType)
+                                                                       
         
         
         if (overlay.overlayType == "video") {
@@ -3595,7 +3775,7 @@ var EditOverlay = {
         } else if(overlay.overlayType == "photo" || overlay.overlayType == "text"){
             $('#overlayUpload .preview').css({
                 'background-image': src ? ("url(" + src + ")") : "",
-                'background-size': "contain"
+                'background-size': "100% 100%"
             })
         }else{
             $('#overlayUpload .preview').css({ 
@@ -3612,8 +3792,18 @@ var EditOverlay = {
             $('#overlayUpload [name="useImgRatio"]').addClass("hide")
             $('#overlayUpload .preview').removeClass('uploaded')
         }
-
-        this.updateOverlayScaleDisplay()
+    }
+    ,
+    
+    
+    
+    updateOverlayPanel: function(overlay) {
+        overlay.overlayType && this.switchEditType(overlay.overlayType)
+        this.updateOverlayPreview(overlay) 
+        this.updateOverlayScaleDisplay() 
+        this.updateGifPanel(overlay)
+        
+      
 
         if (overlay.hasBox) {
             this.scroller.videoDepth.setValue(overlay.scale.z * settings.overlay.depth * 100, true)
@@ -3630,10 +3820,58 @@ var EditOverlay = {
     },
     
     //----------------------------
-    
-    
-    
-    
+    updateGifPanel : function(overlay){ 
+        if(this.editType == 'photo'){
+            if(!overlay.plane.material.map)return;
+            $('#overlayProp #gifEdit').css({display: 'block'})
+         
+            let w = overlay.plane.material.map.image.width
+            let h = overlay.plane.material.map.image.height
+            if(overlay.animateInfo){
+                let a = overlay.animateInfo
+                $("#gifXCount").val(a.cellXcount);
+                $("#gifYCount").val(a.cellYcount);
+                $("#gifImgWidth").text(w)
+                $("#gifImgHeight").text(h)
+                $("#gifCellWidth").val(toPrecision(w / a.cellXcount, 2));
+                $("#gifCellHeight").val(toPrecision(h / a.cellYcount, 2));
+                let frameCount = a.cellXcount * a.cellYcount
+                $("#gifFrameCount").text(frameCount) 
+                $("#gifDuration").val(toPrecision(a.duration / 1000, 2));
+                $("#gifFps").val(toPrecision(frameCount / a.duration * 1000, 1) );  
+            }else{
+                $("#gifXCount").val(1);
+                $("#gifYCount").val(1);
+                $("#gifImgWidth").text(w)
+                $("#gifImgHeight").text(h)
+                $("#gifCellWidth").val(w);
+                $("#gifCellHeight").val(h) 
+                $("#gifFrameCount").text(1) 
+                $("#gifDuration").val(1);
+                $("#gifFps").val(1);  
+            }
+        }
+    }
+                    
+    ,
+    beginEdit :  function(overlay){
+        $('#overlayProp').removeClass('atRight').removeClass('hide')
+        this.endAddPlane();
+        this.editPlane = overlay;
+        
+        
+        overlay.requestDownload() 
+        if(overlay._loadDones){
+            $('.waiting').addClass('showloading');
+            overlay._loadDones.push(()=>{
+                $('.waiting').removeClass('showloading');
+            })
+        }
+        overlay.visible = true
+        this.updateOverlayPanel(overlay)  
+        transformControls.attach(overlay)      
+    }
+    ,
     panoPosSwitchOnChange : function(){
         var on = this.panoPosSwitch.is(':checked')
          
@@ -3713,7 +3951,7 @@ var EditOverlay = {
         if (type == 'cancel') {
             if (!this.editPlane.isNew && !this.editPlane.needDelete)
                 this.editPlane.setFromInfo(this.editPlane.info)
-                //this.setOverlayFromInfo(this.editPlane, this.editPlane.info);//恢复
+                
             else
                 this.disposeOverlay(this.editPlane);
             //删除	
@@ -3759,7 +3997,7 @@ var EditOverlay = {
         
         this.updateScale()
         
-        this.updateOverlayPanel(this.editPlane)
+        this.updateOverlayPreview(this.editPlane)
     },
      
     getOverlayInfo: function(overlay) {
@@ -3787,6 +4025,9 @@ var EditOverlay = {
             hasBox: overlay.hasBox,
             transformAtPanos:  transformAtPanos
         }
+        if(overlay.animateInfo ){
+            overlay.info.animateInfo = CloneObject(overlay.animateInfo)  
+        }
     },
 
     getSavingInfo: function(overlay) {
@@ -3813,8 +4054,13 @@ var EditOverlay = {
             hasBox: overlay.hasBox ? 1 : 0,
             media: [overlay.overlayType], 
             file: overlay.fileSrc || overlay.plane.material.map.image.src,
-            transformAtPanos : transformAtPanos
+            transformAtPanos : transformAtPanos,
+            
+        }
+        if(overlay.animateInfo && overlay.animateInfo.cellXcount * overlay.animateInfo.cellYcount > 1){
+            info.animateInfo = overlay.animateInfo    
         }
+        
 
         return info
 
@@ -3867,7 +4113,9 @@ var EditOverlay = {
         plane.material.dispose();
         overlay.parent.remove(overlay);
         this.removeFromList(overlay)
-
+        if(this.animation){
+            GifTexDeal.remove(this.animation)
+        }
         //this.beginToAddPlane()
 
     },
@@ -4897,29 +5145,7 @@ function permitTranMode(state) {
     state ? $(".pinBottom.left").removeClass('hide') : $(".pinBottom.left").addClass('hide');
 }
 
-CloneObject = function(copyObj, result, isSimpleCopy) {
-    //isSimpleCopy只复制最外层
-    //复制json		result的可能:普通数字或字符串、普通数组、复杂对象
-    result = result || {};
-    if (copyObj instanceof Array) {
-        if (copyObj[0]instanceof Object) {
-            //不支持含有 [[Object]] 这样二级数组里面还是复杂数据的,普通和复杂的数据混合可能也不支持
-            console.error("不支持含有 [[Object]] 这样二级数组里面还是复杂数据的...")
-        }
-        return copyObj.slice(0);
-        //如果是数组,直接复制返回(排除数组内是object
-    }
-    for (var key in copyObj) {
-        if (copyObj[key]instanceof Object && !isSimpleCopy)
-            result[key] = CloneObject(copyObj[key]);
-        else
-            result[key] = copyObj[key];
-        //如果是函数类同基本数据,即复制引用
-    }
-    return result;
-}
-;
-
+ 
 function randomWord(randomFlag, min, max) {
     //随机字符串
     var str = ""

Файловите разлики са ограничени, защото са твърде много
+ 9 - 12
edit-backstage/js/main_2020_edit.js


+ 114 - 0
edit-backstage/js/manage.js

@@ -413,6 +413,120 @@ function hotMatcher(data){
 
 
 
+var GifTexDeal = {
+    
+    animateObjects : [], 
+     
+    addAnimation : function(texture, owner, info, id){
+        var object = {
+            texture,
+            owner,
+            info,
+            id 
+        }
+        this.setRepeart(object)
+        this.animateObjects.push(object)
+        return object
+    },
+    remove : function(object){
+        var index = this.animateObjects.indexOf(object) 
+        if(index>-1){
+            this.stop(object)
+            object.texture.repeat.set(1,1) 
+            this.animateObjects.splice(index, 1)
+        }
+    },
+    setRepeart : function(object){
+        object.texture.repeat.set(1/object.info.cellXcount, 1/object.info.cellYcount)
+    },
+    start: function(object){ 
+        /* var b = this
+          , offset = this.cursor.material.map.offset
+          , f = function(a) {
+            return Math.floor(17 * a) / 17   //对应17个精灵图片段
+        };
+        b.canStartAnimation = !1,
+        this.cursorAnimate = new TWEEN.Tween(offset).to({
+            x: 1    //100%
+        }, 1e3).onStart(function() {
+            b.canStartAnimation = !1
+        }).onStop(function() {
+            b.canStartAnimation = !0,
+            this.x = 0,
+            offset.x = 0
+        }).onUpdate(function() {}).onComplete(function() {
+            done(),
+            offset.x = 0,
+            setTimeout(function() {
+                b.canStartAnimation = !0
+            }, 1500)
+        }),
+        this.cursorAnimate.easing(f),
+        this.cursorAnimate.start()
+ */ 
+          
+        if(!object || object.started)return;
+        var count = object.info.cellXcount * object.info.cellYcount
+        
+        if(count == 1 )return;
+        
+        transitions.start( (progress)=>{
+            var index = Math.floor(count * progress);
+            var indexX =  index % object.info.cellXcount
+            var indexY =  object.info.cellYcount - Math.floor(index / object.info.cellXcount ) - 1;  //uv.offset.y是从下到上的
+            object.texture.offset.x = indexX / object.info.cellXcount;
+            object.texture.offset.y = indexY / object.info.cellYcount;
+            
+            //console.log(object.id + " : "+ object.texture.offset.toArray())
+        } , object.info.duration, ()=>{//done
+            object.started = false
+            object.texture.offset.x = 0;
+            object.texture.offset.y = 0;
+            this.start(object)
+        }, 0 ,null, object.id, "gif_"+object.id); 
+
+        object.started = true
+
+    },
+    
+    startAnimations : function(o={}){
+        this.animateObjects.forEach(e=>{this.start(e)})
+
+    }
+    ,
+    stop: function(object){ 
+        if(!object || !object.started)return;
+        transitions.cancelById("gif_"+object.id);
+        object.texture.offset.set(0,0)    
+        object.started = false
+    }
+}
+
+var CloneObject = function(copyObj, result, isSimpleCopy) {
+    //isSimpleCopy只复制最外层
+    //复制json		result的可能:普通数字或字符串、普通数组、复杂对象
+    if(!copyObj)return null
+    result = result || {};
+    if (copyObj instanceof Array) {
+        if (copyObj[0]instanceof Object) {
+            //不支持含有 [[Object]] 这样二级数组里面还是复杂数据的,普通和复杂的数据混合可能也不支持
+            console.error("不支持含有 [[Object]] 这样二级数组里面还是复杂数据的...")
+        }
+        return copyObj.slice(0);
+        //如果是数组,直接复制返回(排除数组内是object
+    }
+    for (var key in copyObj) {
+        if (copyObj[key]instanceof Object && !isSimpleCopy)
+            result[key] = CloneObject(copyObj[key]);
+        else
+            result[key] = copyObj[key];
+        //如果是函数类同基本数据,即复制引用
+    }
+    return result;
+}
+;
+
+
 
 //兼容一代的場景
 //請求地址統一管理

+ 44 - 2
edit-backstage/js/overlay.js

@@ -170,8 +170,10 @@ var initOverlay = function(THREE) {
                 plane.material.map.minFilter = THREE.LinearFilter;
                 plane.material.map.magFilter = THREE.LinearFilter;
                 plane.material.map.generateMipmaps = true;  */
-            } else
+            } else{
                 plane.material.map.image = info.media;
+                plane.material.map.needsUpdate = true
+            }
             this.file = info.file;
         }
         this.overlayType = info.type;
@@ -183,6 +185,17 @@ var initOverlay = function(THREE) {
         this.updateMatrixWorld()
         this.getVisiblePanos()
 
+        
+        {//gif
+            if(this.animation){
+                GifTexDeal.remove(this.animation)
+            }
+            this.animateInfo = CloneObject(info.animateInfo) 
+            if(this.animateInfo && plane.material.map){
+                this.animation = GifTexDeal.addAnimation(plane.material.map, this, this.animateInfo, this.sid )
+                this.visible && this.inSight() && GifTexDeal.start(this.animation)
+            }    
+        }
     }
 
 
@@ -321,8 +334,31 @@ var initOverlay = function(THREE) {
             return true
         }
     }
+    Overlay.prototype.switchPlay = function(state){//手动播放暂停 
+        this.pausedByUser = !state
+        
+        this.videoControl(state)
+       
+        
+    }
     
     
+    Overlay.prototype.update = function(){//实时监测播放
+        if(this.overlayType == "video"){
+            if(this.visible && !this.pausedByUser && this.inSight()){
+                this.videoControl(true) 
+            }else{
+                this.videoControl(false) 
+            }
+        }else if(this.animateInfo){ 
+            if(this.visible && this.inSight()){
+                GifTexDeal.start(this.animation)
+            }else{
+                GifTexDeal.stop(this.animation)
+            } 
+        }
+    }
+    
     Overlay.prototype.addToLoadQueue = function() {
         if (this.overlayType == 'photo') {
             Overlay.loadQueue.includes(this) || Overlay.loadQueue.push(this)
@@ -339,7 +375,7 @@ var initOverlay = function(THREE) {
         var plane = this.plane;
 
         plane.material.map = Texture.load(this.file, ()=>{
-            plane.material.needsUpdate = true
+             
             if (this._loadDones) {
                 this._loadDones.forEach(e=>e())
                 this._loadDones = null
@@ -347,6 +383,12 @@ var initOverlay = function(THREE) {
             setTimeout(Overlay.loadNext, 50)
             plane.material.opacity = 1;
             console.log('overlay loaded: ' + this.sid)
+            if(this.animateInfo){
+                this.animation = GifTexDeal.addAnimation(plane.material.map, this, this.animateInfo, this.sid )
+                this.visible && this.inSight() && GifTexDeal.start(this.animation)
+            }
+            
+            plane.material.needsUpdate = true
         })
         plane.material.map.wrapS = plane.material.map.wrapT = THREE.ClampToEdgeWrapping;
         plane.material.map.minFilter = THREE.LinearFilter;