소스 검색

热点视频改进

xzw 2 년 전
부모
커밋
f233b60e36
7개의 변경된 파일384개의 추가작업 그리고 295개의 파일을 삭제
  1. 1 1
      edit.html
  2. 218 160
      js/Hot.js
  3. 22 8
      js/edit.js
  4. 19 0
      js/lib/mediainfo.min.js
  5. 28 62
      js/main_2020_edit.js
  6. 17 61
      js/main_2020_show.js
  7. 79 3
      js/manage.js

+ 1 - 1
edit.html

@@ -1016,7 +1016,7 @@
                                         <li class="" index="photo">图片</li>
                                         <li class="" index="video">视频</li>
                                     </ul>  
-                                    <label class="remark">注:修改样式图会影响到使用该组样式的所有热点。鼠标划到样式时使用它的热点会显示边框。未被使用的样式会在保存发布后被删除。</label>
+                                    <label class="remark">注:1 视频数据速率尽量低于2000kbps。 2 修改样式图会影响到使用它的所有热点,鼠标划到样式时这些热点会显示边框。3 未被使用的样式会在保存发布后被删除。</label>
                                     <div id='shineTexSelect' class='selectList texList'> 
                                         <a class="selection">
                                             <ul class="hotTexUpload">

+ 218 - 160
js/Hot.js

@@ -9,9 +9,9 @@ g_currentHot = null
  
 
 const playVideoWhenFlyOut = false
-
-const playCountMax = 2;//同时可播放的最大个数
-
+//同时可播放的最大个数:
+const playVideoMax = window.isEdit ? 4  :   browser.isMobile() ? 2 : 3;   
+const playAniMax = window.isEdit ? 8 :   browser.isMobile() ? 3 : 6;
 
 
 
