2017-04-10 28 views
1

我正在用html5畫布創造財富圈的輪子。它與填充樣式顏色工作正常。我想要隨機切片中的兩(2)個不同圖像填充樣式圖案。我如何實現這一目標。如何用不同的圖像填充cannvas圓弧?

這裏是我JS

function rand(min, max) { 
    return Math.random() * (max - min) + min; 
} 

var color = ['#fbc','#f88','#fbc','#f88','#fbc','#f88', "#fbc", "#f67"]; 
var label = ['10', '200', '50', '100', '5', '500', '0', "jPOT"]; 
var slices = color.length; 
var sliceDeg = 360/slices; 
var deg = rand(0, 360); 
var speed = 0; 
var slowDownRand = 0; 
var ctx = canvas.getContext('2d'); 
var width = canvas.width; // size 
var center = width/2;  // center 
var isStopped = false; 
var lock = false; 

function deg2rad(deg) { 
    return deg * Math.PI/180; 
} 

function drawSlice(deg, color) { 
    ctx.beginPath(); 
    ctx.fillStyle = color; 
    ctx.moveTo(center, center); 
    ctx.arc(center, center, width/2, deg2rad(deg), deg2rad(deg+sliceDeg)); 
    ctx.lineTo(center, center); 
    ctx.fill(); 
} 

function drawText(deg, text) { 
    ctx.save(); 
    ctx.translate(center, center); 
    ctx.rotate(deg2rad(deg)); 
    ctx.textAlign = "right"; 
    ctx.fillStyle = "#fff"; 
    ctx.font = 'bold 30px sans-serif'; 
    ctx.fillText(text, 130, 10); 
    ctx.restore(); 
} 

function drawImg() { 
    ctx.clearRect(0, 0, width, width); 
    for(var i=0; i<slices; i++){ 
    drawSlice(deg, color[i]); 
    drawText(deg+sliceDeg/2, label[i]); 
    deg += sliceDeg; 
    } 
} 



document.getElementById("spin").addEventListener("mousedown", function(){ 
    isStopped = true; 
}, false); 

drawImg(); 

document.getElementById("play").addEventListener("mousedown", function(){ 
    (function anim() { 
    deg += speed; 
    deg %= 360; 

    // Increment speed 
    if(!isStopped && speed<3){ 
    speed = speed+1 * 8; 
    } 
    // Decrement Speed 
    if(isStopped){ 
    if(!lock){ 
     lock = true; 
     slowDownRand = rand(0.994, 0.998); 
    } 
    speed = speed>0.2 ? speed*=slowDownRand : 0; 
    } 
    // Stopped! 
    if(lock && !speed){ 
    var ai = Math.floor(((360 - deg - 90) % 360)/sliceDeg); // deg 2 Array Index 
    ai = (slices+ai)%slices; // Fix negative index 
    return alert("You got:\n"+ label[ai]); // Get Array Item from end Degree 
    } 

    drawImg(); 
    window.requestAnimationFrame(anim); 
}()); 
}, false); 

這裏是我的html

<div id="wheel"> 
    <canvas id="canvas" width="300" height="300"></canvas> 
</div> 
<button id="spin">Stop!</button> 
<button id="play">play!</button> 

請幫助我。 Working fiddle is here

+0

你能提供什麼你到底想達到一個靜態的樣機? – Kaiido

+0

