// 词云 Component({ /** * 组件的属性列表 */ properties: { width: { type: Number | String, value: "100%" }, height: { type: Number, value: 330 }, minFont: { type: Number, value: 12 }, maxFont: { type: Number, value: 35 }, fontColor: { type: String, value: "#f4347a" }, wordsCloud: { type: Array, value: [], observer(words) { this.texts = []; this.ctx && this.ctx.clearRect(0, 0, this.width, this.height); if (words.length > 0) { //排序 words.sort((a, b) => { return parseFloat(b.value) - parseFloat(a.value) }) this.maxVal = words[0].value; this.minVal = words[words.length - 1].value; words.forEach((v, i) => { let point = this.creatText(v, i); this.texts.push(point); this.drawText(point); }) } this.ctx && this.ctx.draw() } } }, minVal: 0, maxVal: 0, /** * 组件的初始数据 */ data: { texts: [] }, attached() { this.ctx = wx.createCanvasContext('canvas', this); this.height = this.data.height; this.width = wx.getSystemInfoSync().screenWidth; this.texts = []; }, /** * 组件的方法列表 */ methods: { drawText(word) { let colorLi = ['8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; let color = "#"; for (let i = 0, len = 6; i < len; i++) { color += colorLi[Math.floor(Math.random() * len)] } this.ctx.translate(word.x, word.y); this.ctx.rotate(word.angle); this.ctx.setFillStyle(color); this.ctx.textAlign = "left"; this.ctx.textBaseline = "top"; this.ctx.font = word.height + "px arial"; this.ctx.fillText(word.name, 0, 0); this.ctx.rotate(-1 * word.angle); this.ctx.translate(-1 * word.x, -1 * word.y); }, creatText(v, i) { const maxf = this.data.maxFont; const minf = this.data.minFont; let fen = (this.maxVal - this.minVal) / (maxf - minf); let fontsize = Math.ceil((v.value - this.minVal) / fen + minf) this.ctx.setFontSize(fontsize) let textWidth = this.ctx.measureText(v.name).width //文字所占宽度 const createPoint = { x: 0, y: 0, width: textWidth, height: fontsize, angle: Math.random() * Math.PI / 4, } if (i === 0) { createPoint.x = this.width / 2 - textWidth / 2; createPoint.y = this.data.height / 2 - fontsize / 2; createPoint.angle = 0; } else { createPoint.x = Math.floor(Math.random() * (this.width)); createPoint.y = Math.floor(Math.random() * (this.data.height)); } // else{ // createPoint.x = Math.floor(Math.random() * (this.width)); // createPoint.y = Math.floor(Math.random() * (this.data.height)); // } // 边界碰撞 let c = Math.ceil(Math.sqrt(Math.pow(fontsize, 2) + Math.pow(textWidth, 2))); let cosx = Math.cos(createPoint.angle); let cosy = Math.cos(Math.PI / 2 - createPoint.angle); let jH = Math.asin(fontsize / textWidth); let cosyR = Math.cos(jH); let height = c * cosyR; let width = textWidth * cosx; let leftX = fontsize * cosy; createPoint.x < leftX && (createPoint.x = leftX); createPoint.x > this.width - width && (createPoint.x = this.width - width - 5); createPoint.y > this.data.height - height && (createPoint.y = this.data.height - height); return { ...v, ...createPoint } } } })