裁剪图像像饼图

时间:2015-03-18 19:38:40

标签: javascript canvas html5-canvas raphael

我想将图像裁剪为另一个图像,如饼图,以创建加载动画。我正在考虑使用raphaeljs,但无法找到有关饼图样式的图像裁剪的任何信息。

以下是示例图片:

开始状态:

Start state

结束状态:

End state

应该是什么样子:

What it should look like

2 个答案:

答案 0 :(得分:7)

只需在图像顶部绘制一个半透明的填充弧(将alpha值调整为令人愉悦的):

var ctx = document.querySelector("canvas").getContext("2d"),
    img = new Image;

img.onload = draw;
img.src = "http://i.imgur.com/hQ5Pljv.png";

function draw(){

  var cx = 157, cy = 159, r = 150,
      pst = 0,
      ang = Math.PI * 2 * (pst/100),
      dlt = 2;
  
  // animate the following part
  (function loop() {
    ctx.drawImage(img, 0, 0);
  
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.arc(cx, cy, r, 0, ang);
    ctx.fillStyle = "rgba(0,0,0,0.33)";  // adjust alpha here
    ctx.fill();

    pst += dlt;
    if (pst <= 0 || pst >= 100) dlt = -dlt;
    ang = Math.PI * 2 * (pst/100);

    requestAnimationFrame(loop)
  })()
}
<canvas width=320 height=320></canvas>

方法二 - 合成

使用两个步骤剪切上面的相同弧以改为使用图像:

  • 绘制弧线,这将是复合数据
  • 更改补偿。模式为source-atop - 下一个图形将替换绘制的弧
  • 中绘制辅助图像
  • 更改补偿。模式为destination-atop - 下一张图将填充所有非像素
  • 中绘制主图像

演示:

var ctx = document.querySelector("canvas").getContext("2d"),
    img1 = new Image, img2 = new Image, cnt=2;

img1.onload = img2.onload = loader;
img1.src = "http://i.imgur.com/hQ5Pljv.png";
img2.src = "http://i.imgur.com/k70j3qp.jpg";

function loader(){if (!--cnt) draw()};                      
function draw(){
  var cx = 157, cy = 159, r = 150,
      pst = 0, ang = Math.PI * 2 * (pst/100), dlt = 2;
  
  // animate the following part
  (function loop() {
    ctx.clearRect(0, 0, 320, 320);   // clear canvas, or set last comp mode to "copy"
    
    // first arc
    ctx.beginPath();
    ctx.moveTo(cx, cy);
    ctx.arc(cx, cy, r, 0, ang);
    ctx.fill();       // this will be comp. basis for the next steps

    // comp mode secondary image
    ctx.globalCompositeOperation = "source-atop";      // replaces filled arc
    ctx.drawImage(img2, 0, 0);

    // comp mode main image
    ctx.globalCompositeOperation = "destination-atop"; // fills all non-pixels
    ctx.drawImage(img1, 0, 0);

    pst += dlt; if (pst <= 0 || pst >= 100) dlt = -dlt; ang = Math.PI * 2 * (pst/100);
    ctx.globalCompositeOperation = "source-over";  // reset comp. mode
    requestAnimationFrame(loop)
  })()
}
<canvas width=320 height=320></canvas>

答案 1 :(得分:1)

您需要一个算法:

  1. 将图像A绘制到画布1
  2. 清除画布2
  3. 在画布2上绘制一个部分圆圈,用于旋转器的当前状态,填充白色
  4. 使用乘法混合模式
  5. 将图像B Blit到画布2上
  6. 使用标准(替换)混合
  7. 将画布2滑动到画布1上

    Canvas 2应包含第二个图像,由您要使用的部分遮罩。将它覆盖在画布1上,只要你正确处理透明度,就应该给你想要的效果。

    假设您的目标浏览器支持SVG,您还可以使用两个带图像背景的SVG圈并轻松完成此操作。