【问题标题】:How do I create radiating lines using Canvas?如何使用 Canvas 创建辐射线?
【发布时间】:2013-07-01 10:49:29
【问题描述】:

我正在尝试使用 Canvas 或 SVG 创建这样的仪表。我想我会使用 Canvas,除非人们认为使用 SVG 制作会容易得多。我的问题是,使用画布而不使用图像,你会怎么做,或者,是否有可能在仪表外部创建虚线。

谢谢

【问题讨论】:

标签: javascript canvas


【解决方案1】:

如果您的指标不断变化,帆布将是一个不错的选择。

Canvas 擅长快速重绘。

SVG 在重绘方面没有那么快,但如果需要用户交互,那就很好了。

此画布函数将在内圆和外圆之间绘制辐射线:

function radiantLine(centerX,centerY,innerRadius,outerRadius,degrees,linewidth,color){

    var radians=degrees*Math.PI/180;
    var innerX = centerX + innerRadius * Math.cos(radians);
    var innerY = centerY + innerRadius * Math.sin(radians);
    var outerX = centerX + outerRadius * Math.cos(radians);
    var outerY = centerY + outerRadius * Math.sin(radians);

    ctx.beginPath();
    ctx.moveTo(innerX,innerY);
    ctx.lineTo(outerX,outerY);
    ctx.strokeStyle=color;
    ctx.lineWidth=linewidth;
    ctx.stroke();

}

您的仪表的值介于 0-1000 之间。

以下代码可用于将 (0-1000) 范围的值映射到仪表弧的度数 (0-270)。

// scale the guage values (0-1000) is mapped
// into the range of a partial circle (0-270 degree arc)
// value==0 is mapped to 0 degrees on the arc
// value==1000 is mapped to 270 degrees on the arc
var scaledValue=scaleIntoRange(0,1000,0,270,value);


function scaleIntoRange(minActual,maxActual,minRange,maxRange,value){
  var scaled=(maxRange-minRange)*(value-minRange)/(maxActual-minActual)+minRange;
  return(scaled);
}

将传入的值映射到圆上的度数后,您将旋转 135 度以匹配量规上的起始角度(量规上的 0 度大约是圆上的 135 度)

// rotate so guage value==0 starts at 135 degrees on the circle
var degrees=scaledValue+135;

这是代码和小提琴:http://jsfiddle.net/m1erickson/GV8du/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var cx=150;
    var cy=150;
    var innerRadius=50;
    var outerRadius=65;
    var startRadians=135*Math.PI/180;
    var endRadians=405*Math.PI/180;


    for(var value=0;value<=1000;value+=25){

        // scale the guage values (0-1000) 
        // to fit into the range of a partial circle (0-270 degrees)
        var scaledValue=scaleIntoRange(0,1000,0,270,value);
        // rotate so guageValue==0 starts at 135 degrees on the circle
        var degrees=scaledValue+135;

        // draw the radiant line
        // draw thicker/longer line every 250
        if(value%250==0){
            radiantLine(cx,cy,innerRadius,outerRadius,degrees,2,"black");
        }else{
            var shorterLine=(outerRadius-innerRadius)/2;
            radiantLine(cx,cy,innerRadius,outerRadius-shorterLine,degrees,2,"lightgray");
        }
    }


    // draw inner arc of guage
    ctx.beginPath();
    ctx.arc(cx,cy,innerRadius,startRadians,endRadians,false);
    ctx.strokeStyle="black";
    ctx.lineWidth=3;
    ctx.stroke();

    // draw outer arc of guage (for illustration only)
    ctx.beginPath();
    ctx.arc(cx,cy,outerRadius,startRadians,endRadians,false);
    ctx.strokeStyle="lightgray";
    ctx.lineWidth=0.33;
    ctx.stroke();


    function radiantLine(centerX,centerY,innerRadius,outerRadius,degrees,linewidth,color){

        var radians=degrees*Math.PI/180;
        var innerX = centerX + innerRadius * Math.cos(radians);
        var innerY = centerY + innerRadius * Math.sin(radians);
        var outerX = centerX + outerRadius * Math.cos(radians);
        var outerY = centerY + outerRadius * Math.sin(radians);

        ctx.beginPath();
        ctx.moveTo(innerX,innerY);
        ctx.lineTo(outerX,outerY);
        ctx.strokeStyle=color;
        ctx.lineWidth=linewidth;
        ctx.stroke();

    }


    function scaleIntoRange(minActual,maxActual,minRange,maxRange,value){
      var scaled=(maxRange-minRange)*(value-minRange)/(maxActual-minActual)+minRange;
      return(scaled);
    }

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-16
    • 2010-12-14
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    相关资源
    最近更新 更多