2015-08-24 92 views
1

我在畫布上繪製和旋轉圖像時遇到問題。基本上,我的方法是創造一個幸運之輪,它允許基於陣列形式的獎品進行定製。這個數組中的數據根據​​索引的數量組成了車輪內的部分。如何在HTML5畫布中繪製和旋轉圖像以及文本

數據非常簡單。它僅僅是這樣

var prizes = [ 
{product:"Axe FX", img: "https://mdn.mozillademos.org/files/5395/backdrop.png"}, 
{product:"Musicman JPX", img: "https://mdn.mozillademos.org/files/5395/backdrop.png"}, 
{product:"Ibanez JEM777V", img: "https://mdn.mozillademos.org/files/5395/backdrop.png"} 
]; 

該數據被用於創建車輪內的段的簡單JSON對象。所以我想放置當前正在爲我工​​作的文本。

繪製輪子時,我分爲兩個主要功能。一個繪製輪子,另一個繪製輪子內的分段。

var drawPartial = function(key, lastAngle, angle) { 
var value = prizes[key].product; 

ctx.save(); 
ctx.beginPath(); 
ctx.lineWidth = 6; 
ctx.fillStyle = segColors[key]; 
ctx.moveTo(centerX, centerY); 
ctx.arc(centerX, centerY, size, lastAngle, angle); 
ctx.lineTo(centerX, centerY); 
ctx.closePath(); 
ctx.stroke(); 
ctx.fill(); 

ctx.save(); 
ctx.translate(centerX, centerY); 
ctx.rotate((lastAngle+angle)/2); 
ctx.fillStyle = "#000"; 
ctx.fillText(value.substr(0,20), size/2 + 20, 0); 
ctx.restore(); 

ctx.restore(); 
} 

var draw = function() { 
var len = prizes.length; 
var currentAngle = outCurrentAngle; 
var lastAngle = currentAngle; 

ctx.strokeStyle = '#000000'; 
ctx.textBaseline = "middle"; 
ctx.textAlign = "center"; 
ctx.font = "1.4em Arial"; 

for(var i = 1; i <= len; i++) { 
    var angle = (Math.PI*2) * (i/len) + currentAngle; 
    drawPartial(i-1, lastAngle, angle); 
    lastAngle = angle; 
} 

ctx.beginPath(); 
ctx.lineWidth = 2; 
ctx.fillStyle = "#fff"; 
ctx.moveTo(centerX, centerY); 
ctx.arc(centerX, centerY, size/7, 0, Math.PI*2); 
ctx.closePath(); 
// ctx.stroke(); 
ctx.fill(); 

ctx.beginPath(); 
ctx.lineWidth = 10; 
ctx.arc(centerX, centerY, size, 0, Math.PI*2); 
ctx.closePath(); 
// ctx.stroke(); 
} 

隨着上面的代碼,我只是簡單地調用draw()函數,輪子和所有的段將相應地創建。但是,我想在每個細分市場中繪製圖像,但我不知道如何使其工作。這是drawPartial()的修改渲染圖像與文字

var drawPartial = function(key, lastAngle, angle) { 
var value = prizes[key].product; 

var img = new Image(); 
img.src = prizes[key].img; 
img.onload = function() { 

    ctx.save(); 
    ctx.drawImage(img,centerX,centerY); 

    ctx.save(); 
    ctx.translate(centerX,centerY); 
    ctx.rotate((lastAngle+angle)/2); 
    ctx.drawImage(img,centerX,centerY); 

    ctx.restore(); 
    ctx.restore(); 


} 

ctx.save(); 
ctx.beginPath(); 
ctx.lineWidth = 6; 
ctx.fillStyle = segColors[key]; 
ctx.moveTo(centerX, centerY); 
ctx.arc(centerX, centerY, size, lastAngle, angle); 
ctx.lineTo(centerX, centerY); 
ctx.closePath(); 
ctx.stroke(); 
ctx.fill(); 

ctx.save(); 
ctx.translate(centerX, centerY); 
ctx.rotate((lastAngle+angle)/2); 
ctx.fillStyle = "#000"; 
ctx.fillText(value.substr(0,20), size/2 + 20, 0); 
ctx.restore(); 

ctx.restore(); 
} 

沿着你可以看到,我根據獎品的對象,它應當在正選賽稱爲每次迭代被稱爲添加圖片和它的SRC()功能,但它永遠不會呈現任何細分中的任何圖像。

我想要的是。在drawPartial()的每次迭代中,我希望將圖像與文本一起放置在段中,並根據角度旋轉。

請幫助...

回答

0

問題

在你img.onload功能你是 「雙重翻譯」 您的centerX & centerY。

ctx.translate(centerX,centerY)將畫布的[0,0]原點移動到[centerX,centerY]。

所以當你ctx.drawImage(img,centerX,centerY)來畫你的形象時,你真的是雙重感動。

因此,您的圖像真的被繪製在[ centerX*2, centerY*2 ]

