javascript - 添加动画后 Canvas 变得像素化

标签 javascript html html5-canvas

添加动画后, Canvas 变得像素化。我尝试通过添加 context.clearRect(0, 0, canvas.width, canvas.height); 来解决此问题,但它隐藏了前面的段

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x - 40;
var endPercent = 45;
var curPerc = 0,
  mybeg;
var counterClockwise = false;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
var col = ['#000', '#ff0000', '#002bff'];

function animate(current, colr, mybeg) {
  context.beginPath();
  context.moveTo(x, y);
  context.arc(x, y, radius, mybeg, ((circ) * current));
  context.fillStyle = colr;
  context.fill();
  //console.log(x, y, radius, mybeg, ((circ) * current));

  curPerc++;
  if (curPerc <= endPercent) {
    mybeg = 0;
    requestAnimationFrame(function() {
      animate(curPerc / 100, col[0], mybeg)
    });
  } else if (curPerc > 44 && curPerc <= 65) {
    const mybeg1 = ((circ) * 45 / 100);
    requestAnimationFrame(function() {
      animate(curPerc / 100, col[1], mybeg1)
    });
  } else if (curPerc > 64 && curPerc <= 100) {
    const mybeg2 = ((circ) * 65 / 100);
    requestAnimationFrame(function() {
      animate(curPerc / 100, col[2], mybeg2)
    });
  }
}
animate();
<canvas id="myCanvas" height="300" width="300"></canvas>

result

最佳答案

您多次重新绘制相同的弧线。 为了渲染平滑的弧线,我们需要半透明像素(抗锯齿),并且在其他半透明像素上绘制半透明像素将使它们更加不透明。

所以这里的解决方案是清除所有内容并在每一帧重新绘制所有内容。

有多种方法可以做到这一点,但最简单的方法之一可能是每次都渲染完整的饼图,并且仅在其上设置蒙版动画,使用 compositing :

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = x - 40;

var stops = [
//[ begin, end , color ]  
  [  0,  45, '#000' ],
  [ 45,  65, '#ff0000' ],
  [ 65, 100, '#002bff' ]
];
var current = 0;

animate();

function drawFullPie() {
  stops.forEach( function( stop , i) {
    var begin = (stop[0] / 100 ) * Math.PI * 2;
    var end   = (stop[1] / 100 ) * Math.PI * 2;
    context.beginPath();
    context.moveTo( x, y );
    context.arc( x, y, radius, begin, end );
    context.fillStyle = stop[2];
    context.fill();
  } );
}

function drawMask() {
  var begin = 0;
  var end = (current / 100) * Math.PI * 2;
  // Keep whatever is currently painted to the canvas
  // only where our next drawings will appear
  context.globalCompositeOperation = 'destination-in';
  context.beginPath();
  context.moveTo( x, y );
  context.arc( x, y, radius, begin, end );
  context.fill();
  // disable masking
  context.globalCompositeOperation = 'source-over';
}


function animate() {
  // clear at every frame
  context.clearRect( 0, 0, canvas.width, canvas.height );
  // draw the full pie
  drawFullPie();
  // mask it as needed
  drawMask();
  // until complete
  if( current ++ < 100 ) {
    // do it again
    requestAnimationFrame( animate );
  }
}
<canvas id="myCanvas" height="300" width="300"></canvas>

关于javascript - 添加动画后 Canvas 变得像素化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57987187/

相关文章:

javascript - 初学者 Node.JS net.createServer 示例

jquery - 使用 jquery 来防止重新提交表单

javascript - 简单的 SQL 到 PHP 数字递增动画 [Jquery]

python - Ubuntu 中的 header 、用户代理、Url 请求

html - HTML5 中有内容元素吗?

javascript - fabricjs 中的轮廓和边框

javascript - Canvas 响应式媒体屏幕最小宽度 - FabricJS

javascript - 有没有办法进一步简化这些 javascript 函数?

javascript - 将方法添加到方法

javascript - 对 setInterval() 感到困惑