在Fabric.js中创建山谷文本(带曲线的文本)

时间:2013-11-01 12:28:45

标签: javascript canvas fabricjs

我正在使用Fabric.js在CANVAS上显示文字..效果很好并显示如下文字

enter image description here

我想要实现的是文字效果,如下所示

enter image description here

而不是简单..是否可以这样做?

这是我的代码..

<!DOCTYPE html>    
<head>
    <meta charset="utf-8">
    <title>fabric.js-simple text display</title>

    <!-- Get version 1.1.0 of Fabric.js from CDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.1.0/fabric.all.min.js" ></script>

    <!-- Get the highest 1.X version of jQuery from CDN. Required for ready() function. -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 

<body>
        <!-- A canvas tag is required or 
             Fabric.js doesn't know where to draw. -->
        <canvas id="c" style="border:1px solid black;" ></canvas>
</body>

<script>
    // Place script tags at the bottom of the page.
    // That way progressive page rendering and 
    // downloads are not blocked.

    // Run only when HTML is loaded and 
    // DOM properly initialized (courtesy jquery)
    $(function () {

        // Obtain a canvas drawing surface from fabric.js
        var canvas = new fabric.Canvas('c');

        // Create a text object. 
        // Does not display it-the canvas doesn't 
        // know about it yet.
        var hi = new fabric.Text('hello, world.', {
            left: canvas.getWidth() / 2,
            top: canvas.getHeight() / 2     
        });

        // Attach it to the canvas object, then (re)display
        // the canvas.  
        canvas.add(hi);

    });
</script>

</head>


</html>

3 个答案:

答案 0 :(得分:2)

还要看这个小提琴。 http://jsfiddle.net/swesh/c7s9x2fh/199/

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

var text= "Happy Birthday"
var headingText = [];
var startAngle = -58;
var textLength = text.length;

var r = getTranslationDistance(text);
var j=-1;
var angleInterval = 116/textLength;
for(var iterator=(-textLength/2), i=textLength-1; iterator<textLength/2;iterator++,i--){

var rotation = 90-(startAngle+(i)*angleInterval) ;

headingText.push(new fabric.IText(text[i], {
angle : j*((startAngle)+(i*angleInterval)),
shadow: 'rgba(0,0,0,0.5) 5px 5px 5px',
fontSize:28,
    left: (r)*Math.cos((Math.PI/180)*rotation),
    top: (r)*Math.sin((Math.PI/180)*rotation)

}));

}

var group2 = new fabric.Group(headingText, { left: 0, top: canvas.height/2,fontFamily: 'Arial',  strokeWidth: 1,

    strokeStyle:"#fff"});
    canvas.add(group2);


   function getTranslationDistance(text){
   var boundingRectangle = $("<div id='tempdiv' style='display:table-cell;font- family:Arial; font-size:28px;'>"+text+"</div>").appendTo("#main");

var translationDistance = $(boundingRectangle).width();
$(boundingRectangle).remove();
return translationDistance;
}

答案 1 :(得分:1)

我还没有找到任何会生成山谷文本的结构js库函数。 但您可以使用http://tympanus.net/Development/Arctext/.Hope尝试弯曲文本,这可以帮助您 enter image description here

要在HTML5画布上使用弯曲文本,请转到此处 http://www.html5canvastutorials.com/labs/html5-canvas-text-along-arc-path/

答案 2 :(得分:1)

