style-parse.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. "use strict";
  2. var Util = require('../../util/common');
  3. function _mod(n, m) {
  4. return (n % m + m) % m;
  5. }
  6. function _addStop(steps, gradient) {
  7. Util.each(steps, function (item) {
  8. item = item.split(':');
  9. gradient.addColorStop(Number(item[0]), item[1]);
  10. });
  11. } // the string format: 'l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff'
  12. function _parseLineGradient(color, shape, context) {
  13. var arr = color.split(' ');
  14. var angle = arr[0].slice(2, arr[0].length - 1);
  15. angle = _mod(parseFloat(angle) * Math.PI / 180, Math.PI * 2);
  16. var steps = arr.slice(1);
  17. var _shape$getBBox = shape.getBBox(),
  18. minX = _shape$getBBox.minX,
  19. minY = _shape$getBBox.minY,
  20. maxX = _shape$getBBox.maxX,
  21. maxY = _shape$getBBox.maxY;
  22. var start;
  23. var end;
  24. if (angle >= 0 && angle < 0.5 * Math.PI) {
  25. start = {
  26. x: minX,
  27. y: minY
  28. };
  29. end = {
  30. x: maxX,
  31. y: maxY
  32. };
  33. } else if (0.5 * Math.PI <= angle && angle < Math.PI) {
  34. start = {
  35. x: maxX,
  36. y: minY
  37. };
  38. end = {
  39. x: minX,
  40. y: maxY
  41. };
  42. } else if (Math.PI <= angle && angle < 1.5 * Math.PI) {
  43. start = {
  44. x: maxX,
  45. y: maxY
  46. };
  47. end = {
  48. x: minX,
  49. y: minY
  50. };
  51. } else {
  52. start = {
  53. x: minX,
  54. y: maxY
  55. };
  56. end = {
  57. x: maxX,
  58. y: minY
  59. };
  60. }
  61. var tanTheta = Math.tan(angle);
  62. var tanTheta2 = tanTheta * tanTheta;
  63. var x = (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.x;
  64. var y = tanTheta * (end.x - start.x + tanTheta * (end.y - start.y)) / (tanTheta2 + 1) + start.y;
  65. var gradient = context.createLinearGradient(start.x, start.y, x, y);
  66. _addStop(steps, gradient);
  67. return gradient;
  68. } // the string format: 'r(0.5, 0.5, 0.1) 0:#ffffff 1:#1890ff'
  69. function _parseRadialGradient(color, shape, context) {
  70. var arr = color.split(' ');
  71. var circleCfg = arr[0].slice(2, arr[0].length - 1);
  72. circleCfg = circleCfg.split(',');
  73. var fx = parseFloat(circleCfg[0]);
  74. var fy = parseFloat(circleCfg[1]);
  75. var fr = parseFloat(circleCfg[2]);
  76. var steps = arr.slice(1); // if radius is 0, no gradient, stroke with the last color
  77. if (fr === 0) {
  78. var _color = steps[steps.length - 1];
  79. return _color.split(':')[1];
  80. }
  81. var _shape$getBBox2 = shape.getBBox(),
  82. width = _shape$getBBox2.width,
  83. height = _shape$getBBox2.height,
  84. minX = _shape$getBBox2.minX,
  85. minY = _shape$getBBox2.minY;
  86. var r = Math.sqrt(width * width + height * height) / 2;
  87. var gradient = context.createRadialGradient(minX + width * fx, minY + height * fy, fr * r, minX + width / 2, minY + height / 2, r);
  88. _addStop(steps, gradient);
  89. return gradient;
  90. }
  91. module.exports = {
  92. parseStyle: function parseStyle(color, shape, context) {
  93. if (color[1] === '(') {
  94. try {
  95. var firstCode = color[0];
  96. if (firstCode === 'l') {
  97. return _parseLineGradient(color, shape, context);
  98. } else if (firstCode === 'r') {
  99. return _parseRadialGradient(color, shape, context);
  100. }
  101. } catch (ev) {
  102. console.error('error in parsing gradient string, please check if there are any extra whitespaces.');
  103. console.error(ev);
  104. }
  105. }
  106. return color;
  107. }
  108. };