javascript - Canvas place image in shape -
this question has answer here:
- how fillstyle images in canvas html5 2 answers
i'm trying create spinning wheel of sorts, image displayed prize. i'm reusing project found online, , i'm pretty new canvas, appreciate help.
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/
to clip image inside 1 of wheel-wedges:
see illustration below.
- calculate 4 vertices of specified wedge.
- begin new path
context.beginpath
, move point0. - draw line point0 point1.
- draw arc point1 point2.
- draw line point2 point3.
- draw arc point3 point0.
- close path (not needed, being careful).
- call
context.clip()
create clipping area of wedge.
drawing image @ appropriate angle
see illustration below.
- find centerpoint of wedge.
- set canvas origin centerpoint
context.translate
. - calculate angle wheel center (point#1 below) wedge center.
- rotate canvas calculated angle.
- draw image offset half image's width & height. causes image visually centered inside wedge.
other useful information
when set clip
context.clip
way undo clip wrap clip betweencontext.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
Post a Comment