一個額外的想法:預緊您的圖像

這是最好的預裝的所有圖片。這樣,如果圖像加載失敗,您可以在開始繪製輪子之前採取修復操作。

這裏是如何預加載所有的圖片,以便它們可當你需要吸引他們到你的車輪:

// your incoming JSON 
 
var prizesJSON='[{"product":"Axe FX","img":"https://mdn.mozillademos.org/files/5395/backdrop.png"},{"product":"Musicman JPX","img":"https://mdn.mozillademos.org/files/5395/backdrop.png"},{"product":"Ibanez JEM777V","img":"https://mdn.mozillademos.org/files/5395/backdrop.png"}]'; 
 

 
// the JSON converted to a JS array of objects 
 
var prizes=JSON.parse(prizesJSON); 
 

 
// preload all images 
 
var imageURLs=[]; 
 
var imgs=[]; 
 
var imagesOK=0; 
 
// add prize images into the image preloader 
 
for(var i=0;i<prizes.length;i++){ 
 
    imageURLs.push(prizes[i].img); 
 
} 
 
startLoadingAllImages(imagesAreNowLoaded); 
 
// 
 
function startLoadingAllImages(callback){ 
 
    for (var i=0; i<imageURLs.length; i++) { 
 
    var img = new Image(); 
 
    imgs.push(img); 
 
    img.onload = function(){ 
 
     imagesOK++; 
 
     if (imagesOK>=imageURLs.length) { 
 
     callback(); 
 
     } 
 
    }; 
 
    img.onerror=function(){alert("image load failed");} 
 
    img.src = imageURLs[i]; 
 
    }  
 
} 
 
// 
 
function imagesAreNowLoaded(){ 
 
    // add the img objects to your prizes array objects 
 
    for(var i=0;i<prizes.length;i++){ 
 
    prizes[i].imageObject=imgs[i]; 
 
    // just testing (add the img to the DOM) 
 
    document.body.appendChild(imgs[i]); 
 
    } 
 
    // All images are fully loaded 
 
    // So draw your wheel now! 
 
}
body{ background-color: ivory; }
<h4>Testing: (1) Preload all images, (2) Add imgs to DOM</h4>

我有這個周圍鋪設...

我看到你已經有了繪製輪子的代碼,但我在代碼檔案中有這樣的代碼,所以我在這裏提供它以防萬一它有一些用處。

下面是如何繪製包含獎勵圖像和文本的每個刀片的「財富之輪」的示例。使用的技術包括:

  • context.translate將旋轉點設置到車輪中心。
  • context.rotate將每個刀片旋轉到其所需的角度。
  • context.textAlign & context.textBaseline繪製中心文本。
  • context.globalAlpha減輕每個刀片的顏色,使黑色文字具有良好的對比度。

enter image description here

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var cw=canvas.width; 
 
var ch=canvas.height; 
 

 
var PI=Math.PI; 
 
var PI2=PI*2; 
 
var bladeCount=10; 
 
var sweep=PI2/bladeCount; 
 
var cx=cw/2; 
 
var cy=ch/2; 
 
var radius=130; 
 

 
var img=new Image(); 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house32x32transparent.png"; 
 
function start(){ 
 
    for(var i=0;i<bladeCount;i++){ 
 
     drawBlade(img,'House'+i,cx,cy,radius,sweep*i,sweep); 
 
    }  
 
} 
 

 
function drawBlade(img,text,cx,cy,radius,angle,arcsweep){ 
 
    // save the context state 
 
    ctx.save(); 
 
    // rotate the canvas to this blade's angle 
 
    ctx.translate(cx,cy); 
 
    ctx.rotate(angle); 
 
    // draw the blade wedge 
 
    ctx.lineWidth=1.5; 
 
    ctx.beginPath(); 
 
    ctx.moveTo(0,0); 
 
    ctx.arc(0,0,radius,0,arcsweep); 
 
    ctx.closePath(); 
 
    ctx.stroke(); 
 
    // fill the blade, but keep the color light 
 
    // so the black text has good contrast 
 
    ctx.fillStyle='white'; 
 
    ctx.fill(); 
 
    ctx.fillStyle=randomColor(); 
 
    ctx.globalAlpha=0.30; 
 
    ctx.fill(); 
 
    ctx.globalAlpha=1.00; 
 
    // draw the text 
 
    ctx.rotate(PI/2+sweep/2); 
 
    ctx.textAlign='center'; 
 
    ctx.textBaseline='middle'; 
 
    ctx.fillStyle='black'; 
 
    ctx.fillText(text,0,-radius+50); 
 
    // draw the img 
 
    // (resize to 32x32 so be sure orig img is square) 
 
    ctx.drawImage(img,-16,-radius+10,32,32); 
 
    // restore the context to its original state 
 
    ctx.restore(); 
 
} 
 

 
function randomColor(){ 
 
    return('#'+Math.floor(Math.random()*16777215).toString(16)); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>