画布将图像放在形状中

时间:2015-06-14 18:50:57

标签: javascript html5-canvas

我正在尝试创建各种各样的旋转轮,其中图像显示为奖品。我重复使用我在网上找到的一个项目,而且我对画布很新,所以我很感激一些帮助。

enter image description here

这就是它的外观,这里将在每个字段中显示一个图像,其角度与车轮相匹配。以下是生成它的代码:

            var outsideRadius = 210;
        var textRadius = 160;
        var insideRadius = 155;

        ctx = canvas.getContext("2d");
        ctx.clearRect(0,0,500,500);

        ctx.strokeStyle = "#943127";
        ctx.lineWidth = 4;

        for(var i = 0; i < 12; i++) {
            var angle = startAngle + i * arc;
            ctx.fillStyle = '#a9382d';
            ctx.beginPath();
            ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
            ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
            ctx.closePath();
            ctx.stroke();
            ctx.fill();
        }

在上面的每个字段中,应显示来自阵列的奖品图像。我在字段中绘制图像时遇到问题。我没有运气就尝试过使用createPattern()。

编辑:添加了jsfiddle:http://jsfiddle.net/46k72m7z/

1 个答案:

答案 0 :(得分:0)

enter image description here

要在其中一个车轮楔块内剪切图像:

见下图。

  1. 计算指定楔形的4个顶点。
  2. 使用context.beginPath开始新路径并转到point0。
  3. 从point0到point1画一条线。
  4. 从point1到point2绘制弧。
  5. 从第2点到第3点画一条线。
  6. 从point3绘制弧线返回point0。
  7. 关闭路径(不需要,只是要格外小心)。
  8. 调用context.clip()创建楔形的剪裁区域。
  9. enter image description here

    以适当的角度绘制图像

    见下图。

    1. 找到楔形的中心点。
    2. 使用context.translate将画布原点设置为该中心点。
    3. 计算从车轮中心(下面的#1点)到楔形中心的角度。
    4. 按计算的角度旋转画布。
    5. 将图像偏移一半的图像宽度&amp;高度。这会使图像在楔形内部以视觉方式居中。
    6. enter image description here

      其他有用信息

      • 使用context.clip设置剪辑时,撤消该剪辑的唯一方法是将剪辑包裹在context.savecontext.restore之间。 (或者调整画布大小,但是当您尝试绘制多个剪切区域时会产生反效果,因为在调整画布大小时会删除所有内容)。

        // save the begininning unclipped context state
        context.save();
        
        ... draw your path
        
        // create the clipping area
        context.clip();
        
        ... draw the image inside the clipping area
        
        // restore the context to its unclipped state
        context.restore();
        
      • 要将图像居中放置在任何位置,找到您希望图像居中的中心点,然后将图像偏移一半的宽度&amp;身高:

        ctx.drawImage( img,-img.width/2, -img.height/2 );
        
      • 计算圆周上的点:

        // given...
        var centerX=150;  // the circle's center
        var centerY=150;
        var radius=25;    // the circle's radius
        var angle=PI/2;   // the desired angle on the circle (angles are expressed in radians)
        
        var x = centerX + radius * Math.cos(angle);
        var y = centerY + radius * Math.sin(angle);
        
      • 效率: path命令会自动从上一个命令的端点画一条线到你新命令的起始点。因此,您可以跳过步骤#3&amp;步骤#5,因为绘制圆弧时将自动绘制线条。

      示例代码和演示:

      &#13;
      &#13;
      var canvas=document.getElementById("canvas");
      var ctx=canvas.getContext("2d");
      var cw=canvas.width;
      var ch=canvas.height;
      function reOffset(){
        var BB=canvas.getBoundingClientRect();
        offsetX=BB.left;
        offsetY=BB.top;        
      }
      var offsetX,offsetY;
      reOffset();
      window.onscroll=function(e){ reOffset(); }
      
      var PI=Math.PI;
      var cx=250;
      var cy=250;      
      var outsideRadius = 210;
      var textRadius = 160;
      var insideRadius = 155;
      var wedgecount=12;
      var arc=Math.PI*2/wedgecount;
      var startAngle=-arc/2-PI/2;
      
      var mm=new Image;
      mm.onload=start;
      mm.src='https://dl.dropboxusercontent.com/u/139992952/multple/mm1.jpg';
      var goldCar=new Image();
      goldCar.onload=start;
      goldCar.src='https://dl.dropboxusercontent.com/u/139992952/multple/carGold.png';
      var redCar=new Image();
      redCar.onload=start;
      redCar.src='https://dl.dropboxusercontent.com/u/139992952/multple/cars1.png';
      var imgCount=2;
      function start(){
        if(++imgCount<2){return;}
        drawWheel();
        for(var i=0;i<wedgecount;i++){
          var img=(i%2==0)?goldCar:redCar;
          if(i==3){img=mm;}
          clipImageToWedge(i,img);
        }
      }
      
      function drawWheel(){
        ctx.clearRect(0,0,500,500);
        ctx.lineWidth = 4;
        for(var i = 0; i < 12; i++) {
          var angle = startAngle + i * arc;
          ctx.fillStyle = '#a9382d';
          ctx.beginPath();
          ctx.arc(cx,cy, outsideRadius, angle, angle + arc, false);
          ctx.arc(cx,cy, insideRadius, angle + arc, angle, true);
          ctx.closePath();
          ctx.stroke();
          ctx.fill();
        }
      }
      
      function clipImageToWedge(index,img){
        var angle = startAngle+arc*index;
        var angle1= startAngle+arc*(index+1);
        var x0=cx+insideRadius*Math.cos(angle);
        var y0=cy+insideRadius*Math.sin(angle);
        var x1=cx+outsideRadius*Math.cos(angle);
        var y1=cy+outsideRadius*Math.sin(angle);
        var x3=cx+outsideRadius*Math.cos(angle1);
        var y3=cy+outsideRadius*Math.sin(angle1);
      
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(x0,y0);
        ctx.lineTo(x1,y1);
        ctx.arc(cx,cy,outsideRadius,angle,angle1);
        ctx.arc(cx,cy,insideRadius,angle1,angle,true);
        ctx.clip();
        var midRadius=(insideRadius+outsideRadius)/2;
        var midAngle=(angle+angle1)/2;
        var midX=cx+midRadius*Math.cos(midAngle);
        var midY=cy+midRadius*Math.sin(midAngle);
      
        ctx.translate(midX,midY);
        ctx.rotate(midAngle+PI/2);
        ctx.drawImage(img,-img.width/2,-img.height/2);
      
        ctx.restore();
      }
      &#13;
      body{ background-color: ivory; }
      #canvas{border:1px solid red; margin:0 auto; }
      &#13;
      <canvas id="canvas" width=500 height=500></canvas>
      &#13;
      &#13;
      &#13;