View unanswered posts | View active topics It is currently 2022-07-04 10:11



Reply to topic  [ 2 posts ] 
 【求助】link流动效果的卡顿问题 
Author Message
新手上路

Joined: 2017-03-12 18:59
Posts: 6
Post 【求助】link流动效果的卡顿问题
实现如附件,demo中创建100个link后,动画效果开始卡顿了。 是动画的性能问题吗?有办法能做到大规模link(1000个左右)的流畅动画吗?求指导


Attachments:
flowLink.rar [2.64 KiB]
Downloaded 414 times
2017-04-24 9:57
Profile
TWaver开发组
User avatar

Joined: 2014-02-11 8:59
Posts: 575
Post Re: 【求助】link流动效果的卡顿问题
1. 如果link都是直线,建议直接使用icon图标,来展示发光效果;只需要注册一个发光的图标就ok;
参考代码:
Code:
<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8">
   <title>Test Zoom</title>
   <script src="../../lib/twaver.js"></script>
   <script>
      var network;
      var box;
      function load() {
         initNetwork();
         registerImage();
         initNode();
      }
      function addDatas(rowCount, columnCount) {
         var i = 0, j = 0, node, name;
         this.nodeCount = 0;
         for (j = 0; j < rowCount; j++) {
            for (i = 0; i < columnCount; i++) {
               name = "Node:" + j + "," + i;
               node = new twaver.Node(name);
               node.setName(name);
               node.setLocation(30 + i * 200, 30 + j * 200);
               box.add(node);
               this.nodeCount++;
            }
         }

         linkCount = 0;
         var from, to, link;
         var linkList = new twaver.List();
         
         for (j = 0; j < rowCount; j++) {
            for (i = 0; i < columnCount; i++) {
               var color = twaver.Util.randomColor();
               if (i > 0) {
                  from = box.getDatas().get(i + j * rowCount);
                  to = box.getDatas().get(i - 1 + j * rowCount);
                  link = new twaver.Link({
                     clients:{
                        box:box,
                        factor:i,
                        'link.type':'flowLink',
                        'fillColor':color,
                        'shadowColor':color,
                        'tail':10,
                        'tailRadius':2,
                        'tailFactor':1.5,
                     },
                     styles:{
                        'link.color':color,
                        'link.width':1,
                        'link.pattern':[4,2],
                     }
                  },from, to);
                  link.s('link.label.rotatable',[true]).
                  s('icons.names', [['arrow']]).
                  s('icons.position',['from']).
                  s('icons.xoffset',[0.05]).
                  s('link.icons.rotatable',[true,true]);
                  linkList.add(link);
                  linkCount++;
               }
               if (j > 0) {
                  from = this.box.getDatas().get(i + j * rowCount);
                  to = this.box.getDatas().get(i + (j - 1) * rowCount);
                  link = new twaver.Link({
                     clients:{
                        box:box,
                        factor:i,
                        'link.type':'flowLink',
                        'fillColor':color,
                        'shadowColor':color,
                        'tail':10,
                        'tailRadius':2,
                        'tailFactor':1.5,
                     },
                     styles:{
                        'link.color':color,
                        'link.width':1,
                        'link.pattern':[4,2],
                     }
                  },from, to);
                  link.s('link.label.rotatable',[true]).
                  s('icons.names', [['arrow']]).
                  s('icons.position',['from']).
                  s('icons.xoffset',[0.05]).
                  s('link.icons.rotatable',[true,true]);
                  linkList.add(link);
                  linkCount++;
               }
            }
         }
         linkList.forEach(function (link) {
            box.add(link);
         }, this);
         return linkList;
      }

      function initNode() {
         var linkList = addDatas(30,30);
         var animate = new twaver.Animate({
            from: 0.1,
            to: 0.9,
            repeat: Number.POSITIVE_INFINITY,
            // repeat: 1,
            dur: 3000,
            reverse: false,
            onPlay: function() {

            },
            onUpdate: function (value) {
               for(var i = 0;i<linkList.size();i++){
                  linkList.get(i).setStyle('icons.xoffset',value);
               }
            },
            onDone: function () {

            },
            onStop: function () {

            }
         });
         animate.play();
      }

      function registerImage(){
         twaver.Util.registerImage('arrow',{
            "w": 19.2,
            "h": 8,
            "origin": {
               "x": 0,
               "y": 0
            },
            'shadowOffsetX': 0,
            'shadowOffsetY': 0,
            'shadowBlur': 5,
            'shadowColor': 'rgba(255,0,0,1.0)',
            "clip": true,
            "v": [
            {
               "shape": "path",
               "data": "M19.2,4l-7.4-4v1.7H0v4.6h11.8V8L19.2,4z M3.8,5H1.9V3.1h1.9V5z M7.1,5H5.2V3.1h1.9V5z   M10.3,5H8.4V3.1h1.9V5z",
               "fill": "#CBDA00"
            },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.1)',
            //    'shadowColor': 'rgba(255,0,0,0.1)',
            //    r: 3,
            //    cx: 0,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.4)',
            //    'shadowColor': 'rgba(255,0,0,0.4)',
            //    r: 3,
            //    cx: 6,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.6)',
            //    'shadowColor': 'rgba(255,0,0,0.56)',
            //    r: 3,
            //    cx: 10,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.8)',
            //    'shadowColor': 'rgba(255,0,0,0.68)',
            //    r: 3,
            //    cx: 14,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,1.0)',
            //    'shadowColor': 'rgba(255,0,0,0.70)',
            //    r: 3,
            //    cx: 18,
            //    cy: 4
            // },
            ]
         });
      }

      function registerNormalImage(url, name) {
         var image = new Image();
         image.src = url;
         image.onload = function() {
            twaver.Util.registerImage(name, image, image.width, image.height);
            image.onload = null;
            network.invalidateElementUIs();
         };
      }

      function initNetwork() {
         network = new twaver.vector.Network();
         network.setMaxZoom(100);
         network.setMinZoom(0.01);
         box = network.getElementBox();
         // network.getView().style.backgroundColor = 'black';
         main.appendChild(network.getView());
         network.adjustBounds({
            x: 0,
            y: 0,
            width: 1500,
            height: 700
         });
         twaver.Defaults.SHOW_ICON_IN_ATTACHMENT_DIV = true;
      }
   </script>
