经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Ext.js » 查看文章
arctext.js实现文字平滑弯曲弧形效果的插件
来源:jb51  时间:2019/5/14 8:32:02  对本文有异议

本文介绍了实现文字平滑弯曲弧形效果的插件-arctext.js,分享给大家,具体如下:

扇形的文字

有时候产品大佬就是很任性,说做一个宣传页,一个类似拱门的效果,每次文字不一样,但是文字得呈现拱形状,类似上图啦。

尝试自己使用canvas画和css3的rotate旋转div,两种方法都是计算旋转角度的时候很麻烦,因为可能5个字10个字,但是得均匀地呈拱形分布,要知道让每个文字都沿着弯曲路径排布相当的复杂,于是便发现了这个好用的插件---arctext.js

它能够自动计算每个文字正确的旋转角度,并且生成对应的CSS ,其实就是基于css3和jquery,使用起来也很方便。

1.创建一个容器装文字

  1. <h3 id="title">文字弯曲效果类似扇形拱桥状</h3>

2.引入jquery和arctext.js

  1. <script type="text/javascript" src="//code.jquery.com/jquery-1.8.2.min.js" ></script>
  2. <script src="jquery.arctext.js"></script>

3.调用arctext的方法:

  1. $(function(){
  2. $("#title").show().arctext({
  3. radius:180
  4. })
  5. })

arctext参数说明:

  • radius:弯曲度数,最小的值是文字长度,如果设置为-1,则显示直线。
  • rotate:默认true,为false则不旋转文字
  • dir:默认1 (1:向下弯曲 非1(-1,0,2等):向上弯曲 )
  • fitText:默认false,如果你想尝试使用fitText插件,设置为true,记住包装的标签需要fluid布局。

效果图完整demo:

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. #title{
  8. font-size: 20px;
  9. color: #ffe400;
  10. text-align: center;
  11. }
  12. </style>
  13. </head>
  14. <body>
  15. <h3 id="title">文字弯曲效果类似扇形拱桥状</h3>
  16. <script type="text/javascript" src="//code.jquery.com/jquery-1.8.2.min.js" ></script>
  17. <script src="jquery.arctext.js"></script>
  18. <script>
  19. $(function(){
  20. $("#title").arctext({
  21. radius:180
  22. })
  23. })
  24. </script>
  25. </body>
  26. </html>

