javascript - Canvas place image in shape -


this question has answer here:

i'm trying create spinning wheel of sorts, image displayed prize. i'm reusing project found online, , i'm pretty new canvas, appreciate help.

enter image description here

this how looks, here image displayed in each of fields, angle match wheel. here code generating it:

            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 = 0; < 12; i++) {             var angle = startangle + * 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();         } 

in each of fields above should displayed image of prize array. im having problems drawing images in fields. i've tried using createpattern() without luck.

edit: added jsfiddle: http://jsfiddle.net/46k72m7z/

enter image description here

to clip image inside 1 of wheel-wedges:

see illustration below.

  1. calculate 4 vertices of specified wedge.
  2. begin new path context.beginpath , move point0.
  3. draw line point0 point1.
  4. draw arc point1 point2.
  5. draw line point2 point3.
  6. draw arc point3 point0.
  7. close path (not needed, being careful).
  8. call context.clip() create clipping area of wedge.

enter image description here

drawing image @ appropriate angle

see illustration below.

  1. find centerpoint of wedge.
  2. set canvas origin centerpoint context.translate.
  3. calculate angle wheel center (point#1 below) wedge center.
  4. rotate canvas calculated angle.
  5. draw image offset half image's width & height. causes image visually centered inside wedge.

enter image description here

other useful information

  • when set clip context.clip way undo clip wrap clip between context.save , context.restore. (or resize canvas, that's counter-productive when you're trying draw multiple clipped regions because content erased when canvas resized).

    // save begininning unclipped context state context.save();  ... draw path  // create clipping area context.clip();  ... draw image inside clipping area  // restore context unclipped state context.restore(); 
  • to center image anywhere, find center point want image centered , draw image offset half it's width & height:

    ctx.drawimage( img,-img.width/2, -img.height/2 ); 
  • calculating points on circumference of circle:

    // given... var centerx=150;  // circle's center var centery=150; var radius=25;    // circle's radius var angle=pi/2;   // desired angle on circle (angles expressed in radians)  var x = centerx + radius * math.cos(angle); var y = centery + radius * math.sin(angle); 
  • an efficiency: path command automatically draw line previous command's endpoint new command's startpoint. therefore, can skip step#3 & step#5 because lines drawn automatically when draw arcs.

example code , demo:

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 = 0; < 12; i++) {      var angle = startangle + * 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();  }
body{ background-color: ivory; }  #canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=500 height=500></canvas>


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -