javascript - 如何在圆形 Canvas 上添加线条

标签 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>

最佳答案

是的,使用globalCompositeOperation,我们可以在 Canvas 上绘制这些线,并将它们用作 mask 来剪切图表。这些线路可能需要进行一些调整才能满足您的需求,但以下内容应该可以让您快速入门:

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>

关于javascript - 如何在圆形 Canvas 上添加线条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47250869/

相关文章:

javascript - 从百分比获取颜色值

css - 随着浏览器变小,css 是否可以调整文本大小

javascript - 在 php 代码中添加 php

javascript新日期创建错误

javascript - jssor 附近的 slider 不透明度即将到来的照片

html - 我正在尝试调整我的图像大小以适合我的导航栏正上方所以它不是那么大?

jquery - 使用 Angular 形式和 chrome 禁用自动填充/自动完成

javascript - 是否可以访问 nodejs 模块的 *loaded* 子级?

html - 如何在我的圆形图像周围放置多色边框?

html - 是否可以添加仅针对特定浏览器显示的 css 样式