link.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <g class="flow-link" :class="{'flow-link--pointer':pointer}" :status="status" @mousedown="$emit('mousedown',$event)">
  3. <path class="flow-link__area" :d="path" />
  4. <path class="flow-link__visible" :d="path" />
  5. <path v-if="status" class="flow-link__status" :d="path" />
  6. </g>
  7. </template>
  8. <script>
  9. const curve = 100
  10. export default {
  11. name: 'FlowLink',
  12. props: {
  13. x1: {type: Number, default: 0},
  14. y1: {type: Number, default: 0},
  15. x2: {type: Number, default: 0},
  16. y2: {type: Number, default: 0},
  17. pointer: {type: Boolean, default: false},
  18. status: {type: String, default: null}
  19. },
  20. computed: {
  21. path () {
  22. const x1 = this.x1 + 7
  23. const y1 = this.y1
  24. const x2 = this.x2 - (this.pointer ? 4 : 15.5)
  25. const y2 = this.y2
  26. const dx = x2 - x1
  27. const dy = y2 - y1
  28. let s = curve
  29. let lineDist = 200
  30. let dist = Math.sqrt(dx * dx + dy * dy)
  31. // Reduce curve with distance
  32. if (dist < lineDist) {
  33. s = Math.max(curve - (lineDist - dist), 0)
  34. }
  35. s = Math.min(s, Math.min(dx, 100))
  36. let ox1 = s
  37. let oy1 = 0
  38. let ox2 = -s
  39. let oy2 = 0
  40. if (dx < 0) {
  41. ox1 = Math.min(-dx, 100)
  42. ox2 = -Math.min(-dx, 100)
  43. oy1 = Math.min(-dx, 150)
  44. oy2 = -Math.min(-dx, 150)
  45. if (dy < 0) {
  46. oy1 = -oy1
  47. oy2 = -oy2
  48. }
  49. }
  50. return `
  51. M${x1},${y1}
  52. C${x1 + ox1},${y1 + oy1}
  53. ${x2 + ox2},${y2 + oy2}
  54. ${x2 - 1},${y2}
  55. L${x2} ${y2}
  56. `
  57. }
  58. }
  59. }
  60. </script>
  61. <style>
  62. .flow-view:not(.activity) .flow-link {
  63. cursor:pointer;
  64. }
  65. .flow-link__head{
  66. fill:#333;
  67. }
  68. .flow-link {
  69. stroke:#333;
  70. }
  71. .flow-link__area {
  72. stroke-width:20;
  73. stroke: transparent;
  74. fill: transparent;
  75. }
  76. .flow-link__visible{
  77. stroke-width:2;
  78. fill: transparent;
  79. marker-end:url(#head);
  80. }
  81. .flow-link--pointer {
  82. pointer-events:none;
  83. }
  84. .flow-link__status {
  85. opacity:1;
  86. stroke-width:4;
  87. }
  88. .flow-link[status=waiting] .flow-link__status {
  89. stroke-dasharray:8;
  90. stroke: grey;
  91. animation: dash 10s linear infinite;
  92. }
  93. .flow-link[status=running] .flow-link__status {
  94. stroke-dasharray:4,10;
  95. stroke: #aa2;
  96. animation: dash 1s linear infinite;
  97. }
  98. .flow-link[status=finish] .flow-link__status {
  99. stroke: green;
  100. }
  101. .flow-link[status=error] .flow-link__status {
  102. stroke: red;
  103. }
  104. @keyframes dash {
  105. from { stroke-dashoffset:100;}
  106. to { stroke-dashoffset: 0; }
  107. }
  108. </style>