function word_cloud(self, id, config) { const _self = this; _self.ownerDocument = wx.createSelectorQuery().select('#' + id).boundingClientRect(); _self.ownerWindow = self; _self.config = config; _self.ownerDocument.exec(res => { _self.canvas = res[0] }) _self.canvas.width = _self.config.width; _self.canvas.height = _self.config.height; _self.ctx = _self.canvas.getContext('2d'); _self.canvas.style.zIndex = 1; _self.word = []; _self.canvas.style.backgroundColor = _self.config.bgcolor; } word_cloud.prototype.clear = function () { var _self = this; _self.ctx.clearRect(0, 0, _self.config.width, _self.config.height); _self.ctx_temp.clearRect(0, 0, _self.config.width, _self.config.height); _self.word = []; clearTimeout(_self._timeout); } word_cloud.prototype.show = function (data) { var _self = this; _self.clear(); data = data.sort(function (a, b) { //排序 return parseInt(b[0]) - parseInt(a[0]); }); for (var i = 0; i < data.length; i++) { if (data[i]) { var ret = data[i]; var size = parseInt(ret[0]) * _self.config.size_zoom; var txt = ret[1]; var color = ret[2]; if (size < _self.config.min_size) size = _self.config.min_size; _self.word.push({ size: size, text: txt, color: color }); } } var pixel = []; var midx = Math.floor(_self.config.width / 2); var midy = Math.floor(_self.config.height / 2); var step = 1; var isgoon = true; while (isgoon) { var leftX = midx - step * _self.config.minstep; var rightX = midx + step * _self.config.minstep; var topY = midy - step * _self.config.minstep; var bottomY = midy + step * _self.config.minstep; isgoon = false; var buff = []; if (topY >= 0) //上下 { for (var i = leftX; i < rightX; i += _self.config.minstep) { buff.push([i, topY]); buff.push([i, bottomY]); } isgoon = true; } if (leftX >= 0) //左右 { for (var i = topY; i < bottomY; i += _self.config.minstep) { buff.push([rightX, i]); buff.push([leftX, i]); } isgoon = true; } buff = buff.sort(function () { return Math.floor(Math.random() * 1000) > 500; }); pixel = pixel.concat(buff); step++; } _self.pixel = pixel; //遍历路径 var curIndex = 0; var _append = function () { if (curIndex < _self.word.length) { _self.appendWord(_self.word[curIndex]); curIndex++; _self._timeout = setTimeout(_append, _self.config.speed); } }; _self._timeout = setTimeout(_append, _self.config.speed); }; word_cloud.prototype.appendWord = function (objWord) { var _self = this; var r = 0; if (Math.random() * 100 < _self.config.rotate_chance) { r = Math.round(Math.random() * 40); if (Math.random() * 10 > 5) r = 0 - r; } var imgdata = _self.ctx.getImageData(0, 0, _self.config.width, _self.config.height); var wordData = _self.wordPixel(objWord.text, objWord.size, objWord.color, r); var width = wordData.width; var height = wordData.height; var step = Math.round(width / 2); for (var i = 0; i < _self.pixel.length; i += step) { var x = Math.round(_self.pixel[i][0] - width / 2); var y = Math.round(_self.pixel[i][1] - height / 2); var curLine = 0; var curIndex = 0; var isfaild = false; if (x < 0 || y < 0 || x + width > _self.config.width || y + height > _self.config.height) { continue; } while (curLine < height + _self.config.spacing) { var cSite = ((y + curLine) * _self.config.width + x + curIndex) * 4; var tSite = (curLine * (width) + curIndex) * 4; if (imgdata.data[cSite] > 0 || imgdata.data[cSite + 1] > 0 || imgdata.data[cSite + 2] > 0 || imgdata.data[cSite + 3] > 0) { if (wordData.data[tSite] > 0 || wordData.data[tSite + 1] > 0 || wordData.data[tSite + 2] > 0 || wordData.data[tSite + 3] > 0) { isfaild = true; break; } } curIndex++; if (curIndex >= width) { curLine++; curIndex = 0; } } if (!isfaild) { var curData = _self.ctx.createImageData(width, height); curLine = 0; curIndex = 0; while (curLine < height + _self.config.spacing) { var cSite = ((y + curLine) * _self.config.width + x + curIndex) * 4; var tSite = (curLine * (width) + curIndex) * 4; if (imgdata.data[cSite] > 0 || imgdata.data[cSite + 1] > 0 || imgdata.data[cSite + 2] > 0 || imgdata.data[cSite + 3] > 0) { curData.data[tSite] = imgdata.data[cSite]; curData.data[tSite + 1] = imgdata.data[cSite + 1]; curData.data[tSite + 2] = imgdata.data[cSite + 2]; curData.data[tSite + 3] = imgdata.data[cSite + 3]; } else { curData.data[tSite] = wordData.data[tSite]; curData.data[tSite + 1] = wordData.data[tSite + 1]; curData.data[tSite + 2] = wordData.data[tSite + 2]; curData.data[tSite + 3] = wordData.data[tSite + 3]; } curIndex++; if (curIndex >= width) { curLine++; curIndex = 0; } } _self.ctx.putImageData(curData, x, y, 0, 0, width, height); break; } } _self.ctx_temp.clearRect(0, 0, _self.config.width, _self.config.height); }; word_cloud.prototype.wordPixel = function (text, size, color, rotate) { var _self = this; if (!color) { if (_self.config.default_color && _self.config.default_color.length > 0) { var ind = Math.round(Math.random() * _self.config.default_color.length); color = _self.config.default_color[ind]; } else { color = "#" + Math.floor((Math.random() * 255)).toString(16) + Math.floor((Math.random() * 255)).toString(16) + Math.floor((Math.random() * 255)).toString(16); } } _self.ctx_temp.textBaseline = "top"; _self.ctx_temp.font = _self.config.default_bold + " " + size + "px " + _self.config.default_family; _self.ctx_temp.fillStyle = color; _self.ctx_temp.strokeStyle = color; var height = size + _self.config.spacing; var width = _self.ctx_temp.measureText(text).width + _self.config.spacing; if (isNaN(rotate) || rotate == 0) { _self.ctx_temp.fillText(text, 0, 0); } else { var a = Math.round(Math.abs(Math.sin((Math.PI / 180) * rotate) * height)); var b = Math.round(Math.abs(Math.sin((Math.PI / 180) * rotate) * width)); var centerX = Math.round((width + a) / 2); var centerY = Math.round((height + b) / 2); _self.ctx_temp.translate(centerX, centerY); _self.ctx_temp.rotate((Math.PI / 180) * rotate); _self.ctx_temp.translate(-centerX, -centerY); _self.ctx_temp.fillText(text, a / 2, b / 2); _self.ctx_temp.translate(centerX, centerY); _self.ctx_temp.rotate((Math.PI / 180) * (-rotate)); _self.ctx_temp.translate(-centerX, -centerY); width += a; height += b; } return _self.ctx_temp.getImageData(0, 0, width, height); }