index.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <div class="marquee-box">
  3. <div class="scroll-area">
  4. <!-- 设置margin,使内容 有从无到有的出现效果 -->
  5. <div class="marquee-container">
  6. <div class="icon">
  7. <i
  8. v-if="config.customize.icon.position === 'left'"
  9. :class="config.customize.icon.name"
  10. :style="{ color: config.customize.icon.color, fontSize: config.customize.fontSize + 'px' }"
  11. />
  12. </div>
  13. <svg class="svg-container">
  14. <defs>
  15. <linearGradient
  16. :id="'backgroundGradient-'+config.code"
  17. :x1="0"
  18. :y1="['to top right'].includes(config.customize.bgGradientDirection) ? '100%' : '0'"
  19. :x2="['to right','to bottom right','to top right'].includes(config.customize.bgGradientDirection) ? '100%' : '0'"
  20. :y2="['to bottom','to bottom right'].includes(config.customize.bgGradientDirection) ? '100%' : '0'"
  21. >
  22. <stop
  23. offset="0%"
  24. :stop-color="config.customize.backgroundColorType === 'pure' ? config.customize.backgroundColor : config.customize.bgGradientColor0"
  25. />
  26. <stop
  27. offset="100%"
  28. :stop-color="config.customize.backgroundColorType === 'pure' ? config.customize.backgroundColor : config.customize.bgGradientColor1"
  29. />
  30. </linearGradient>
  31. <linearGradient
  32. :id="'textGradient-'+config.code"
  33. :x1="0"
  34. :y1="['to top right'].includes(config.customize.textGradientDirection) ? '100%' : '0'"
  35. :x2="['to right','to bottom right','to top right'].includes(config.customize.textGradientDirection) ? '100%' : '0'"
  36. :y2="['to bottom','to bottom right'].includes(config.customize.textGradientDirection) ? '100%' : '0'"
  37. >
  38. <stop
  39. offset="0%"
  40. :stop-color="config.customize.textColorType === 'pure' ? config.customize.textColor : config.customize.textGradientColor0"
  41. />
  42. <stop
  43. offset="100%"
  44. :stop-color="config.customize.textColorType === 'pure' ? config.customize.textColor : config.customize.textGradientColor1"
  45. />
  46. </linearGradient>
  47. </defs>
  48. <rect
  49. v-if="config.customize.backgroundColorType !== 'transparent'"
  50. width="100%"
  51. height="100%"
  52. :fill="`url(#backgroundGradient-${config.code})`"
  53. />
  54. <text
  55. :x="10"
  56. :y="config.customize.fontSize"
  57. :style="{ fontSize: config.customize.fontSize + 'px', fontWeight: config.customize.fontWeight }"
  58. :fill="`url(#textGradient-${config.code})`"
  59. >
  60. <animate
  61. v-if="isAnimate"
  62. :attributeName="attributeName[config.customize.direction]"
  63. :from="from[config.customize.direction]"
  64. :to="to[config.customize.direction]"
  65. :dur="config.customize.dur + 's'"
  66. repeatCount="indefinite"
  67. />
  68. {{ config.customize.title }}
  69. </text>
  70. </svg>
  71. <div class="icon">
  72. <i
  73. v-if="config.customize.icon.position === 'right'"
  74. :class="config.customize.icon.name"
  75. :style="{ color: config.customize.icon.color, fontSize: config.customize.fontSize + 'px' }"
  76. />
  77. </div>
  78. </div>
  79. </div>
  80. </div>
  81. </template>
  82. <script>
  83. import { EventBus } from 'data-room-ui/js/utils/eventBus'
  84. import commonMixins from 'data-room-ui/js/mixins/commonMixins'
  85. import paramsMixins from 'data-room-ui/js/mixins/paramsMixins'
  86. export default {
  87. props: {
  88. // 卡片的属性
  89. config: {
  90. type: Object,
  91. default: () => ({})
  92. }
  93. },
  94. data () {
  95. return {
  96. customClass: {},
  97. attributeName: {
  98. right: 'x',
  99. left: 'x',
  100. top: 'y',
  101. bottom: 'y'
  102. },
  103. // 动画开始
  104. from: {
  105. left: '-100%',
  106. right: '100%',
  107. top: '-100%',
  108. bottom: '100%'
  109. },
  110. // 动画结束
  111. to: {
  112. left: '100%',
  113. right: '-100%',
  114. top: '100%',
  115. bottom: '-100%'
  116. },
  117. isAnimate: true
  118. }
  119. },
  120. mixins: [paramsMixins, commonMixins],
  121. mounted () {
  122. this.chartInit()
  123. // 如果点击了生成图片,则先关闭动画
  124. EventBus.$on('stopMarquee', () => {
  125. this.isAnimate = false
  126. })
  127. // 图片生成完成后,再开启动画
  128. EventBus.$on('startMarquee', () => {
  129. this.isAnimate = true
  130. })
  131. },
  132. beforeDestroy () {
  133. EventBus.$off('stopMarquee')
  134. EventBus.$off('startMarquee')
  135. },
  136. methods: {
  137. changeStyle () {
  138. },
  139. dataFormatting (config, data) {
  140. // 文本数据配置原则:选择数据集则以后端返回的数据为主,否则以设置面板中标题设置为准
  141. if (config.dataSource.businessKey) {
  142. config.customize.title = data && data.data && data.data.length ? data.data[0][config.dataSource.metricField] : '暂无数据'
  143. }
  144. return config
  145. }
  146. }
  147. }
  148. </script>
  149. <style lang="scss" scoped>
  150. .marquee-box {
  151. width: 100%;
  152. height: 100%;
  153. display: inline-block;
  154. white-space: nowrap;
  155. overflow: hidden;
  156. .scroll-area {
  157. width: 100%;
  158. height: 100%;
  159. display: inline-block;
  160. .marquee-container {
  161. width: 100%;
  162. height: 100%;
  163. display: flex;
  164. .svg-container {
  165. display: inline-block;
  166. width: 100%;
  167. height: 100%;
  168. }
  169. }
  170. }
  171. .icon {
  172. position: relative;
  173. top: 0;
  174. // 清除浮动
  175. }
  176. }
  177. </style>