waterbubble.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /**
  2. * 水球图 wataerbubble
  3. * @author fiona23 (fiona_fanmy@163.com)
  4. */
  5. (function($) {
  6. $.fn.waterbubble = function(options) {
  7. var config = $.extend({
  8. radius: 100,
  9. lineWidth: undefined,
  10. data: 0.5,
  11. waterColor: 'rgba(25, 139, 201, 1)',
  12. textColor: 'rgba(06, 85, 128, 0.8)',
  13. font: '',
  14. wave: true,
  15. txt: undefined,
  16. animation: true
  17. }, options);
  18. var canvas = this[0];
  19. // config.lineWidth = config.lineWidth ? config.lineWidth : config.radius/24;
  20. config.lineWidth = options.lineWidth;
  21. var waterbubble = new Waterbubble(canvas, config);
  22. return this;
  23. }
  24. function Waterbubble (canvas, config) {
  25. this.refresh(canvas, config);
  26. }
  27. Waterbubble.prototype = {
  28. refresh: function (canvas, config) {
  29. canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height)
  30. this._init(canvas, config)
  31. },
  32. _init: function (canvas, config){
  33. var radius = config.radius;
  34. var lineWidth = config.lineWidth;
  35. canvas.width = radius*2 + lineWidth;
  36. canvas.height = radius*2 + lineWidth;
  37. this._buildShape(canvas, config);
  38. },
  39. _buildShape: function (canvas, config) {
  40. var ctx = canvas.getContext('2d');
  41. var gap = config.lineWidth*2;
  42. //raidus of water
  43. var r = config.radius - gap;
  44. var data = config.data;
  45. var lineWidth = config.lineWidth
  46. var waterColor = config.waterColor;
  47. var textColor = config.textColor;
  48. var font = config.font;
  49. var wave = config.wave
  50. // //the center of circle
  51. var x = config.radius + lineWidth/2;
  52. var y = config.radius + lineWidth/2;
  53. ctx.beginPath();
  54. ctx.arc(x, y, config.radius, 0, Math.PI*2);
  55. ctx.lineWidth = lineWidth;
  56. ctx.strokeStyle = waterColor;
  57. ctx.stroke();
  58. //if config animation true
  59. if (config.animation) {
  60. this._animate(ctx, r, data, lineWidth, waterColor, x, y, wave)
  61. } else {
  62. this._fillWater(ctx, r, data, lineWidth, waterColor, x, y, wave);
  63. }
  64. if (typeof config.txt == 'string'){
  65. this._drawText(ctx, textColor, font, config.radius, data, x, y, config.txt);
  66. }
  67. return;
  68. },
  69. _fillWater: function (ctx, r, data, lineWidth, waterColor, x, y, wave) {
  70. ctx.beginPath();
  71. ctx.globalCompositeOperation = 'destination-over';
  72. //start co-ordinates
  73. var sy = r*2*(1 - data) + (y - r);
  74. var sx = x - Math.sqrt((r)*(r) - (y - sy)*(y - sy));
  75. //middle co-ordinates
  76. var mx = x;
  77. var my = sy;
  78. //end co-ordinates
  79. var ex = 2*mx - sx;
  80. var ey = sy;
  81. var extent; //extent
  82. if (data > 0.9 || data < 0.1 || !wave) {
  83. extent = sy
  84. } else{
  85. extent = sy - (mx -sx)/4
  86. }
  87. ctx.beginPath();
  88. ctx.moveTo(sx, sy)
  89. ctx.quadraticCurveTo((sx + mx)/2, extent, mx, my);
  90. ctx.quadraticCurveTo((mx + ex)/2, 2*sy - extent, ex, ey);
  91. var startAngle = -Math.asin((x - sy)/r)
  92. var endAngle = Math.PI - startAngle;
  93. ctx.arc(x, y, r, startAngle, endAngle, false)
  94. ctx.fillStyle = waterColor;
  95. ctx.fill()
  96. },
  97. _drawText: function (ctx, textColor, font, radius, data, x, y, txt) {
  98. ctx.globalCompositeOperation = 'source-over';
  99. var size = font ? font.replace( /\D+/g, '') : 0.4*radius;
  100. ctx.font = font ? font : 'bold ' + size + 'px Microsoft Yahei';
  101. txt = txt.length ? txt : data*100 + '%'
  102. var sy = y + size/2;
  103. var sx = x - ctx.measureText(txt).width/2
  104. ctx.fillStyle = textColor;
  105. ctx.fillText(txt, sx, sy)
  106. },
  107. _animate: function (ctx, r, data, lineWidth, waterColor, x, y, wave) {
  108. var datanow = {
  109. value: 0
  110. };
  111. var requestAnimationFrame = window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || function (func) {
  112. setTimeout(func, 16);
  113. };
  114. var self = this;
  115. var update = function () {
  116. if (datanow.value < data - 0.01) {
  117. datanow.value += (data - datanow.value)/15
  118. self._runing = true;
  119. } else {
  120. self._runing = false;
  121. }
  122. }
  123. var step = function () {
  124. self._fillWater(ctx, r, datanow.value, lineWidth, waterColor, x, y, wave);
  125. update();
  126. if (self._runing) {
  127. requestAnimationFrame(step);
  128. }
  129. }
  130. step(ctx, r, datanow, lineWidth, waterColor, x, y, wave)
  131. }
  132. }
  133. }(jQuery));