其實在我的畫布圈裏他們是8個部分。我想隨機設置兩個不同的@Kaiido圖像作爲模式。 [請找到圖像的附加鏈接](https://ibb.co/cam8vk)我想要什麼。我實現了文字和圓圈,但無法實現模式。你可以查看[我的小提琴也](https://jsfiddle.net/as88425/12j4fvmL/) – Abhishek

回答

1

你可以使用一個屏幕外的畫布,在那裏你會

  • 繪製的第一個圖像,在當前旋轉,
  • 應用於合成它用的一半切片(1/2)
  • 在主屏幕上繪製此屏幕外的畫布,
  • 進行同樣的動作與第二圖像

這裏是概念的基礎上你的代碼醜陋的證明,這是十分可怕的,所以把它改寫請。

// First, load our images 
 
var srcs = ["https://images.pexels.com/photos/172292/pexels-photo-172292.jpeg?w=500&h=500&auto=compress&cs=tinysrgb", 
 
    "https://static.pexels.com/photos/218434/pexels-photo-218434.jpeg?w=500&h=200&auto=compress&cs=tinysrgb" 
 
]; 
 
var loaded = 0; 
 

 
function onload() { 
 
    if (++loaded >= srcs.length) drawImg(); 
 
} 
 
var imgs = srcs.map(s => Object.assign(new Image, { 
 
    onload: onload, 
 
    src: s 
 
})); 
 

 

 
function rand(min, max) { 
 
    return Math.random() * (max - min) + min; 
 
} 
 

 
var color = ['#fbc', '#f88', '#fbc', '#f88', '#fbc', '#f88', "#fbc", "#f67"]; 
 
var label = ['10', '200', '50', '100', '5', '500', '0', "jPOT"]; 
 
var slices = color.length; 
 
var sliceDeg = 360/slices; 
 
var deg = rand(0, 360); 
 
var speed = 0; 
 
var slowDownRand = 0; 
 
var ctx = canvas.getContext('2d'); 
 
var ctx1 = canvas.cloneNode().getContext('2d'); // create an offscreen context 
 
var width = canvas.width; // size 
 
var center = width/2; // center 
 
var isStopped = false; 
 
var lock = false; 
 

 
function deg2rad(deg) { 
 
    return deg * Math.PI/180; 
 
} 
 

 
function drawSlice(deg, color) { 
 
    ctx1.moveTo(center, center); 
 
    ctx1.arc(center, center, width/2, deg2rad(deg), deg2rad(deg + sliceDeg)); 
 
    ctx1.lineTo(center, center); 
 
    ctx1.closePath(); 
 
} 
 

 
function drawText(deg, text) { 
 
    // this should probably be rewritten 
 
    ctx1.save(); 
 
    ctx1.translate(center, center); 
 
    ctx1.rotate(deg2rad(deg)); 
 
    ctx1.textAlign = "right"; 
 
    ctx1.fillStyle = "#fff"; 
 
    ctx1.font = 'bold 30px sans-serif'; 
 
    ctx1.fillText(text, 130, 10); 
 
    ctx1.restore(); 
 
} 
 

 
function drawOnHiddenCanvas(index) { 
 

 
    // we rotate the whole context 
 
    ctx1.translate(canvas.width/2, canvas.height/2); 
 
    ctx1.rotate(deg2rad(deg)); 
 
    ctx1.translate(-canvas.width/2, -canvas.height/2); 
 
    // so even our image is rotated 
 
    ctx1.drawImage(imgs[index], 0, 0); 
 

 
    // new drawn pixels will act as an mask (previous drawn pixels will remain) 
 
    ctx1.globalCompositeOperation = 'destination-atop'; 
 

 
    ctx1.beginPath(); 
 
    // draw one on 2 slices 
 
    for (var i = index; i < slices; i += 2) { 
 
    drawSlice((sliceDeg * i), color[i], ctx); 
 
    } 
 
    ctx1.fill(); // fill only after all your shapes are done 
 

 
    ctx1.globalCompositeOperation = 'source-over'; 
 
    for (var i = index; i < slices; i += 2) { 
 
    drawText((sliceDeg * i) + sliceDeg/2, label[i]); 
 
    } 
 
    // reset the normal matrix 
 
    ctx1.setTransform(1, 0, 0, 1, 0, 0); 
 
    // draw this state on the main canvas 
 
    ctx.drawImage(ctx1.canvas, 0, 0); 
 

 
} 
 

 
function drawImg() { 
 

 
    ctx.clearRect(0, 0, width, width); 
 

 
    drawOnHiddenCanvas(0); 
 

 
    drawOnHiddenCanvas(1); 
 

 
} 
 

 

 

 
document.getElementById("spin").addEventListener("mousedown", function() { 
 
    isStopped = true; 
 
}, false); 
 

 

 
document.getElementById("play").addEventListener("mousedown", function() { 
 
    (function anim() { 
 
    deg += speed; 
 
    deg %= 360; 
 

 
    // Increment speed 
 
    if (!isStopped && speed < 3) { 
 
     speed = speed + 1 * 8; 
 
    } 
 
    // Decrement Speed 
 
    if (isStopped) { 
 
     if (!lock) { 
 
     lock = true; 
 
     slowDownRand = rand(0.994, 0.998); 
 
     } 
 
     speed = speed > 0.2 ? speed *= slowDownRand : 0; 
 
    } 
 
    // Stopped! 
 
    if (lock && !speed) { 
 
     var ai = Math.floor(((360 - deg - 90) % 360)/sliceDeg); // deg 2 Array Index 
 
     ai = (slices + ai) % slices; // Fix negative index 
 
     return alert("You got:\n" + label[ai]); // Get Array Item from end Degree 
 
    } 
 

 
    drawImg(); 
 
    window.requestAnimationFrame(anim); 
 
    }()); 
 
}, false);
#wheel{ 
 
    display:inline-block; 
 
    position:relative; 
 
    overflow:hidden; 
 
} 
 
#wheel:after{ 
 
    content:""; 
 
    background:red; 
 
    border:2px solid white; 
 
    position:absolute; 
 
    top:-7px; 
 
    left:50%; 
 
    width:10px; 
 
    height:10px; 
 
    margin-left:-7px; 
 
    transform: rotate(45deg) 
 
}
<div id="wheel"> 
 
    <canvas id="canvas" width="300" height="300"></canvas> 
 
</div> 
 
<button id="spin">Stop!</button> 
 
<button id="play">play!</button>

+0

感謝它幫助我很多 – Abhishek

+0

我可以把不同的圖像代替標籤 – Abhishek

+0

@Abishek,肯定只是使用drawImage。 – Kaiido

0

嘗試

var img=new Image(); 
img.onload=start; 
img.src="http://www.flooringvillage.co.uk/ekmps/shops/flooringvillage/images/request-a-sample--547-p.jpg"; 
function start(){ 
    var pattern=ctx.createPattern(img,'repeat'); 
    ctx.beginPath(); 
    ctx.arc(50,50,15,0,Math.PI*2); 
    ctx.closePath(); 
    ctx.fillStyle=pattern; 
    ctx.fill(); 
    ctx.stroke(); 
} 
+0

我試過你的代碼,顯示黑色的顏色片。我想隨機片上的兩個不同的圖像 – Abhishek