如何在结构js中绘制扇区(而不是弧形)?

时间:2017-06-01 03:53:02

标签: javascript canvas svg fabricjs

我正在尝试使用fabricjs绘制semecircle(扇区):

$('#button').click(function(){
  fov+=10;
  drawSector(fov);

});

$('#button2').click(function(){
    fov-=10;
  drawSector(fov);
});


var w=500,h=500;
var R = 100;
var fov = 75.0;
var lastFOV;

var ele = {
    center: {x: 0.5, y:0.5},
    focal: {x: 0.5, y: 0.5},
    radius: 0.6,
    transform: {
        rotate: 0,
        translate: {
            x: 0,
            y: 0,
        },
        scale: {
            x: 1,
            y: 1,
        }
    },
    stops: [
        {offset: '0', color: "purple",alpha:'0.75'},
        {offset: '0.9', color: "transparent",opacity:'0'}
    ]
};

var tr_str = "rotate("+ele.transform.rotate+",0.5,0.5) translate("+ele.transform.translate.x*w+","+ele.transform.translate.y*h+") scale("+ele.transform.scale.x+","+ele.transform.scale.y+")";
var tr_matrix = fabric.parseTransformAttribute(tr_str);

var rg = {
    type: 'radial',
    x1: ele.center.x,
    y1: ele.center.y,
    r1: 0,
    x2: ele.focal.x,
    y2: ele.focal.y,
    r2: R,
    //transformMatrix: [1,0,0,2,0,0],
    //gradientTransform: [1,0,0,2,0,0],
    gradientTransform: tr_matrix,
    colorStops: (function(){
        var color_stops = {};
        for(var i=0;i<ele.stops.length;i++){
            color_stops[ele.stops[i].offset] = ele.stops[i].color;
        }
        return color_stops;
    })()
};

var HideControls = {
                'tl':false,
                'tr':false,
                'bl':false,
                'br':false,
                'ml':false,
                'mt':false,
                'mr':false,
                'mb':false,
                'mtr':true
            };

    var canvas = new fabric.Canvas('canvas1');
    canvas.setWidth(w);
    canvas.setHeight(h);

var x,y,my,startPoints;
var sector;
var rotationAngle = 0;
drawSector(fov);

function drawSector(fov){
        $('#fov').html("FOV = "+fov);
    x = Math.cos(fov*Math.PI/180.0)*R;
    y = Math.sin(fov*Math.PI/180.0)*R;
    my = -Math.sin(fov/2.*Math.PI/180.0)*R/2.;
    startPoints = [
        {x: 0, y: 0},
        {x: R, y: 0},
        {x: x, y: y}
      ];

        if(sector) {
        rotationAngle = sector.angle;
      canvas.remove(sector);
    }

    sector = new fabric.Polygon(startPoints,{
      left: w/2,
      top: h/2,
      originX:'left',
      originY:'top',
      centeredRotation:false,
      hasBorders:false,
      lockMovementX:true,
      lockMovementY:true,
      rotatingPointOffset:my,
      width: R,
      height: R
    });
    sector.setControlsVisibility(HideControls);
    sector.setGradient('fill', rg);
    rotationAngle = rotationAngle==0?-fov/2:rotationAngle-(fov-lastFOV)/2;
    sector.setAngle(rotationAngle);
    canvas.add(sector);
    lastFOV = fov;
}

https://jsfiddle.net/2v0es4xh/35/

但是当FOV大于90时,旋转X / Y正在改变。

Leaflet http://jieter.github.io/Leaflet-semicircle/examples/semicircle.html

中有一些内容

如果我可以使用面料画这样的半圆会很棒。 是否有人试图这样做?

提前谢谢。

2 个答案:

答案 0 :(得分:1)

尝试这样的事情:http://jsfiddle.net/qoadhrop/

在主圆的顶部设置两个半圆,为您提供这种“半径”效果

HTML:

<canvas id="c" width="300" height="300"></canvas>

JS:

var canvas  = new fabric.Canvas('c');

var c1 = new fabric.Circle({
    radius: 50,
    left: 100,
    top: 100,
    stroke: '#000',
    strokeWidth: 1,
    fill: 'lightblue',
    opacity: 0.8
});

var c2 = new fabric.Circle({
    radius: 50,
    left: 100,
    top: 100,
    startAngle: 0,
    endAngle: Math.PI,
    stroke: '#000',
    strokeWidth: 1,
    fill: 'red'
});
c2.setAngle(45);

var c3 = new fabric.Circle({
    radius: 50,
    left: 100,
    top: 100,
    flipX: true,
    startAngle: 0,
    endAngle: Math.PI,
    stroke: '#000',
    strokeWidth: 1,
    fill: 'red'
});
c3.setAngle(-45);

canvas.add(c1);
canvas.add(c2);
canvas.add(c3);

答案 1 :(得分:1)

A。Lau的先前代码无效。因此,这是我的简单实现。您可以绘制任何扇区并旋转它们。在https://jsfiddle.net/irwinwelsh/rn9emuqd/

尝试直播示例
 var canvas = new fabric.Canvas('c');

 function arc(left,top,radius,angle, rotate) {

 var coeff = Math.PI/180;

  var xshift = Math.sqrt(2) * radius * ( Math.cos(45 * coeff) - Math.cos((45 + rotate) * coeff));
  var yshift = Math.sqrt(2) * radius * ( Math.sin(45 * coeff) - Math.sin((45 + rotate) * coeff));

  left = left + xshift;
  top = top + yshift;

  var width = 2 * radius * Math.sin((angle/2) * coeff);
  var height = radius * Math.cos((angle/2) * coeff);  

  var triangle = new fabric.Triangle({
    width: width, 
    height: height, 
    left: left + width/2,
    top: top,
    fill: 'rgba(0,200,0,0.3)',
    angle: 180,
  });    

  var circle = new fabric.Circle({
    radius: radius, 
    fill: 'rgba(0,200,0,0.3)',
    left: left - radius,
    top: top - radius,
    startAngle: (270 - angle/2) * coeff,
    endAngle: (270 + angle/2) * coeff,
    angle: 0,
  });


  var group = new fabric.Group([circle,triangle],{
    angle : rotate,
  });

  return group;    
}   

var sector = arc(100,200,200,30, 30);
canvas.add(sector);