123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- // 词云
- 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
- }
- }
- }
- })
|