【问题标题】:How to draw sector (not arc) in fabric js?如何在fabric js中绘制扇区(不是弧线)?
【发布时间】:2017-11-02 01:18:23
【问题描述】:

我正在尝试用fabricjs 绘制半圆(扇区):

$('#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 时,rotationX/Y 会发生变化。

Leaflet http://jieter.github.io/Leaflet-semicircle/examples/semicircle.html 里有东西

如果我能用布料画出这样的半圆就好了。 有没有人尝试过这样做?

提前谢谢你。

【问题讨论】:

标签: javascript canvas svg fabricjs


【解决方案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);

【讨论】:

  • 这是个好主意。最大 fov 将是 180 度?我必须轮换组才能轮换扇区?
  • @imudin07 好吧,我实际上不知道你是如何实现的,但轮换组可能是最简单的
  • 是的,向右旋转组和最大 180 fov 限制没有问题
  • 现在我正在尝试使其透明
  • 它不能是透明的:(
【解决方案2】:

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);

【讨论】:

  • 哇,这正是我想做的!我们也可以使扇区的角度可变吗? arc函数的第三个参数
  • 这是我的新增强版jsfiddle.net/irwinwelsh/3xw691nf/1 它说明了网络摄像头的视角。 Camera({left:10,top:200,radius:500,alfa:20, rotate:90,fill:'rgba(0,200,0,0.3)'});这里的“alfa” - 是扇区的一个角度。
  • 酷它运作良好!谢谢!最后一个问题:如何动态更改“alfa”? jsfiddle.net/3xw691nf/4 在这个演示中,我正在尝试为 alfa 值设置动画,例如旋转
猜你喜欢
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 2014-11-16
  • 1970-01-01
  • 1970-01-01
  • 2018-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多