【问题标题】:Optimizing performance in fabric.js在 fabric.js 中优化性能
【发布时间】:2017-07-07 09:34:09
【问题描述】:

我正在编写一个小程序来制作有趣的背景纹理。它以我想要的方式工作,除了一件事,它在计算机上非常慢/不稳定,在移动设备上它甚至不显示动画。我想知道是否有更好的方法来实现我正在尝试的目标。

当圆圈的大小很小或屏幕很大(创建很多对象)时,波动会变得特别糟糕。

这里是小提琴:https://jsfiddle.net/cv6cgdja/12/

var canvas = new fabric.StaticCanvas('c')
var height = window.innerHeight
var width = window.innerWidth
var size = 35
var strokeWidth = 2
var strokeColor = '#c9db8e'
var fill = 'transparent'
var x = 0
var y = 0
var groups = []

canvas.setHeight(height)
canvas.setWidth(width)

while(y <= (height + (size*2))){
    while(x <= (width + (size*2))){
    var rotation = 0
    switch(Math.floor(Math.random()*4)){
        case 1: rotation = 90; break;
    }

    var first = new fabric.Circle({
      left: 0,
      top: 0,
      radius: size,
      startAngle: 0,
      endAngle: Math.PI/2,
      fill: fill,
      strokeWidth: strokeWidth,
      stroke: strokeColor
    });    
    var second = new fabric.Circle({
        left: size *2 ,
      top: size*2,
      radius: size,
      startAngle: Math.PI,
      endAngle: -Math.PI/2,
      fill: fill,
      strokeWidth: strokeWidth,
      stroke: strokeColor
    });

    var group = new fabric.Group([ first, second ], {
      left: x - size,
      top: y - size,
      originX: 'center',
      originY: 'center',
      angle : rotation
    });

    groups.push(group)
    x += size * 2
  }
  x = 0
    y += size * 2
}

function draw(){
    groups.forEach(function(g){
    canvas.add(g)
  })
}

draw()

setInterval(function(){
    groups.forEach(function(g){
    var rotation = g.get('angle')
    switch(Math.floor(Math.random()*32)){
        case 1: rotation = '+=90'; break;
        case 1: rotation = '-=90'; break;
    }
    g.animate('angle', rotation, {
      onChange: canvas.renderAll.bind(canvas),
      duration: 250,
      easing: fabric.util.ease.easeOut
    });
  })
}, 800)

【问题讨论】:

    标签: javascript canvas optimization fabricjs


    【解决方案1】:

    给你! 首先很好地使用 startAngle、endAngle。

    第二个主要问题是为每个动画触发一个 renderAll。如果你有 100 个组,canvas/js 不能在短时间内(16ms)容忍 100 个动画。

    在这种情况下的解决方案是让.animate 使动画工作(所以只是改变角度)并且在 onChange 函数中什么都不做。

    然后开始一个单一的动画,具有相同的持续时间,这将使 onChange 函数成为 renderAll。

    如果您使用requestRenderAll,如果已经请求另一个渲染,则此问题将在最新的 beta 版本中自动解决,但我建议始终采取有意识的方法继续,并在必要时触发renderAll

    var canvas = new fabric.StaticCanvas('c')
    var height = window.innerHeight
    var width = window.innerWidth
    var size = 50
    var strokeWidth = 2
    var strokeColor = '#c9db8e'
    var fill = 'transparent'
    var x = 0
    var y = 0
    var groups = []
    
    canvas.setHeight(height)
    canvas.setWidth(width)
    while(y <= (height + (size*2))){
    	while(x <= (width + (size*2))){
      	var rotation = 0
        switch(Math.floor(Math.random()*4)){
        	case 1: rotation = 90; break;
        }
      
      	var first = new fabric.Circle({
          left: 0,
          top: 0,
          radius: size,
          startAngle: 0,
          endAngle: Math.PI/2,
          fill: fill,
          strokeWidth: strokeWidth,
          stroke: strokeColor
        });    
        var second = new fabric.Circle({
      		left: size *2 ,
          top: size*2,
          radius: size,
          startAngle: Math.PI,
          endAngle: -Math.PI/2,
          fill: fill,
          strokeWidth: strokeWidth,
          stroke: strokeColor
        });
        
        var group = new fabric.Group([ first, second ], {
          left: x - size,
          top: y - size,
          originX: 'center',
          originY: 'center',
          angle : rotation
        });
    		
        groups.push(group)
      	x += size * 2
      }
      x = 0
    	y += size * 2
    }
    
    function draw(){
      canvas.renderOnAddRemove = false;
    	groups.forEach(function(g){
      	canvas.add(g)
      })
      canvas.renderOnAddRemove = true;
      canvas.renderAll();
    }
    
    draw();
    
    setInterval(function(){
        groups.forEach(function(g){
        var rotation = g.get('angle')
        switch(Math.floor(Math.random()*32)){
            case 1: rotation = '+=90'; break;
            case 0: rotation = '-=90'; break;
        }
        g.animate('angle', rotation, {
          onChange: () => {},
          duration: 250,
          easing: fabric.util.ease.easeOut
        });
      })
      groups[0].animate('nothing', 1000, {
        duration: 250,
        onChange: canvas.renderAll.bind(canvas)
      });
    }, 500)
    <script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.13/fabric.js"></script>
    <canvas id='c'></canvas>
    <div>
    Hi there
    </div>

    【讨论】:

      猜你喜欢
      • 2012-01-19
      • 2013-03-17
      • 2016-05-14
      • 2011-10-17
      • 2014-01-08
      • 1970-01-01
      • 2017-06-02
      • 2013-03-31
      • 2018-07-19
      相关资源
      最近更新 更多