@@ -91,11 +91,7 @@ window.initHot = function(model){
         if(mat) return mat
         else{
             var mat = new THREE.ShaderMaterial({ 
-                uniforms: {
-                    color: {
-                        type: "c",
-                        value: new THREE.Color(16720384)
-                    },
+                uniforms: { 
                     opac: {
                         type: "f",
                         value: 0
@@ -110,7 +106,7 @@ window.initHot = function(model){
                     }
                 }, 
                 vertexShader: "varying vec2 vUv;\n\nvoid main() {\n\n vUv =  uv ;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n}\n",
-                fragmentShader: "varying vec3 vNormal;\n\nvarying vec2 vUv;\n\nuniform float opac;\n\nuniform vec3 color;\n\nuniform sampler2D texture1;\n\nuniform sampler2D texture2;\n\nvoid main() {\n\nvec4 tcolor1 = texture2D( texture1, vUv );\n\nvec4 tcolor2 = texture2D( texture2, vUv );\n\ngl_FragColor = mix(tcolor1,tcolor2 ,opac) + tcolor2*0.2; }\n"
+                fragmentShader: "varying vec3 vNormal;\n\nvarying vec2 vUv;\n\nuniform float opac;\n\n  uniform sampler2D texture1;\n\nuniform sampler2D texture2;\n\nvoid main() {\n\nvec4 tcolor1 = texture2D( texture1, vUv );\n\nvec4 tcolor2 = texture2D( texture2, vUv );\n\ngl_FragColor = mix(tcolor1,tcolor2 ,opac) + tcolor2*0.2; }\n"
                 ,transparent: !0
             })
             shineMats.push(mat)
@@ -165,28 +161,7 @@ window.initHot = function(model){
          
 
 
-        build(info) {
-            /* this.changeMaterial(new THREE.MeshBasicMaterial({ 
-                color: "#00c8af",
-                opacity: 0.4,
-                transparent: !0,
-                polygonOffset: true,
-                //是否开启多边形偏移		//ie不开启时blank也不会闪烁
-                polygonOffsetFactor: -0.9,
-                //多边形偏移因子
-                polygonOffsetUnits: -4.0,
-                //多边形偏移单位  
-            })) 
-          
-            if(!info.objSrc){
-                this.addPlane() 
-                if (info.hasBox)   this.addBox(true)  
-            }else{ 
-                this.addModel(new THREE.Mesh())//暂时创建个空的
-                 
-            }     */
-            
-             
+        build(info) { 
             hotGroup.add(this)
             this.setTitleElem()          
             this.setFromInfo(info)
@@ -350,8 +325,8 @@ window.initHot = function(model){
                     video = media
                 }else{
                     if(!this.info.texSrc)return
-                    var video = $(`<video  controls="controls" loop autoplay x5-playsinline="" webkit-playsinline="true" playsinline="true" controlslist="nodownload"></video>`)[0]
-                    if(window.isEdit) video.src = manage.dealURL(this.info.texSrc);
+                    var video = $(`<video  controls="controls" loop autoplay x5-playsinline="" webkit-playsinline="true" playsinline="true" controlslist="nodownload"  preload="meta" ></video>`)[0]
+                    if(window.isEdit) video.src = manage.dealURL(this.info.texSrc);  //注意,src赋值就会自动加载, preload="meta" 只加载元数据,提高加载速度,否则一开始卡 
                     video.name = this.info.fileName
                 } 
                 
@@ -365,19 +340,23 @@ window.initHot = function(model){
 
                 this.texMedia = video;
                   
-                video.oncanplaythrough = ()=> {
+                video.oncanplaythrough = (e)=> {
                     if(this.texMedia == video){ 
-                        this.material_.map.needsUpdate = !0  
-                        this.update(player) 
-                        //video.play() 
+                        //console.log('oncanplaythrough',e,this.sid)
+                        //this.material_.map.needsUpdate = !0   //当初为何加这句?
+                        //this.update(player) 
+                         
                     } 
                 }
-                
+                 
+                 
                 
                 video.volume = 0
                 video.muted = true
                 video.currentTime = 0
                 
+                
+                if(!window.isEdit) this.material_.opacity = 0.1;
                 this.material_.map = new THREE.VideoTexture(video) 
                 this.material_.map.wrapS = this.material_.map.wrapT = THREE.ClampToEdgeWrapping;
                 
@@ -391,7 +370,7 @@ window.initHot = function(model){
                     this.material_.map = new THREE.Texture();   //texture也不能共用一个,因为有的会有动画,就不一样
                     this.material_.map.image = media //image可以共用
                     this.material_.map.needsUpdate = !0  
-                    
+                    this.material_.opacity = 1
                 }else{
                     if(!this.info.texSrc)return
                     this._loadDones = []
@@ -415,8 +394,8 @@ window.initHot = function(model){
                 /*  this.material_.map.minFilter = THREE.LinearFilter;
                 this.material_.map.magFilter = THREE.LinearFilter; */
                 dealMap(this.material_.map);
-                this.material_.color.set("#FFFFFF");
-                this.material_.opacity = 1
+                this.material_.color.set("#FFFFFF"); 
+                
                 this.material_.needsUpdate = true
             }
              
@@ -463,40 +442,7 @@ window.initHot = function(model){
         
         
         
-        
-        
-        
-        /* 
-        actionType: "common"
-        infoAttribute: {images: [], styleImg: [], model: [], video: [], bgName: "background", iframe: [], title: "11",…}
-        bgName: "background"
-        content: "111"
-        iframe: []
-        images: []
-        model: []
-        styleImg: []
-        title: "11"
-        video: []
-        isSprite: 0
-        link: "https://www.4dmodel.com/SuperTwo/hot_online1/index.html#/?m=EDwn769489868"
-        linkType: "common"
-        noAction: 0
-        order: 4
-        position: {x: -4.238, y: 1.32, z: -0.648}
-        rotation: {x: 0, y: 0.018105110200249575, z: 0}
-        transformAtPanos: {}
-        IO4Kq7494332: {actionTy
-
-
-        depth: 0.08
-        file: "https://super.4dage.com/data/TEST/edit/20200805_172635119.mp4"
-        hasBox: 1
-        height: 0.7289
-        media: ["video"]
-        pos: [-5.562, 1.349, 1.994]
-        qua: [0, 0.70672, 0, 0.70749]
-        sid: "1596619585929"
-        transformAtPanos: {,…} */
+       
      
         preDeal(info, source){// source:来源
         
@@ -896,17 +842,33 @@ window.initHot = function(model){
                 
                 return this.cornerPoints[player.currentPano.id]
             }
-            
-                
-                 
-            
-            
-            
-            
+              
              
         }
         
         
+        
+        
+        getMediaSize(){
+            let size = new THREE.Vector2;
+            if(this.texMedia){
+                if(this.texType == 'photo'){
+                    size.x = this.texMedia.width;
+                    size.y = this.texMedia.height;
+                    //动画的话再变
+                    if(this.info.animateInfo){
+                        size.x /= this.info.animateInfo.cellXcount
+                        size.y /= this.info.animateInfo.cellYcount
+                    }  
+                }else{
+                    size.x = this.texMedia.videoWidth || this.videoWidth
+                    size.y = this.texMedia.videoHeight || this.videoHeight
+                }
+            }
+            return size
+        }
+         
+        
         inSight(){
             //return true
             if(window.isEdit)return true // 太容易move了
@@ -917,8 +879,20 @@ window.initHot = function(model){
                 var cornerPointInfo = this.getCornerPoint(); 
                 var cornerPoint
                 
+                 
+                let min = new THREE.Vector2(5,5)
+                let scaleRatio = 1/player.zoomLevel;
+                
+                //根据media原始大小来调整阈值:  media的原始大小能代表期望显示的大小,如果显示大小的远小于期望大小,就不显示(此时能感受到贴图锯齿严重,清晰度被浪费)。比如如果gif是一个很小的按钮,即使diffLon很小也要显示。缺点:需要用户根据所需上传合适清晰度的图。
+           
+                let size = this.getMediaSize()
+                if(size.x>0){
+                    scaleRatio *= Math.sqrt(size.x * size.y) / 1000
+                }
+                min.multiplyScalar(scaleRatio)
                 
-                if(cornerPointInfo.diffLon < 3  || cornerPointInfo.diffLat < 3 ){
+                
+                if(cornerPointInfo.diffLon < min.x || cornerPointInfo.diffLat < min.y ){
                     //console.log('two far and small')
                     return false
                 }
@@ -943,30 +917,14 @@ window.initHot = function(model){
                 
                 
                 
-        update(player){
-         
-            if(player.mode == 'panorama'){//实时监测播放
-                if(this.texType == "video" && !player.flying){ //飞行时不判断
-                    if(this.visible && !this.pausedByUser && this.inSight()){
-                        this.videoControl(true) 
-                    }else{
-                        this.videoControl(false) 
-                    }
-                }else if(this.info.animateInfo){ 
-                    if(this.visible && this.inSight()){
-                        GifTexDeal.start(this.animation)
-                    }else{
-                        GifTexDeal.stop(this.animation)
-                    } 
-                }
-            }    
-            
+        update(player){  
+              
             if(this.info.isSprite){
                 this.quaternion.copy(player.camera.quaternion)
             }
             
             this.updateScale()
-            
+            this.updateTitle()
         }
                     
         updateScale(e, t) {//自适应调节大小 
@@ -999,7 +957,7 @@ window.initHot = function(model){
         videoControl(state){
             if(this.texType != "video" || !this.material_.map)return
             var video = this.material_.map.image
-           
+            this.shouldPlay = state
             
             if(!state || state == 'stop'){
                 if(!video.paused){
@@ -1009,21 +967,43 @@ window.initHot = function(model){
                
                 if(state == 'stop'){
                     video.currentTime = 0; 
-                }
-                 
-                 
+                }  
             }else if(state){
                 if(video.paused){
                     this.loadVideo(video)
                     video.play()
-                    //console.log("play " + this.sid)                    
+                    this.changeOpaWhenPlay(video)
+                     
+                    console.log("play " + this.sid)                    
                 }                    
                   
             }
         }     
         
         
-                    
+        changeOpaWhenPlay(video){//当播放成功后,恢复为不透明
+            if(isNaN(video.duration)){//未加载好
+                return setTimeout(()=>{
+                    this.changeOpaWhenPlay(video)
+                },100)
+            }
+            const minPlayedTime = Math.min(video.duration/10, 0.1); //到这个时间说明加载成功
+            if(!video.hasInitedOpacity){
+                setTimeout(e=>{ 
+                    if(video.currentTime>minPlayedTime){
+                        this.material_.opacity = 1
+                        video.hasInitedOpacity = true
+                        console.log('changeOpaWhenPlay',this.sid)
+                    }else{
+                        if(!video.paused){//再次尝试
+                            return setTimeout(()=>{
+                                this.changeOpaWhenPlay(video)
+                            },500)
+                        }
+                    }
+                },minPlayedTime*1000+500)
+            }
+        }            
                 
             
             
@@ -1064,46 +1044,6 @@ window.initHot = function(model){
         }
         
         
-        /* setTitleElem(){
-            var root = $("#hot");
-            var title = this.info.title;
-            if(title){
-                if(!this.titleElem){
-                    var elem = $(`<div></div>`)
-                    root.append(elem);
-                    this.titleElem = elem; 
-                } 
-                this.titleElem.text(title)
-                this.setTitleDir()
-            }else{
-                if(this.titleElem){
-                    this.titleElem.remove()
-                    this.titleElem = null;
-                }
-            }
-        } 
-        
-        
-        setTitleDir(){
-            this.titleElem.attr('pos',this.info.titlePos) 
-        }
-         
-        
-         
-        updateTitle(){ 
-            if(!this.titleElem)return;
-            if(!this.visible || this.info.titleShowType == 'unvisible' || 
-                this.info.titleShowType != 'always' && !this.hovered ){ 
-                    return this.titleElem.css("display","none");
-            }
-            var pos = math.getPos2d(this.position, player.camera, $("#player")[0])
-            if(pos.trueSide){//inSight
-                this.titleElem.css( { "left" : `${pos.pos.x}px`,  "top": `${pos.pos.y}px ` });
-                this.titleElem.css("display","block");
-            }else{
-                this.titleElem.css("display","none");
-            } 
-        } */
         
         setHoverState(state){ 
             if(!this.titleElem)return
@@ -1160,17 +1100,40 @@ window.initHot = function(model){
                 (pano)=>{//尽量正对hot
                     let dir = new THREE.Vector3(0,0,1).applyQuaternion(this.quaternion)
                     let dir2 = new THREE.Vector3().subVectors(pano.position, this.position).normalize();
-                    let s = dir.dot(dir2) * 10;
+                    let s = dir.dot(dir2) * 60;
                     //console.log(pano.id + ":" + s)
                     return s
-                } 
-            
+                }  
             );
                 
                 
+            /* var tanD = player.domElement.clientWidth / player.domElement.clientHeight * Math.tan((THREE.Math.degToRad(player.zoomFov/2))) ;
+                var goodDistance =  overlay.width / 2 / tanD;
+                n.push(
+                    function (pano) { //寻找正对着overlay的pano
+                        var overlayDir = new THREE.Vector3(0,0,1).applyQuaternion(overlay.quaternion) 
+                        var v1 = overlayDir//.setY(0);  朝上的话set0会得到0,0,0 无法求angle
+                        var v2 = pano.position.clone().sub(overlay.position)//.setY(0)
+                        var angle = v1.angleTo(v2)
+                        angles[pano.id] = angle; 
+                        angle = -angle * 100 
+                        return  angle
+                    },
+                    function (pano) { //寻找正对着overlay的pano
+                        var dis = pano.position.clone().distanceToSquared(overlay.position)
+                        var goodDistance2 = goodDistance * Math.abs(Math.cos(angles[pano.id]))//考虑了倾斜角度后的最佳距离
+                         
+                        var result =  - 300 * Math.abs(dis-goodDistance2) / goodDistance2 //dis和goodDistance2差距越大分数越低
+                        return result; 
+                    } 
+                ) */    
+                
+                
+                
+                
             var s = t.model.panos.sortByScore(i, n);
-             
-            return s && 0 < s.length && s[0].pano
+            console.log(s) 
+            return s && 0 < s.length && s[0].item
         }
          
         
@@ -1506,6 +1469,7 @@ window.initHot = function(model){
                                         }
                                         if(!finded){
                                             let tex_ = tex.clone();
+                                            tex_.needsUpdate = true //clone后不写这句会黑块
                                             animateTexSrcs[e.info.texSrc].set(e.info.animateInfo, tex_)  
                                             e.material_.map = tex_ 
                                         } 
@@ -1567,7 +1531,15 @@ window.initHot = function(model){
                 
                 this.modelHasRequestLoad = true
             }
-        }            
+        }
+
+
+        dispose(){
+            this.parent.remove(this)
+            this.titleElem && this.titleElem.dispose()
+            delete player.model.hots[this.sid]
+        }
+        
 
     }
     
@@ -1606,7 +1578,7 @@ window.initHot = function(model){
         let count = Hot.maxLoadingCount - loadings.length
         Hot.loadQueue.slice(0, count).forEach(e=>{
             loadings.push(e) 
-            console.log('requestDownload', e.hot.info.texSrc)
+            //console.log('requestDownload', e.hot.info.texSrc)
             e.hot.requestDownload(e.type, ()=>{
                 var i = loadings.indexOf(e)
                 //console.log('requestDownloaded index', i)
@@ -1767,14 +1739,20 @@ window.initHot = function(model){
     
     
     
-    Hot.mobileAutoPlay = function(player){//移动端。不这么写video不会播放 
+    Hot.mobileAutoPlay = function(player){//移动端。不这么写video不会播放 . (2022.11.29: 可为何加了Hot.updateHots之后又会自动播了?https有关?
         if(browser.isMobile()){
-            hotGroup.children.forEach((hot)=>{ 
-                if(!hot.clickToPlayInited && hot.texType == 'video' && hot.material_.map.image.paused){
-                    hot.update(player)
-                    console.log('clickToPlayInited111')
+            hotGroup.children.forEach((hot)=>{  
+                /* if(hot.texType == 'video' && hot.shouldPlay){
+                    console.log(1)
+                } */ 
+                if(!hot.clickToPlayInited && hot.texType == 'video' && hot.material_.map.image.paused && hot.shouldPlay){
+                    //hot.update(player)
+                    //console.log('clickToPlayInited111')
+                    hot.videoControl(true)
+                    
                     if(!hot.material_.map.image.paused){
                         console.log('clickToPlayInited')
+                        hot.changeOpaWhenPlay(video)
                         hot.clickToPlayInited = true 
                     } 
                 }  
@@ -1782,6 +1760,81 @@ window.initHot = function(model){
         }
         
     }
+    
+    Hot.updateHots = function(){ 
+        for(var i in player.model.hots){
+            player.model.hots[i].update(player)
+        }
+        
+        if(player.mode != 'panorama' || !player.ready)return
+        
+        common.intervalTool.isWaiting('updateHots', ()=>{ //延时update,防止卡顿
+            let videoCanPlay = [], aniCanPlay = [];
+            for(var i in player.model.hots){
+                 
+                let hot = player.model.hots[i]
+                
+                 
+                {//实时监测播放
+                    if(hot.texType == "video" && !player.flying){ //飞行时不判断
+                        if(hot.visible && !hot.pausedByUser && hot.inSight()){  //注意edit时insight一直为true
+                            //this.videoControl(true)  
+                            videoCanPlay.push(hot)
+                        }else{
+                            hot.videoControl(false) 
+                        }
+                    }else if(hot.info.animateInfo){ 
+                        if(hot.visible && hot.inSight()){
+                            aniCanPlay.push(hot) 
+                        }else{
+                            GifTexDeal.stop(hot.animation)
+                        } 
+                    }
+                } 
+            }                
+            let filter = (type,max,list,playFun)=>{
+                if(list.length < max){
+                    list.forEach(hot=>type == 'video' ? hot.videoControl(true) : GifTexDeal.start(hot.animation))
+                }else{
+                    let r = common.sortByScore(list,[],[(hot)=>{
+                        let score = 0
+                        var cornerPointInfo = hot.getCornerPoint(); //仅支持漫游模式
+                        let pos2dSum = 0    //越接近0越接近屏幕中心
+                        for(let i=1,j=cornerPointInfo.cornerPoint.length;i<j;i++){//忽略第一个点,那是中心点
+                            var pos2d = math.getPos2d(cornerPointInfo.cornerPoint[i], player.camera, $("#player")[0])
+                            if(pos2d.trueSide){
+                                pos2dSum += Math.abs(pos2d.vector.x);
+                                pos2dSum += Math.abs(pos2d.vector.y);
+                            }else{
+                                pos2dSum += 2-Math.abs(pos2d.vector.x); //感觉决定背面的只有x,所以忽略y?  
+                            }  
+                        }
+                        let area = cornerPointInfo.diffLon * cornerPointInfo.diffLat   //占据面积
+                        score = -pos2dSum * (type == 'video' ? 100 : 10) + area  //gif的面积权重增加些,也就是不一定要靠近中心。因为一般而言gif比较小,起指示作用,即使散落在四角也尽量闪烁;而视频要观看的话一般会凑近居于中心
+                        return score
+                    }])
+                    //console.log(r)
+                    r && r.forEach((e,j)=>{
+                        let hot = e.item
+                        if(j<max){
+                            type == 'video' ? hot.videoControl(true) : GifTexDeal.start(hot.animation)
+                        }else{
+                            type == 'video' ? hot.videoControl(false) : GifTexDeal.stop(hot.animation) 
+                        } 
+                    })
+                }
+            }
+            filter('video',playVideoMax, videoCanPlay);
+            filter('animateInfo',playAniMax, aniCanPlay);
+        
+        
+            
+             
+             
+        },  300) 
+        
+    }
+    
 }
 
 
@@ -1804,4 +1857,9 @@ window.initHot = function(model){
     数据速率为1824kbps,720 *576px   时正常
     所以尽量降到2000以下 同时播放个数最好不超过2个 可能需要将src归零  并延迟加载、不自动播放
     
+    
+    
+    
+    有遇到某张图在ios里显示不出,但在ps重新输出后就可以。这张图的dpi高达500,不知道是否与此有关。
+    
      */

+ 22 - 8
js/edit.js

@@ -160,7 +160,7 @@ EditTools.prototype.init = function() {
             _settings.floorPlanAngle = parseFloat(name) * Math.PI/2  //设置好方向 (0是无效的,将不设置)
              
             
-            if(name != 0){  
+            if(name != 0 && player.ready){  
                 if(player.mode != 'floorplan' && player.modeTran.split('-')!= 'floorplan'){
                     player.flyToMode('floorplan')
                 }else{
@@ -2112,10 +2112,16 @@ Hotpoint.prototype.initListSelect = function(){//热点样式图列表
                 elem.find(".upload").addClass("uploaded")
                 photoList.push(elem) 
                 
+            }else{
+                //尽量使用带ani的
+                if(hot.info.animateInfo){
+                    let elem = photoList.find(elem=>elem[0]._media == media)
+                    if(!elem[0].animateInfo) elem[0].animateInfo = CloneObject(hot.info.animateInfo)
+                }
             } 
         }else if(hot.texType == 'video'){
             var media = hot.texMedia
-            if(!videos.find(u=>media == u)){
+            if(!videos.find(u=>media.src == u.src)){ //if(!videos.find(u=>media == u)){  
                 videos.push(media)
                 
                 var elem = getVideoListItem()
@@ -2919,14 +2925,14 @@ Hotpoint.prototype.useSuitableRatio = function(o={}) {//自适应素材比例
                 w = h = Math.sqrt(Math.abs(s))
             }            
         }else{
-            if(!hot.material_.map)return
+            if(!hot.texMedia)return
             //假设不变总面积
             if(o.setScaleAuto){ 
                 s = defaultS
             }else{
                 s = hot.scale.x * hot.scale.y
             }
-            if(hot.texType == 'photo'){
+            /* if(hot.texType == 'photo'){
                 mediaW = hot.texMedia.width;
                 mediaH = hot.texMedia.height;
                 //动画的话再变
@@ -2941,7 +2947,16 @@ Hotpoint.prototype.useSuitableRatio = function(o={}) {//自适应素材比例
             }else{
                 mediaW = hot.texMedia.videoWidth || hot.videoWidth || 1;
                 mediaH = hot.texMedia.videoHeight || hot.videoHeight || 1;
+            } */
+            let size = hot.getMediaSize()
+           
+            if(size.x == 0){
+                mediaW = mediaH = 1
+            }else{
+                mediaW = size.x; mediaH = size.y; 
             }
+            
+            
             var k = Math.sqrt(Math.abs(s) / (mediaW * mediaH))    
             w = k * mediaW * (hot.scale.x < 0 ? -1 : 1);
             h = k * mediaH * (hot.scale.y < 0 ? -1 : 1);
@@ -3248,9 +3263,8 @@ Hotpoint.prototype.updateNumDisplay = function() {
 //删除热点
 Hotpoint.prototype.removeHot = function(hot ) { 
     //hot.dispose();
-    hot.parent.remove(hot)
-    
-    delete player.model.hots[hot.sid] 
+    hot.dispose() 
+      
     hot.$li.remove();
     this.updateNumDisplay() 
 }
@@ -3613,7 +3627,7 @@ Hotpoint.prototype.saveHot = function() {
         
         that.editDone()
         
-        
+        that._scale[hot.texType] = hot.scale.clone()
     })
 
     return promise

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 19 - 0
js/lib/mediainfo.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 28 - 62
js/main_2020_edit.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 17 - 61
js/main_2020_show.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 79 - 3
js/manage.js