style-parse.js 3.1 KB

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