如何用不同的图像填充画布圆弧?

时间:2017-04-10 13:35:12

标签: javascript html5 canvas html5-canvas

我正在使用html5画布创建财富圈。它的填充样式颜色很好。我希望随机切片填充样式模式中的两(2)个不同的图像。如何实现这一目标。

这是我的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

2 个答案:

答案 0 :(得分:1)

您可以使用屏幕外的画布,

  • 以当前轮次绘制第一张图片
  • 使用一半切片(1/2)
  • 对其进行合成
  • 在主屏幕上绘制此屏幕外画布,
  • 使用第二张图片重复相同的操作

这是一个基于你的代码的丑陋的概念证明,它真的很难看,所以请重写它。

&#13;
&#13;
// 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);
&#13;
#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)
}
&#13;
<div id="wheel">
    <canvas id="canvas" width="300" height="300"></canvas>
 </div>
 <button id="spin">Stop!</button>
 <button id="play">play!</button>
&#13;
&#13;
&#13;

答案 1 :(得分: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();
}