我在这里得到了一个有效的例子Demo:http://jsfiddle.net/NHs8t/ 感谢大家的帮助

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title> - jsFiddle demo</title>

  <script type='text/javascript' src='//code.jquery.com/jquery-1.9.1.js'></script>



  <link rel="stylesheet" type="text/css" href="/css/result-light.css">



      <script type='text/javascript' src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.2.0/fabric.all.min.js"></script>


  <style type='text/css'>
    canvas {  border:1px solid #000;     }
.controles {  margin:50px 0;   }
  </style>



<script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
/***** Required : http://fabricjs.com *****/
var CurvedText = (function() {

    /**
    * Constructor
    * @method curvedText
    * @param canvas
    * @param {object} options
    */
    function CurvedText( canvas, options ){

      // Options
      this.opts = options || {};
      for ( var prop in CurvedText.defaults ) {
         if (prop in this.opts) { continue; }
         this.opts[prop] = CurvedText.defaults[prop];
      }

      this.canvas = canvas;
      this.group = new fabric.Group([], {selectable: this.opts.selectable});
      this.canvas.add( this.group ) ;
      this._forceGroupUpdate();
      this.setText( this.opts.text );
    }


    /**
    * @method set
    * @param {string} param
    * @param value
    * @return false if the param name is unknown
    */
    CurvedText.prototype.set = function( param, value ) {
      if ( this.opts[param] !== undefined ) {
        this.opts[param] = value;
        if ( param === 'fontSize' || param === 'fontWeight' ) {
          this._setFontStyles();
        }
        if ( param === 'selectable' ) {
          this.group.selectable = value;
        }
        if ( param === 'angle' ) {
          this._forceGroupUpdate();
        }

        this._render();
        return true;
      } else {
        return false;
      }
    };

    /**
    * @method get
    * @param {string} param
    * @return value of param, or false if unknown
    */
    CurvedText.prototype.get = function( param ) {
      this._render();
      if ( this.opts[param] !== undefined ) {
        return this.opts[param];
      } else {
        return false;
      }
    };

    /**
    * @method getParams
    * @return {object} value of every options
    */
    CurvedText.prototype.getParams = function() {
      this._render();
      return this.opts;
    };

    /**
    * Center the group in canvas
    * @method center
    * @return {object} with top and left
    */
    CurvedText.prototype.center = function() {
      this.opts.top = this.canvas.height / 2;
      this.opts.left = this.canvas.width / 2;
      this._render();
      return { top:this.opts.top, left:this.opts.left };
    };

    /**
    * Remove all letters from canvas
    * @method remove
    */
    CurvedText.prototype.remove = function() {
      var size = this.group.size();
      for ( var i=size; i>=0; i-- ){
        this.group.remove( this.group.item(i) );
      }
      this.canvas.renderAll();
    };

    /**
    * Used to change the text
    * @method setText
    * @param {string} newText
    */
    CurvedText.prototype.setText = function( newText ) {

      while ( newText.length !== 0 && this.group.size() >= newText.length ) {
        this.group.remove( this.group.item( this.group.size()-1 ) );
      }

      for ( var i=0; i<newText.length; i++ ){
        if ( this.group.item(i) === undefined ){
          var letter = new fabric.Text(newText[i], {
            selectable: true
          });
          this.group.add( letter );
        }
        else{
          this.group.item(i).text = newText[i];
        }
      }
      this.opts.text = newText;
      this._setFontStyles();
      this._render();
    };

    /**
    * Update font size and weight
    * @private
    * @method _setFontStyles
    */
    CurvedText.prototype._setFontStyles = function() {
      for ( var i=0; i<this.group.size(); i++ ){
        this.group.item(i).setFontSize( this.opts.fontSize );
        this.group.item(i).fontWeight = this.opts.fontWeight ;
      }
    };

    /**
    * Force update group scale and angles
    * @private
    * @method _forceGroupUpdate
    */
    CurvedText.prototype._forceGroupUpdate = function() {
      this.group.setAngle( this.opts.angle );
      this.group.scaleX = this.opts.scaleX;
      this.group.scaleY = this.opts.scaleY;
      this._render();
    };


    /**
    * calculate the position and angle of each letter
    * @private
    * @method _render
    */
    CurvedText.prototype._render = function() {
        var curAngle=0,angleRadians=0, align=0;

        // Object may have been moved with drag&drop
        if ( this.group.hasMoved() ) {
          this.opts.top = this.group.top;
          this.opts.left = this.group.left;
        }
        this.opts.angle = this.group.getAngle();
        this.opts.scaleX = this.group.scaleX;
        this.opts.scaleY = this.group.scaleY;


        // Text align
        if ( this.opts.align === 'center' ) {
          align = ( this.opts.spacing / 2) * ( this.group.size() - 1) ;
        } else if ( this.opts.align === 'right' ) {
          align = ( this.opts.spacing ) * ( this.group.size() - 1) ;
        }

        for ( var i=0; i<this.group.size(); i++) {
          // Find coords of each letters (radians : angle*(Math.PI / 180)
          if ( this.opts.reverse ) {
            curAngle = (-i * parseInt( this.opts.spacing, 10 )) + align;
            angleRadians = curAngle * (Math.PI / 180);
            this.group.item(i).set( 'top', (Math.cos( angleRadians ) * this.opts.radius) );
            this.group.item(i).set( 'left', (-Math.sin( angleRadians ) * this.opts.radius) );
          } else {
            curAngle = (i * parseInt( this.opts.spacing, 10)) - align;
            angleRadians = curAngle * (Math.PI / 180);
            this.group.item(i).set( 'top', (-Math.cos( angleRadians ) * this.opts.radius) );
            this.group.item(i).set( 'left', (Math.sin( angleRadians ) * this.opts.radius) ) ;
          }
          this.group.item(i).setAngle( curAngle );
        }

        // Update group coords
        this.group._calcBounds();
        this.group._updateObjectsCoords();
        this.group.top = this.opts.top;
        this.group.left = this.opts.left;
        this.group.saveCoords();

        this.canvas.renderAll();
    };



    /**
    * Default options
    */
    CurvedText.defaults = {
      top: 0,
      left: 0,
      scaleX: 1,
      scaleY: 1,
      angle: 0,
      spacing: 20,
      radius: 50,
      text: 'Curved text',
      align: 'center',
      reverse: false,
      fontSize: 20,
      fontWeight: 'normal',
      selectable: true
    };

    return CurvedText;
})();

$(document).ready(function(){
  canvas = new fabric.Canvas('c');

  Example = new CurvedText( canvas, {angle:50} );
  Example.center();


  $('.radius, .spacing, .align, .fontSize').change(function(){
    Example.set( $(this).attr('class'), $(this).val() ) ;    
  });
  $('.reverse').change(function(){
    Example.set( 'reverse', ( $(this).val() == 'true' ) ) ;    
  });
  $('.text').keyup(function(){
    Example.setText( $(this).val() ) ;
  });




});

});//]]>  

</script>


</head>
<body>
   <canvas id="c" width="400" height="200"></canvas>
  <br>
  <input type="text" class="text" value="Curved text"><br>
  Rayon : <input type="range"  min="0" max="100" value="50" class="radius" /><br>
  Espacement : <input type="range"  min="5" max="40" value="20" class="spacing" /><br>
  inverser le texte : <label><input type="radio" name="reverse" class="reverse" value="true" /> Oui</label> <label><input type="radio" name="reverse" class="reverse" value="false" checked="checked" /> Non</label><br />
  Alignement : <label><input type="radio" name="align" class="align" value="left" /> Gauche</label> <label><input type="radio" name="align" class="align" value="center" checked="checked" /> Centr�</label>  <label><input type="radio" name="align" class="align" value="right" /> Droite</label><br >
  Taille du texte : <input type="range"  min="3" max="100" value="20" class="fontSize" /><br>

</body>


</html>