likes
comments
collection
share

用 G2 绘制一个动态爱心效果

作者站长头像
站长
· 阅读数 36

某天看到公众号的推送文章《用 Python 制作一个动态爱心效果》,感觉挺有意思,所以想用 G2 5.0 可视化的思维方式去实现一下。

用 G2 绘制一个动态爱心效果

这个图使用可视化的思维去实现的话,大概的逻辑是:

  1. 找到一个心形函数,可以生成这个图形
  2. 基于这个函数,随机产生 5000 个点,这样的话,这些点就可以拼凑出心形的形状
  3. 在具体坐标点绘制的时候,可以加一个随机函数,讲点随机散开

直接贴代码:

import { Chart } from '@antv/g2';
import { randomExponential } from 'd3-random'

const random = randomExponential(5, [0, 1]);
const direction = () => Math.random() > 0.5 ? 1 : -1

const chart = new Chart({
  container: 'container',
  autoFit: true,
});

const SAMPLE = 5000;
const HEART_COLOR = "#ff2121"  // 心的颜色,这个是中国红
const JITTER_RATIO = 0.2;

function point(angle) {
  const a = 6;
  const x = a * (16 * Math.sin(angle) ** 3);
  const y =
    a *
    (13 * Math.cos(angle) -
      5 * Math.cos(2 * angle) -
      2 * Math.cos(3 * angle) -
      Math.cos(4 * angle));
  return { x, y };
}

function getHeartPoints() {
  return new Array(SAMPLE).fill(0).map(() => point(Math.random() * 2 * Math.PI))
}

chart
  .point()
  .data(getHeartPoints())
  .encode('x', 'x')
  .encode('y', 'y')
  .encode('shape', 'point')
  .encode('color', HEART_COLOR)
  .encode('size', 1)
  .transform({ type: Jitter })
  .axis(false);

chart.render();

function Jitter() {
  return (I, mark) => {
    const { encode } = mark;
    const { x, y } = encode;
    const X = x.value;
    const Y = y.value;

    X.forEach((v, idx) => {
      X[idx] = v += (v * random() * JITTER_RATIO * direction())
    });

    Y.forEach((v, idx) => {
      Y[idx] = v += (v * random() * JITTER_RATIO * direction())
    });

    return [I, mark];
  };
}
  • 这里面 getHeartPoints就是心形函数,随机生成数据
  • 然后最后加了一个 Jitter 函数,为了让数据散开的时候,散开越远的点越少,所以使用了 exp 的 random 函数。

最后的效果如下,也可以把上面的代码贴到 G2 官网示例 中调参获得更好的效果。

用 G2 绘制一个动态爱心效果

总结

G2 可视化的思维方式,其实很简单,就是使用数据去驱动图形的属性,然后在渲染之前需要额外做一下调整(比如随机)就使用 transform。

再次感谢文章《用 Python 制作一个动态爱心效果》提供的思路。

转载自:https://juejin.cn/post/7176069612897828923
评论
请登录