</head>
<body onload='load();'>
   <div id='main' style="position:relative;"></div>
</body>
</html>

2. 如果Link是曲线,性能方面考虑,可以有以下优化空间:
(1). 发光体是直线,不是曲线;优点:提高性能;缺点:与实际的link轨迹稍微有些偏差;
(2). 控制发光体中圆圈的个数;zoom值小,圆圈个数少;反之,圆圈个数增加;

代码:
Code:
<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8">
   <title>Test Zoom</title>
   <script src="../../lib/twaver.js"></script>
   <script>
      var network;
      var box;
      function load() {
         initNetwork();
         registerImage();
         network.setLinkPathFunction(function(linkUI, defaultPoints) {
            var link = linkUI._element;
            if(link.getClient('link.type') === 'flowLink'){
               var f = linkUI.getFromPoint();
               var t = linkUI.getToPoint();
               var factor = link.getClient('factor') || 1;

               var points = new twaver.List();
               points.add(f);
               points.add(t);

               var lineLength = _twaver.math.getDistance(f, t);
               var offset = -lineLength / 5;
               var m = {
                  x: (f.x + t.x) / 2 + offset ,
                  y: (f.y + t.y) / 2 + offset + Math.pow(-1,factor)*factor * 20
               }

               var cps = new twaver.List();
               cps.add(m);
               cps.add(t);

               points.removeAt(1);
               points.add(cps);
               link.setClient('controlPointX',m.x);
               link.setClient('controlPointY',m.y);
               return points;
            }else{
               return defaultPoints;
            }
         });
         initNode();
      }
      function addDatas(rowCount, columnCount) {
         var i = 0, j = 0, node, name;
         this.nodeCount = 0;
         for (j = 0; j < rowCount; j++) {
            for (i = 0; i < columnCount; i++) {
               name = "Node:" + j + "," + i;
               node = new twaver.Node(name);
               node.setName(name);
               node.setLocation(30 + i * 200, 30 + j * 200);
               box.add(node);
               this.nodeCount++;
            }
         }

         linkCount = 0;
         var from, to, link;
         var linkList = new twaver.List();
         
         for (j = 0; j < rowCount; j++) {
            for (i = 0; i < columnCount; i++) {
               var color = twaver.Util.randomColor();
               if (i > 0) {
                  from = box.getDatas().get(i + j * rowCount);
                  to = box.getDatas().get(i - 1 + j * rowCount);
                  var link = new FlowLink({
                     clients:{
                        box:box,
                        factor:i,
                        'link.type':'flowLink',
                        'fillColor':color,
                        'shadowColor':color,
                        'tail':10,
                        'tailRadius':2,
                        'tailFactor':1.5,
                     },
                     styles:{
                        'link.color':color,
                        'link.width':1,
                        'link.pattern':[4,2],
                     }
                  },from,to);
                  link.setAnimate(3000);
                  link.playAnimate();
                  linkList.add(link);
                  linkCount++;
               }
               if (j > 0) {
                  from = this.box.getDatas().get(i + j * rowCount);
                  to = this.box.getDatas().get(i + (j - 1) * rowCount);
                  var link = new FlowLink({
                     clients:{
                        box:box,
                        factor:i,
                        'link.type':'flowLink',
                        'fillColor':color,
                        'shadowColor':color,
                        'tail':10,
                        'tailRadius':2,
                        'tailFactor':1.5,
                     },
                     styles:{
                        'link.color':color,
                        'link.width':1,
                        'link.pattern':[4,2],
                     }
                  },from,to);
                  link.setAnimate(3000);
                  link.playAnimate();
                  linkList.add(link);
                  linkCount++;
               }
            }
         }
         linkList.forEach(function (link) {
            box.add(link);
         }, this);
         return linkList;
      }

      function initNode() {
         var linkList = addDatas(30,30);
      }

      function registerImage(){
         twaver.Util.registerImage('arrow',{
            "w": 19.2,
            "h": 8,
            "origin": {
               "x": 0,
               "y": 0
            },
            'shadowOffsetX': 0,
            'shadowOffsetY': 0,
            'shadowBlur': 5,
            'shadowColor': 'rgba(255,0,0,1.0)',
            "clip": true,
            "v": [
            {
               "shape": "path",
               "data": "M19.2,4l-7.4-4v1.7H0v4.6h11.8V8L19.2,4z M3.8,5H1.9V3.1h1.9V5z M7.1,5H5.2V3.1h1.9V5z   M10.3,5H8.4V3.1h1.9V5z",
               "fill": "#CBDA00"
            },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.1)',
            //    'shadowColor': 'rgba(255,0,0,0.1)',
            //    r: 3,
            //    cx: 0,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.4)',
            //    'shadowColor': 'rgba(255,0,0,0.4)',
            //    r: 3,
            //    cx: 6,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.6)',
            //    'shadowColor': 'rgba(255,0,0,0.56)',
            //    r: 3,
            //    cx: 10,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,0.8)',
            //    'shadowColor': 'rgba(255,0,0,0.68)',
            //    r: 3,
            //    cx: 14,
            //    cy: 4
            // },
            // {
            //    shape: 'circle',
            //    'fill':'rgba(255,0,0,1.0)',
            //    'shadowColor': 'rgba(255,0,0,0.70)',
            //    r: 3,
            //    cx: 18,
            //    cy: 4
            // },
            ]
         });

      }

      function registerNormalImage(url, name) {
         var image = new Image();
         image.src = url;
         image.onload = function() {
            twaver.Util.registerImage(name, image, image.width, image.height);
            image.onload = null;
            network.invalidateElementUIs();
         };
      }

      function initNetwork() {
         network = new twaver.vector.Network();
         network.setMaxZoom(100);
         network.setMinZoom(0.01);
         box = network.getElementBox();
         // network.getView().style.backgroundColor = 'black';
         main.appendChild(network.getView());
         network.adjustBounds({
            x: 0,
            y: 0,
            width: 1500,
            height: 700
         });
         twaver.Defaults.SHOW_ICON_IN_ATTACHMENT_DIV = true;
      }

      function FlowLink () {
         FlowLink.superClass.constructor.apply(this, arguments);
      }

      twaver.Util.ext(FlowLink, twaver.Link, {
         getVectorUIClass: function() {
            return FlowLinkUI;
         },
         playAnimate:function(dur){
            this.animate.play();
         },
         setAnimate:function(dur) {
            var dur = dur || 1200;
            var self = this;
            var fNode, tNode;

            fNode = self.getFromNode();
            tNode = self.getToNode();

            this.animate = new twaver.Animate({
               from: 0,
               to: 1,
               repeat: Number.POSITIVE_INFINITY,
        // repeat: 1,
        reverse: false,
        // delay:5000,
        dur: dur,
        // interval:3000,
        onPlay: function() {
         // console.log('onPlay');
     },
     onUpdate: function (value) {
          // console.log('onupdate');
          // console.log('onupdate value = %s', Math.ceil(value*10));
          self.setClient('percent', value);
          if(value >= 1) self.setClient('over',true);
          else self.setClient('over',false);
      },
      onDone: function () {
          // console.log('onDone');
      },
      onStop: function () {
          // console.log('onStop');
      }
  });
         }
      });

      function FlowLinkUI () {
         FlowLinkUI.superClass.constructor.apply(this, arguments);
      }

      twaver.Util.ext(FlowLinkUI, twaver.vector.LinkUI, {
         paintBody: function (ctx) {
            var link = this.getElement();
            if(link.getClient('over')) {FlowLinkUI.superClass.paintBody.call(this, ctx); return};
            var fillColor = link.getClient('fillColor');
            var shadowColor = link.getClient('shadowColor');
            var tail = link.getClient('tail');
            var percent = link.getClient('percent') || window.value;
            var paths = this.getLinkPoints();
            var offset = this.getLineLength() * percent;
            var tailFactor = link.getClient('tailFactor') || 1.5;
            var tailRadius = link.getClient('tailRadius') || 2;
     //  var point;
     //  var fromPoint = this._element.getFromAgent().getCenterLocation();
     //  var toPoint = this._element.getToAgent().getCenterLocation();
     //  var point = _twaver.math.calculatePointInfoAlongLine(paths, true, offset, 0).point;
     //  var points = new twaver.List();
     //  var backpoints = new twaver.List();

     //  points.add(fromPoint);
     //  points.add(point);

     //  backpoints.add(fromPoint);
     //  backpoints.add(toPoint);

     //  var rect = _twaver.math.getRect(points);
     //  var backrect = _twaver.math.getRect(backpoints);

     //  console.log("rect.height=%s",rect.height);
     //  if(fromPoint.x < toPoint.x){
     //    ctx.rect(rect.x,rect.y,Math.abs(point.x - fromPoint.x) + 1.5, rect.height < 100 ? 100 : rect.height);
     //  }else{
     //    ctx.rect(point.x - 1.5,rect.y,Math.abs(point.x - fromPoint.x),rect.height < 100 ? 100 : rect.height);
     // }
     // ctx.clip();
     var zoom = this._network.getZoom();
     tail = tail * zoom;
     for (var i = 0, count = tail; i < count; i++) {
        var v = i / count;
        point = _twaver.math.calculatePointInfoAlongLine(paths, true, offset - (count - i)*tailFactor, 0).point;
        ctx.globalAlpha = v * v;
        ctx.shadowBlur = 10;
        ctx.shadowColor = shadowColor;
        ctx.beginPath();
        ctx.fillStyle = fillColor;
        ctx.arc(point.x, point.y, tailRadius, 0, Math.PI * 2, false);
        ctx.fill();
     }
    // for (var i = 0, count = tail; i < count; i++) {
    //   var v = i / count;
    //   point = _twaver.math.calculatePointInfoAlongLine(paths, true, offset - (count - i)*1, 0).point;
    //   ctx.globalAlpha = v * v;
    //   ctx.shadowBlur = 1;
    //   ctx.shadowColor = shadowColor;
    //   ctx.beginPath();
    //   ctx.fillStyle = 'white';
    //   ctx.arc(point.x, point.y, 1, 0, Math.PI * 2, false);
    //   ctx.fill();
    // }

    // for (var i = 0, count = tail; i < count; i++) {
    //   var v = i / count;
    //   point = _twaver.math.calculatePointInfoAlongLine(paths, false, offset - (count - i)*tailFactor, 0).point;
    //   ctx.globalAlpha = v * v;
    //   ctx.shadowBlur = 10;
    //   ctx.shadowColor = shadowColor;
    //   ctx.beginPath();
    //   ctx.fillStyle = fillColor;
    //   ctx.arc(point.x, point.y, tailRadius, 0, Math.PI * 2, false);
    //   ctx.fill();
    // }
    // for (var i = 0, count = tail; i < count; i++) {
    //   var v = i / count;
    //   point = _twaver.math.calculatePointInfoAlongLine(paths, false, offset - (count - i)*1, 0).point;
    //   ctx.globalAlpha = v * v;
    //   ctx.shadowBlur = 1;
    //   ctx.shadowColor = shadowColor;
    //   ctx.beginPath();
    //   ctx.fillStyle = 'white';
    //   ctx.arc(point.x, point.y, 1, 0, Math.PI * 2, false);
    //   ctx.fill();
    // }

    FlowLinkUI.superClass.paintBody.call(this, ctx);
}
});
</script>
</head>
<body onload='load();'>
   <div id='main' style="position:relative;"></div>
</body>
</html>


Attachments:
WX20170426-163520@2x.png
WX20170426-163520@2x.png [ 698.07 KiB | Viewed 4796 times ]
2017-04-26 16:35
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 2 posts ] 

Who is online

Users browsing this forum: No registered users and 12 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron