simple-word-cloud
Advanced tools
Comparing version 1.0.0 to 1.0.1
135
index.js
import WordItem from './src/WordItem' | ||
import { getFontSize, getTextBoundingRect, createRandom } from './src/utils' | ||
import { | ||
getFontSize, | ||
getTextBoundingRect, | ||
createRandom, | ||
joinFontStr, | ||
downloadFile | ||
} from './src/utils' | ||
import { addToMap, getPosition, getBoundingRect, clear } from './src/compute' | ||
@@ -20,2 +26,5 @@ | ||
this.wordItemElList = [] | ||
// canvas | ||
this.canvas = null | ||
this.renderCtx = null | ||
} | ||
@@ -48,3 +57,4 @@ | ||
transition, | ||
smallWeightInCenter | ||
smallWeightInCenter, | ||
onClick | ||
}) { | ||
@@ -71,5 +81,9 @@ // 字号大小 | ||
// 文本元素过渡动画 | ||
this.transition = transition || 'all 0.5s' | ||
this.transition = transition || 'all 0.5s ease' | ||
// 按权重从小到大的顺序渲染,默认是按权重从大到小进行渲染 | ||
this.smallWeightInCenter = smallWeightInCenter || false | ||
// 点击事件 | ||
this.onClick = onClick || null | ||
// 当前渲染的列表 | ||
this.curRenderList = [] | ||
} | ||
@@ -144,5 +158,100 @@ | ||
// 计算并直接渲染到容器内 | ||
// 计算并使用canvas渲染到容器内 | ||
renderUseCanvas(words, done = () => {}) { | ||
if (!this.canvas) { | ||
this.canvas = document.createElement('canvas') | ||
this.canvas.width = this.elWidth | ||
this.canvas.height = this.elHeight | ||
this.el.appendChild(this.canvas) | ||
this.renderCtx = this.canvas.getContext('2d') | ||
this.canvas.addEventListener('click', e => { | ||
this.onCanvasClick(e) | ||
}) | ||
} | ||
this.renderCtx.clearRect(0, 0, this.elWidth, this.elHeight) | ||
this.run(words, list => { | ||
this.curRenderList = list | ||
list.forEach(item => { | ||
this.renderCtx.save() | ||
this.renderCtx.font = joinFontStr(item.fontStyle) | ||
this.renderCtx.fillStyle = item.color | ||
if (item.rotate === 0) { | ||
this.renderCtx.textBaseline = 'top' | ||
this.renderCtx.fillText(item.text, item.left, item.top) | ||
} else { | ||
const cx = item.left + item.width / 2 | ||
const cy = item.top + item.height / 2 | ||
this.renderCtx.translate(cx, cy) | ||
this.renderCtx.textAlign = 'center' | ||
this.renderCtx.textBaseline = 'middle' | ||
this.renderCtx.rotate((item.rotate * Math.PI) / 180) | ||
this.renderCtx.fillText(item.text, 0, 0) | ||
} | ||
this.renderCtx.restore() | ||
}) | ||
done(list) | ||
}) | ||
} | ||
// Canvas的点击事件 | ||
onCanvasClick(e) { | ||
const { left, top } = this.canvas.getBoundingClientRect() | ||
const x = e.clientX - left | ||
const y = e.clientY - top | ||
let res = null | ||
for (let i = 0; i < this.curRenderList.length; i++) { | ||
const item = this.curRenderList[i] | ||
this.renderCtx.save() | ||
this.renderCtx.font = joinFontStr(item.fontStyle) | ||
this.renderCtx.fillStyle = item.color | ||
this.renderCtx.textBaseline = 'top' | ||
this.renderCtx.beginPath() | ||
if (item.rotate === 0) { | ||
this.renderCtx.rect(item.left, item.top, item.width, item.height) | ||
} else { | ||
const textSize = getTextBoundingRect({ | ||
text: item.text, | ||
fontStyle: item.fontStyle, | ||
space: item.space | ||
}) | ||
const cx = item.left + item.width / 2 | ||
const cy = item.top + item.height / 2 | ||
this.renderCtx.translate(cx, cy) | ||
this.renderCtx.rotate((item.rotate * Math.PI) / 180) | ||
this.renderCtx.rect( | ||
-textSize.width / 2, | ||
-textSize.height / 2, | ||
textSize.width, | ||
textSize.height | ||
) | ||
} | ||
this.renderCtx.closePath() | ||
this.renderCtx.restore() | ||
const isIn = this.renderCtx.isPointInPath(x, y) | ||
if (isIn) { | ||
res = item | ||
break | ||
} | ||
} | ||
if (res && this.onClick) { | ||
this.onClick(res) | ||
} | ||
} | ||
// 导出画布,只有当使用renderUseCanvas方法渲染时才有效 | ||
// isDownload:是否直接触发下载,为false则返回data:URL数据 | ||
exportCanvas(isDownload = true, fileName = 'wordCloud') { | ||
if (!this.canvas) return null | ||
const res = this.canvas.toDataURL() | ||
if (isDownload) { | ||
downloadFile(res, fileName) | ||
} else { | ||
return res | ||
} | ||
} | ||
// 计算并使用DOM直接渲染到容器内 | ||
render(words, done = () => {}) { | ||
this.run(words, list => { | ||
this.curRenderList = [] | ||
list.forEach((item, index) => { | ||
@@ -163,3 +272,2 @@ const exist = this.wordItemElList[index] | ||
align-items: center; | ||
transition: ${this.transition}; | ||
left: ${this.elWidth / 2}px; | ||
@@ -178,2 +286,5 @@ top: ${this.elHeight / 2}px; | ||
}) | ||
wrap.addEventListener('click', () => { | ||
if (this.onClick) this.onClick(item) | ||
}) | ||
this.el.appendChild(wrap) | ||
@@ -186,2 +297,3 @@ } | ||
wrap.style.height = `${item.height}px` | ||
wrap.style.transition = this.transition | ||
@@ -209,2 +321,15 @@ inner.style.fontSize = `${item.fontStyle.fontSize}px` | ||
// 清除渲染 | ||
clear() { | ||
this.curRenderList = [] | ||
if (this.canvas) { | ||
this.el.removeChild(this.canvas) | ||
this.canvas = null | ||
this.renderCtx = null | ||
} else { | ||
this.el.innerHTML = '' | ||
this.wordItemElList = [] | ||
} | ||
} | ||
// 计算文本的位置 | ||
@@ -211,0 +336,0 @@ compute(wordItemList) { |
{ | ||
"name": "simple-word-cloud", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "一个简单的词云库", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -133,3 +133,3 @@ // 获取随机颜色 | ||
// 计算旋转后的矩形的宽高 | ||
export const getRotateBoundingRect = (width, height, rotate) => { | ||
export const getRotateBoundingRect = (width, height, rotate = 0) => { | ||
const rad = degToRad(rotate) | ||
@@ -153,1 +153,9 @@ const w = width * Math.abs(Math.cos(rad)) + height * Math.abs(Math.sin(rad)) | ||
} | ||
// 下载文件 | ||
export const downloadFile = (file, fileName) => { | ||
let a = document.createElement('a') | ||
a.href = file | ||
a.download = fileName | ||
a.click() | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21013
685