jquery.arctext.js

  1. /**
  2. * Arctext.js
  3. * A jQuery plugin for curved text
  4. * http://www.codrops.com
  5. *
  6. * Copyright 2011, Pedro Botelho / Codrops
  7. * Free to use under the MIT license.
  8. *
  9. * Date: Mon Jan 23 2012
  10. */
  11.  
  12. (function( $, undefined ) {
  13. /*!
  14. * FitText.js 1.0
  15. *
  16. * Copyright 2011, Dave Rupert http://daverupert.com
  17. * Released under the WTFPL license
  18. * http://sam.zoy.org/wtfpl/
  19. *
  20. * Date: Thu May 05 14:23:00 2011 -0600
  21. */
  22. $.fn.fitText = function( kompressor, options ) {
  23.  
  24. var settings = {
  25. 'minFontSize' : Number.NEGATIVE_INFINITY,
  26. 'maxFontSize' : Number.POSITIVE_INFINITY
  27. };
  28.  
  29. return this.each(function() {
  30. var $this = $(this); // store the object
  31. var compressor = kompressor || 1; // set the compressor
  32. if ( options ) {
  33. $.extend( settings, options );
  34. }
  35. // Resizer() resizes items based on the object width divided by the compressor * 10
  36. var resizer = function () {
  37. $this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
  38. };
  39.  
  40. // Call once to set.
  41. resizer();
  42.  
  43. // Call on resize. Opera debounces their resize by default.
  44. $(window).resize(resizer);
  45. });
  46.  
  47. };
  48.  
  49. /*
  50. * Lettering plugin
  51. *
  52. * changed injector function:
  53. * add   for empty chars.
  54. */
  55. function injector(t, splitter, klass, after) {
  56. var a = t.text().split(splitter), inject = '', emptyclass;
  57. if (a.length) {
  58. $(a).each(function(i, item) {
  59. emptyclass = '';
  60. if(item === ' ') {
  61. emptyclass = ' empty';
  62. item=' ';
  63. }
  64. inject += '<span class="'+klass+(i+1)+emptyclass+'">'+item+'</span>'+after;
  65. });
  66. t.empty().append(inject);
  67. }
  68. }
  69. var methods = {
  70. init : function() {
  71.  
  72. return this.each(function() {
  73. injector($(this), '', 'char', '');
  74. });
  75.  
  76. },
  77.  
  78. words : function() {
  79.  
  80. return this.each(function() {
  81. injector($(this), ' ', 'word', ' ');
  82. });
  83.  
  84. },
  85. lines : function() {
  86.  
  87. return this.each(function() {
  88. var r = "eefec303079ad17405c889e092e105b0";
  89. // Because it's hard to split a <br/> tag consistently across browsers,
  90. // (*ahem* IE *ahem*), we replaces all <br/> instances with an md5 hash
  91. // (of the word "split"). If you're trying to use this plugin on that
  92. // md5 hash string, it will fail because you're being ridiculous.
  93. injector($(this).children("br").replaceWith(r).end(), r, 'line', '');
  94. });
  95.  
  96. }
  97. };
  98.  
  99. $.fn.lettering = function( method ) {
  100. // Method calling logic
  101. if ( method && methods[method] ) {
  102. return methods[ method ].apply( this, [].slice.call( arguments, 1 ));
  103. } else if ( method === 'letters' || ! method ) {
  104. return methods.init.apply( this, [].slice.call( arguments, 0 ) ); // always pass an array
  105. }
  106. $.error( 'Method ' + method + ' does not exist on jQuery.lettering' );
  107. return this;
  108. };
  109. /*
  110. * Arctext object.
  111. */
  112. $.Arctext = function( options, element ) {
  113. this.$el = $( element );
  114. this._init( options );
  115. };
  116. $.Arctext.defaults = {
  117. radius : 0, // the minimum value allowed is half of the word length. if set to -1, the word will be straight.
  118. dir : 1, // 1: curve is down, -1: curve is up.
  119. rotate : true, // if true each letter will be rotated.
  120. fitText : false // if you wanna try out the fitText plugin (http://fittextjs.com/) set this to true. Don't forget the wrapper should be fluid.
  121. };
  122. $.Arctext.prototype = {
  123. _init : function( options ) {
  124. this.options = $.extend( true, {}, $.Arctext.defaults, options );
  125. // apply the lettering plugin.
  126. this._applyLettering();
  127. this.$el.data( 'arctext', true );
  128. // calculate values
  129. this._calc();
  130. // apply transformation.
  131. this._rotateWord();
  132. // load the events
  133. this._loadEvents();
  134. },
  135. _applyLettering : function() {
  136. this.$el.lettering();
  137. if( this.options.fitText )
  138. this.$el.fitText();
  139. this.$letters = this.$el.find('span').css('display', 'inline-block');
  140. },
  141. _calc : function() {
  142. if( this.options.radius === -1 )
  143. return false;
  144. // calculate word / arc sizes & distances.
  145. this._calcBase();
  146. // get final values for each letter.
  147. this._calcLetters();
  148. },
  149. _calcBase : function() {
  150. // total word width (sum of letters widths)
  151. this.dtWord = 0;
  152. var _self = this;
  153. this.$letters.each( function(i) {
  154. var $letter = $(this),
  155. letterWidth = $letter.outerWidth( true );
  156. _self.dtWord += letterWidth;
  157. // save the center point of each letter:
  158. $letter.data( 'center', _self.dtWord - letterWidth / 2 );
  159. });
  160. // the middle point of the word.
  161. var centerWord = this.dtWord / 2;
  162. // check radius : the minimum value allowed is half of the word length.
  163. if( this.options.radius < centerWord )
  164. this.options.radius = centerWord;
  165. // total arc segment length, where the letters will be placed.
  166. this.dtArcBase = this.dtWord;
  167. // calculate the arc (length) that goes from the beginning of the first letter (x=0) to the end of the last letter (x=this.dtWord).
  168. // first lets calculate the angle for the triangle with base = this.dtArcBase and the other two sides = radius.
  169. var angle = 2 * Math.asin( this.dtArcBase / ( 2 * this.options.radius ) );
  170. // given the formula: L(ength) = R(adius) x A(ngle), we calculate our arc length.
  171. this.dtArc = this.options.radius * angle;
  172. },
  173. _calcLetters : function() {
  174. var _self = this,
  175. iteratorX = 0;
  176. this.$letters.each( function(i) {
  177. var $letter = $(this),
  178. // calculate each letter's semi arc given the percentage of each letter on the original word.
  179. dtArcLetter = ( $letter.outerWidth( true ) / _self.dtWord ) * _self.dtArc,
  180. // angle for the dtArcLetter given our radius.
  181. beta = dtArcLetter / _self.options.radius,
  182. // distance from the middle point of the semi arc's chord to the center of the circle.
  183. // this is going to be the place where the letter will be positioned.
  184. h = _self.options.radius * ( Math.cos( beta / 2 ) ),
  185. // angle formed by the x-axis and the left most point of the chord.
  186. alpha = Math.acos( ( _self.dtWord / 2 - iteratorX ) / _self.options.radius ),
  187. // angle formed by the x-axis and the right most point of the chord.
  188. theta = alpha + beta / 2,
  189. // distances of the sides of the triangle formed by h and the orthogonal to the x-axis.
  190. x = Math.cos( theta ) * h,
  191. y = Math.sin( theta ) * h,
  192. // the value for the coordinate x of the middle point of the chord.
  193. xpos = iteratorX + Math.abs( _self.dtWord / 2 - x - iteratorX ),
  194. // finally, calculate how much to translate each letter, given its center point.
  195. // also calculate the angle to rotate the letter accordingly.
  196. xval = 0| xpos - $letter.data( 'center' ),
  197. yval = 0| _self.options.radius - y,
  198. angle = ( _self.options.rotate ) ? 0| -Math.asin( x / _self.options.radius ) * ( 180 / Math.PI ) : 0;
  199. // the iteratorX will be positioned on the second point of each semi arc
  200. iteratorX = 2 * xpos - iteratorX;
  201. // save these values
  202. $letter.data({
  203. x : xval,
  204. y : ( _self.options.dir === 1 ) ? yval : -yval,
  205. a : ( _self.options.dir === 1 ) ? angle : -angle
  206. });
  207. });
  208. },
  209. _rotateWord : function( animation ) {
  210. if( !this.$el.data('arctext') ) return false;
  211. var _self = this;
  212. this.$letters.each( function(i) {
  213. var $letter = $(this),
  214. transformation = ( _self.options.radius === -1 ) ? 'none' : 'translateX(' + $letter.data('x') + 'px) translateY(' + $letter.data('y') + 'px) rotate(' + $letter.data('a') + 'deg)',
  215. transition = ( animation ) ? 'all ' + ( animation.speed || 0 ) + 'ms ' + ( animation.easing || 'linear' ) : 'none';
  216. $letter.css({
  217. '-webkit-transition' : transition,
  218. '-moz-transition' : transition,
  219. '-o-transition' : transition,
  220. '-ms-transition' : transition,
  221. 'transition' : transition
  222. })
  223. .css({
  224. '-webkit-transform' : transformation,
  225. '-moz-transform' : transformation,
  226. '-o-transform' : transformation,
  227. '-ms-transform' : transformation,
  228. 'transform' : transformation
  229. });
  230. });
  231. },
  232. _loadEvents : function() {
  233. if( this.options.fitText ) {
  234. var _self = this;
  235. $(window).on( 'resize.arctext', function() {
  236. _self._calc();
  237. // apply transformation.
  238. _self._rotateWord();
  239. });
  240. }
  241. },
  242. set : function( opts ) {
  243. if( !opts.radius &&
  244. !opts.dir &&
  245. opts.rotate === 'undefined' ) {
  246. return false;
  247. }
  248. this.options.radius = opts.radius || this.options.radius;
  249. this.options.dir = opts.dir || this.options.dir;
  250. if( opts.rotate !== undefined ) {
  251. this.options.rotate = opts.rotate;
  252. }
  253. this._calc();
  254. this._rotateWord( opts.animation );
  255. },
  256. destroy : function() {
  257. this.options.radius = -1;
  258. this._rotateWord();
  259. this.$letters.removeData('x y a center');
  260. this.$el.removeData('arctext');
  261. $(window).off('.arctext');
  262. }
  263. };
  264. var logError = function( message ) {
  265. if ( this.console ) {
  266. console.error( message );
  267. }
  268. };
  269. $.fn.arctext = function( options ) {
  270. if ( typeof options === 'string' ) {
  271. var args = Array.prototype.slice.call( arguments, 1 );
  272. this.each(function() {
  273. var instance = $.data( this, 'arctext' );
  274. if ( !instance ) {
  275. logError( "cannot call methods on arctext prior to initialization; " +
  276. "attempted to call method '" + options + "'" );
  277. return;
  278. }
  279. if ( !$.isFunction( instance[options] ) || options.charAt(0) === "_" ) {
  280. logError( "no such method '" + options + "' for arctext instance" );
  281. return;
  282. }
  283. instance[ options ].apply( instance, args );
  284. });
  285. }
  286. else {
  287. this.each(function() {
  288. var instance = $.data( this, 'arctext' );
  289. if ( !instance ) {
  290. $.data( this, 'arctext', new $.Arctext( options, this ) );
  291. }
  292. });
  293. }
  294. return this;
  295. };
  296. })( jQuery );

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号