如何为wedges的fillPatternImage计算rotationDegree?

时间:2013-08-16 18:45:34

标签: javascript canvas geometry kineticjs trigonometry

我有以下圆圈,由楔子组成。每个楔形都有一个 fillPatternImage 。每个 fillPatternImage 都有一个带居中文本的图像。每个楔子的长度都有所不同。

问题是我需要为每个 fillPatternImage 提供一个旋转度,以便所有文本沿着圆的周长完美对齐。但我不知道给每个 fillPatternImage 的旋转度。

例如,当我将所有 fillPatternImages 的旋转度设置为95°时,短文本会很好地对齐,但是长文本会变得弯曲。

我认为每个 fillPatternImage 的旋转度必须是动态的。但我还没有发现如何。我有楔形尺寸,文字宽度等。

enter image description here

fillPatternImage的代码示例:

imageObj.src = Caption + ".png";
imageObj.onload = function () {
    nts.setFillPatternImage(imageObj);
    nts.setFillPatternRotationDeg(95);
    // nts.setFillPatternOffset(-220, 100);
    nts.setFillPatternX(radio - 15);
    nts.setFillPatternY(leftSide);
    nts.setFillPatternRepeat("no-repeat");
    nts.draw();
}

任何想法都会有很大的帮助。提前谢谢。

1 个答案:

答案 0 :(得分:1)

如何计算动力学楔的fillPatternRotation角度

enter image description here

使用此fillPatternRotation,您的文本将始终在Kinetic wedge中正确旋转:

  fillPatternRotation:Math.PI/2+wedgeAngleDeg*Math.PI/360

其中wedgeAngleDeg是提供给wedge.angleDeg的值:

  angleDeg: wedgeAngleDeg

您还需要设置适当的楔形fillPatternOffset以匹配您的文本图像

enter image description here

您必须将fillPattern水平偏移到图像上文本的中点

假设您的文字在图像上水平居中,则该偏移量为image.width / 2。

 fillPatternOffset X is image.width/2

您必须垂直偏移fillPattern以将图像文本与楔形上的最大宽度对齐。

您可以像这样计算最大的楔形宽度:

 var textTop=radius*Math.sin(wedgeAngleDeg*Math.PI/180);

所以你的fillPatternOffset变为:

 fillPatternOffset: [image.width/2, image.height-textTop],

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

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <div id="container"></div>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.6.0.min.js"></script>
    <script defer="defer">

      var stage = new Kinetic.Stage({
        container: 'container',
        width: 350,
        height: 350
      });

      var img=new Image();
      img.onload=function(){
          start();
      }
      img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/testing.png";

      function start(){

          var layer = new Kinetic.Layer();

          var wedgeAngleDeg=60;
          var radius=100;
          var textTop=radius*Math.sin(wedgeAngleDeg*Math.PI/180);

          var wedge = new Kinetic.Wedge({
            x: stage.getWidth() / 2,
            y: stage.getHeight() / 2,
            radius: radius,
            angleDeg: wedgeAngleDeg,
            fillPatternImage: img,
            fillPatternOffset: [img.width/2, img.height-textTop],
            fillPatternRepeat:"no-repeat", 
            fillPatternRotation:Math.PI/2+wedgeAngleDeg*Math.PI/360,       
            stroke: 'black',
            strokeWidth: 4,
            rotationDeg: 0
          });
          layer.add(wedge);

          wedge.setRotationDeg(-45);

          // add the layer to the stage
          stage.add(layer);

      }
    </script>
  </body>
</html>