如何在圆形画布中添加线条

时间:2017-11-12 16:03:07

标签: javascript html css canvas

我使用css,javascript和html创建了一个进度条(左图)。

但我想在进度条中添加白色分色器(右图)。我尝试了很多方法,但无法存档。任何人都可以帮我修复它。

DEMO

enter image description here

var el = document.getElementById('graph'); // get canvas

var options = {
    percent:  el.getAttribute('data-percent') || 45,
    size: el.getAttribute('data-size') || 220,
    lineWidth: el.getAttribute('data-line') || 25,
    rotate: el.getAttribute('data-rotate') || 200
}

var canvas = document.createElement('canvas');
var span = document.createElement('span');
span.textContent = el.getAttribute('data-text') + ' $';
    
if (typeof(G_vmlCanvasManager) !== 'undefined') {
    G_vmlCanvasManager.initElement(canvas);
}

var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;

el.appendChild(span);
el.appendChild(canvas);

ctx.translate(options.size / 2, options.size / 2); // change center
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg

//imd = ctx.getImageData(0, 0, 240, 240);
var radius = (options.size - options.lineWidth) / 2;

var drawCircle = function(color, lineWidth, percent) {
		percent = Math.min(Math.max(0, percent || 1), 1);
		ctx.beginPath();
		ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
		ctx.strokeStyle = color;
        ctx.lineCap = 'square'; // butt, round or square
		ctx.lineWidth = lineWidth
		ctx.stroke();
};

drawCircle('#bbbec3', options.lineWidth, 100 / 100);
drawCircle('#c21b17', options.lineWidth, options.percent / 100);
.chart {
    position: relative;
    width: 220px;
    text-align: center;
}
canvas {
    display: block;
    position:absolute;
    top:0;
    left:0;
}
span {
    color:#555;
    display:block;
    line-height:220px;
    text-align:center;
    width:220px;
    font-family:sans-serif;
    font-size:30px;
    font-weight:100;
    margin-left:5px;
} 
.centerbox{
        display: inline-block;
    bottom: 0;
    width: 45px;
    position: absolute;
    z-index: 1;
    margin-left: -50px;
    border-bottom: 35px solid #fff;
    border-left: 30px solid transparent;
    border-right: 30px solid transparent;
}
<div class="chart" id="graph" data-text="123123" data-percent="55"><label class="centerbox"><i class="fa fa-usd" aria-hidden="true" style="padding-top: 10px;position: absolute;"></i></label></div>

1 个答案:

答案 0 :(得分:0)

是的,使用globalCompositeOperation我们可以在画布上绘制这些线条并将它们用作剪辑图表的蒙版。这些线可能需要一些调整以满足您的需求,但以下内容应该为您提供一个快速启动:

var drawMask = function(numberOfLines,clipLineWidth) {
  ctx.save();
  ctx.beginPath();
  // Revert the rotation already set:
  ctx.rotate( -1 * options.rotate * Math.PI / 180 );
  // This is where the magic happens:
  ctx.globalCompositeOperation = 'destination-out';
  ctx.lineWidth =  clipLineWidth;
  for (var i = 0; i < numberOfLines; i++) {
    ctx.rotate( Math.PI / (numberOfLines / 2) );
    ctx.moveTo(0, 0);
    ctx.lineTo(0, 120);
    ctx.stroke();
  }
  ctx.restore();
}
drawMask(8, 4);

要了解这与代码一起显示的方式,请参阅this fiddle或以下工作示例:

var el = document.getElementById('graph'); // get canvas

var options = {
    percent:  el.getAttribute('data-percent') || 45,
    size: el.getAttribute('data-size') || 220,
    lineWidth: el.getAttribute('data-line') || 25,
    rotate: el.getAttribute('data-rotate') || 200
}

var canvas = document.createElement('canvas');
var span = document.createElement('span');
span.textContent = el.getAttribute('data-text') + ' $';
    
if (typeof(G_vmlCanvasManager) !== 'undefined') {
    G_vmlCanvasManager.initElement(canvas);
}

var ctx = canvas.getContext('2d');
canvas.width = canvas.height = options.size;

el.appendChild(span);
el.appendChild(canvas);

ctx.translate(options.size / 2, options.size / 2); // change center
ctx.rotate((-1 / 2 + options.rotate / 180) * Math.PI); // rotate -90 deg

//imd = ctx.getImageData(0, 0, 240, 240);
var radius = (options.size - options.lineWidth) / 2;

var drawCircle = function(color, lineWidth, percent) {
		percent = Math.min(Math.max(0, percent || 1), 1);
		ctx.beginPath();
		ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
		ctx.strokeStyle = color;
        ctx.lineCap = 'square'; // butt, round or square
		ctx.lineWidth = lineWidth
		ctx.stroke();
};

drawCircle('#bbbec3', options.lineWidth, 100 / 100);
drawCircle('#c21b17', options.lineWidth, options.percent / 100);

// Let's draw a mask over the chart:
var drawMask = function(numberOfLines,clipLineWidth) {
  ctx.save();
  ctx.beginPath();
  // Revert the rotation already set:
  ctx.rotate( -1 * options.rotate * Math.PI / 180 );
  // This is where the magic happens:
  ctx.globalCompositeOperation = 'destination-out';
  ctx.lineWidth =  clipLineWidth;
  for (var i = 0; i < numberOfLines; i++) {
    ctx.rotate( Math.PI / (numberOfLines / 2) );
    ctx.moveTo(0, 0);
    ctx.lineTo(0, 120);
    ctx.stroke();
  }
  ctx.restore();
}
drawMask(8, 4);
.chart {
    position: relative;
    width: 220px;
    text-align: center;
}
canvas {
    display: block;
    position:absolute;
    top:0;
    left:0;
}
span {
    color:#555;
    display:block;
    line-height:220px;
    text-align:center;
    width:220px;
    font-family:sans-serif;
    font-size:30px;
    font-weight:100;
    margin-left:5px;
} 
.centerbox{
        display: inline-block;
    bottom: 0;
    width: 45px;
    position: absolute;
    z-index: 1;
    margin-left: -50px;
    border-bottom: 35px solid #fff;
    border-left: 30px solid transparent;
    border-right: 30px solid transparent;
}
<div class="chart" id="graph" data-text="123123" data-percent="55"><label class="centerbox"><i class="fa fa-usd" aria-hidden="true" style="padding-top: 10px;position: absolute;"></i></label></div>