deep-viz
Version:
A React component library, provide concise and beautiful diversity charts with Canvas, SVG, E-map, WebGL, Dom, based on data visualization experience and commercial data display practice.
104 lines (101 loc) • 3.23 kB
JavaScript
import React from 'react';
class HotWords extends React.Component {
constructor() {
super();
this.id = `${Math.random()}-canvas`;
this.scaleRatio = 2;
this.colors = [
'#FDB933',
'#D64F44',
'#00A6AC',
'#1D953F',
'#E0861A',
'#45B97C',
'#F3715C',
'#F26522',
'#7FB80E',
'#63C5FA',
];
this.textArray = [];
this.Text = function (text, x, y, vx, vy, color, font, context) {
this.text = text;
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.color = color;
this.font = font;
this.context = context;
};
this.Text.prototype.fillText = function () {
this.context.beginPath();
this.context.save();
this.context.fillStyle = this.color;
this.context.font = this.font;
this.context.fillText(this.text, this.x, this.y);
this.context.restore();
};
}
componentDidMount() {
this.canvas = document.getElementById(this.id);
this.context = this.canvas.getContext('2d');
const styleDom = window.getComputedStyle(this.canvas.parentNode);
const width = Math.floor(window.parseInt(styleDom.width));
const height = Math.floor(window.parseInt(styleDom.height));
this.canvas.style.width = `${width}px`;
this.canvas.style.height = `${height}px`;
this.props.circleOutline && (this.canvas.style.borderRadius = '50%');
this.canvas.width = width * this.scaleRatio;
this.canvas.height = height * this.scaleRatio;
this.context.shadowOffsetX = 5;
this.context.shadowOffsetY = 5;
this.context.shadowBlur = 5;
this.context.shadowColor = 'rgba(0, 0, 0, 0.5)';
this.context.textAlign = 'center';
this.context.textBaseline = 'middle';
const x = this.canvas.width / 2;
const y = this.canvas.height / 2;
this.worlds = this.props.words || [];
const angle = Math.PI * 2 / this.worlds.length;
const baseSpeed = this.props.speed || 3;
let currentAngle = 0;
this.worlds.forEach((it) => {
currentAngle += angle;
const vx = baseSpeed * Math.cos(currentAngle);
const vy = baseSpeed * Math.sin(currentAngle);
const text = new this.Text(
it,
x,
y,
vx,
vy,
this.colors[Math.floor(Math.random() * 11)],
`${Math.floor(Math.random() * 30 + 30)}px serial`,
this.context,
);
this.textArray.push(text);
});
const animation = () => {
this.context = this.canvas.getContext('2d');
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
for (let i = this.textArray.length - 1; i >= 0; i--) {
const it = this.textArray[i];
if (it.x > width * 2 || it.x < 0 || it.y > height * 2 || it.y < 0) {
it.x = x;
it.y = y;
}
it.x += it.vx;
it.y += it.vy;
it.fillText();
}
window.requestAnimationFrame(animation);
};
animation();
}
render() {
return (<div style={{ position: 'relative', width: '100%', height: '100%' }}>
<canvas id={this.id}>对不起,您的浏览器不支持canvas</canvas>
</div>);
}
}
export default HotWords;