• vue中实现3d词云效果(已封装组件)


    1. <template>
    2. <div
    3. :style="{
    4. display: 'flex',
    5. justifyContent: 'center',
    6. border: '1px solid red',
    7. }"
    8. >
    9. <svg
    10. :width="width"
    11. :height="height"
    12. @mousemove="listener($event)"
    13. @mouseout="listener1($event)"
    14. @mouseover="listener2($event)"
    15. >
    16. <a
    17. href="#"
    18. v-for="(tag, index) in tags"
    19. :key="index"
    20. @click="showOptionsAndResult(tag.text)"
    21. >
    22. <text
    23. :x="tag.x"
    24. :y="tag.y"
    25. :font-size="7 * (1000 / (800 - tag.z * 2))"
    26. :font-weight="550"
    27. :fill-opacity="(600 + tag.z) / 800"
    28. :style="style(tag)"
    29. >
    30. {{ tag.text }}
    31. text>
    32. a>
    33. svg>
    34. div>
    35. template>
    36. <script>
    37. export default {
    38. props: {
    39. width: {
    40. type: Number,
    41. default: 600,
    42. },
    43. height: {
    44. type: Number,
    45. default: 600,
    46. },
    47. radius: {
    48. type: Number,
    49. default: 200,
    50. },
    51. },
    52. data() {
    53. return {
    54. speedX: Math.PI / 1800,
    55. speedY: Math.PI / 1800,
    56. tags: [],
    57. colorList: [
    58. "#e27027",
    59. "#cc7b2e",
    60. "#ad4331",
    61. "#88343b",
    62. "#d4902f",
    63. "#c7a736",
    64. "#8d7a3d",
    65. "#8d7a3d",
    66. "#d9b134",
    67. ],
    68. CXNum: 2,
    69. CYNum: 2,
    70. };
    71. },
    72. computed: {
    73. CX() {
    74. return this.width / this.CXNum;
    75. },
    76. CY() {
    77. return this.height / this.CYNum;
    78. },
    79. },
    80. mounted() {
    81. let _this = this;
    82. window.addEventListener(
    83. "resize",
    84. () => {
    85. let normalWidth = document.body.scrollWidth;
    86. _this.screenWidth = normalWidth;
    87. if (normalWidth <= 1550) {
    88. _this.CXNum = 2.7;
    89. _this.CYNum = 1.9;
    90. } else {
    91. _this.CXNum = 2.5;
    92. _this.CYNum = 1.8;
    93. }
    94. },
    95. false
    96. );
    97. setInterval(() => {
    98. this.rotateX(this.speedX);
    99. this.rotateY(this.speedY);
    100. }, 17);
    101. },
    102. methods: {
    103. rotateX(angleX) {
    104. var cos = Math.cos(angleX);
    105. var sin = Math.sin(angleX);
    106. for (let tag of this.tags) {
    107. var y1 = (tag.y - this.CY) * cos - tag.z * sin + this.CY;
    108. var z1 = tag.z * cos + (tag.y - this.CY) * sin;
    109. tag.y = y1;
    110. tag.z = z1;
    111. }
    112. },
    113. rotateY(angleY) {
    114. var cos = Math.cos(angleY);
    115. var sin = Math.sin(angleY);
    116. for (let tag of this.tags) {
    117. var x1 = (tag.x - this.CX) * cos - tag.z * sin + this.CX;
    118. var z1 = tag.z * cos + (tag.x - this.CX) * sin;
    119. tag.x = x1;
    120. tag.z = z1;
    121. }
    122. },
    123. listener(event) {
    124. var x = event.clientX - this.CX;
    125. var y = event.clientY - this.CY;
    126. this.speedX =
    127. x * 0.0001 > 0
    128. ? Math.min(this.radius * 0.00002, x * 0.0001)
    129. : Math.max(-this.radius * 0.00002, x * 0.0001);
    130. this.speedY =
    131. y * 0.0001 > 0
    132. ? Math.min(this.radius * 0.00002, y * 0.0001)
    133. : Math.max(-this.radius * 0.00002, y * 0.0001);
    134. },
    135. listener1(e) {
    136. this.speedX = Math.PI / 1800;
    137. this.speedY = Math.PI / 1800;
    138. },
    139. listener2(e) {
    140. this.speedX = 0;
    141. this.speedY = 0;
    142. },
    143. showOptionsAndResult(text) {
    144. this.$emit("showOptionsAndResult", true, text, "", "");
    145. },
    146. style(tag) {
    147. return `fill:${tag.color};`;
    148. },
    149. calculation3DWord(radius = "") {
    150. let tags = [];
    151. for (let i = 0; i < this.tags.length; i++) {
    152. let tag = {};
    153. let k = -1 + (2 * (i + 1) - 1) / this.tags.length;
    154. let a = Math.acos(k);
    155. let b = a * Math.sqrt(this.tags.length * Math.PI);
    156. tag.text =
    157. typeof this.tags[i] === "string" ? this.tags[i] : this.tags[i].text;
    158. if (radius === "") {
    159. tag.x = this.CX + this.radius * Math.sin(a) * Math.cos(b);
    160. tag.y = this.CY + this.radius * Math.sin(a) * Math.sin(b);
    161. tag.z = this.radius * Math.cos(a);
    162. } else {
    163. tag.x = 150 * (radius / 120) + radius * Math.sin(a) * Math.cos(b);
    164. tag.y = 150 * (radius / 120) + radius * Math.sin(a) * Math.sin(b);
    165. tag.z = radius * Math.cos(a);
    166. }
    167. if (i <= this.colorList.length - 1) {
    168. tag.color = this.colorList[i];
    169. } else {
    170. tag.color =
    171. i % this.colorList.length === 0
    172. ? this.colorList[0]
    173. : this.colorList[i % this.colorList.length];
    174. }
    175. tags.push(tag);
    176. }
    177. this.tags.splice(0);
    178. this.tags = tags;
    179. },
    180. setTags(tags = []) {
    181. this.tags.splice(0);
    182. this.tags.push(...tags);
    183. this.calculation3DWord();
    184. },
    185. },
    186. };
    187. script>
    188. <style>style>
    1. // 使用
    2. ref="wordCloud"
    3. :width="rBox3.width"
    4. :height="rBox3.height"
    5. />
    6. import wordCloud from "@/views/dataScreen/wordCloud.vue";
    7. components: { wordCloud },
    8. init() {
    9. this.$refs.wordCloud.setTags([1, 2, 3 ,4 ,5 ,6]);
    10. }

  • 相关阅读:
    Reactive源码分析
    JavaScript 62 JavaScript 版本 62.2 JavaScript ES5
    redis5.0配置一主两从三哨兵
    Spring之AOP详解
    SQL基础理论篇(一):什么是SQL
    【Flask介绍】
    内存模型 C++
    Ansible相关内容梳理
    有没有什么赚钱的副业?分享,适合学生赚钱的30个副业!
    Sonar: static 修饰符顺序违法了JLS建议
  • 原文地址:https://blog.csdn.net/m0_74149462/article/details/136612079