在微信小顺序中绘制图表(part3)

本期纲要

1、饼图绘制
2、怎样增加动画效果
3、运用rollup构建项目

相干浏览:
在微信小顺序中绘制图表(part1)
在微信小顺序中绘制图表(part2)

关注我的 github 项目 检察完全代码。

很久没更新了,近来事变比较多,本日来把坑填上!

饼图绘制

先看一下API

《在微信小顺序中绘制图表(part3)》

下面最先(运用ES6语法编写,背面我们可以运用rollup编译成ES5的语法)

假定我们有如许的数据

const series = [
    {data: 15, color: '#7cb5ec'},
    {data: 35, color: '#f7a35c'},
    {data: 78, color: '#434348'},
    {data: 63, color: '#90ed7d'}
];

盘算出各项所占的比例和最先的弧度

calPieData.js

export function calPieAngle (series) {
    // 盘算数据总和
    let count = 0;
    series.forEach((item) => {
        count += item.data;
    });

    // 盘算出最先的弧度和所占比例
    let startAngle = 0;
    return series.map((item) => {
        item.proportion = item.data / count;
        item.startAngle = startAngle;
        startAngle += 2 * Math.PI * item.proportion;
        return item;
    });
}

数据已盘算出来了,下面让我最先绘制吧

drawPieChart.js

import { calPieAngle } from 'calPieData'

export default function drawPieChart (series) {
    ...

    let pieSeries = calPieAngle(series);
    pieSeries.forEach((item) => {
        context.beginPath();
        // 设置添补色彩
        context.setFillStyle(item.color);
        // 移动到原点
        context.moveTo(100, 100);    
        // 绘制弧度
        context.arc(100, 100, 80, item.startAngle, item.startAngle + 2 * Math.PI * item.proportion);
        context.closePath();
        context.fill();
    });

    ...

}

挪用drawPieChart(series)就可以获得下面的效果:

《在微信小顺序中绘制图表(part3)》

很简朴是否是,下面我们给各区块加上一个白色的分割线
由于arc实际上是绘制了一条途径,所以我们简朴的stroke描边一下就可以了


...

context.setLineWidth(2);
context.setStrokeStyle('#ffffff');
pieSeries.forEach((item) => {
    context.beginPath();
    context.setFillStyle(item.color);
    context.moveTo(100, 100);    
    context.arc(100, 100, 80, item.startAngle, item.startAngle + 2 * Math.PI * item.proportion);
    context.closePath();
    context.fill();
    context.stroke();
})

...

《在微信小顺序中绘制图表(part3)》

增加动画效果

起首让我们建立一个动画东西,这个动画东西可以传入一些自定义的参数,比方动画时刻,可以有动画每一步的回调以及动画完毕的回调

animation.js

export default function Animation (opts) {
    // 处置惩罚用户传入的动画时刻,默以为1000ms
    // 由于用户有能够传入duration为0,所以不能用opts.duration = opts.duration || 1000 来做默认值处置惩罚
    // 不然用户传入0也会处置惩罚成默认值1000
    opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
    
    let startTimeStamp = null;

    function step (timestamp) {
        if (startTimeStamp === null) {
            startTimeStamp = timestamp;
        } 
        if (timestamp - startTimeStamp < opts.duration) {
            // 盘算出动画的进度
            let process = (timestamp - startTimeStamp) / opts.duration;
            // 触发动画每一步的回调,传入进度process
            opts.onProcess && opts.onProcess(process);
            // 动画举行中,实行下一次动画
            requestAnimationFrame(step);
        } else {
            // 动画完毕
            opts.onProcess && opts.onProcess(1);
            // 触发动画完毕回调
            opts.onAnimationFinish && opts.onAnimationFinish();
        }
    }

    requestAnimationFrame(step);
}

动画运用了requestAnimationFrame,而且已满足了我们上面定义的需求
在实战中,此处的动画都是线性的,平常我们还会到场缓动选项,比方缓入缓出,另有一点,在微信小顺序真机中IOS装备是不支撑requestAnimationFrame的,所以要做降级处置惩罚,运用setTimeout检察完全的代码

下面我们挪用animation来完成动画效果

app.js

import Animation from 'animation'
import drawPieChart from 'drawPieChart'

Animation({
    duration: 1000,
    onProcess: (process) => {
        drawPieDataChart(series, process);
    }
});

修正一下drawPieDataChart function,可以接收process参数


...

export default function drawPieChart (series, process = 1) {
    ...
    // 将process传入给calPieAngle,盘算出对应进度下的图表角度数据
    let pieSeries = calPieAngle(series, process);

...

一样,修正一下calPieAngle function,可以接收process参数


export function calPieAngle (series, process = 1) {
    ...

    // 盘算出最先的弧度和所占比例
    let startAngle = 0;
    return series.map((item) => {
        // 盘算出当前动画进度的比例
        item.proportion = item.data / count * process;
        item.startAngle = startAngle;
        startAngle += 2 * Math.PI * item.proportion;
        return item;
    });
}

好了,如今我们的动画就可以动起来了,相似如许

《在微信小顺序中绘制图表(part3)》

运用rollup构建项目

Rollup is a next-generation JavaScript module bundler. Author your app or library using ES2015 modules, then efficiently bundle them up into a single file for use in browsers and Node.js.

也就是说rollup是一个前端构建东西,可以将我们的悉数项目兼并输出成一个终究的编译效果,上面我们编写代码的时刻都是根据差别的功用放到差别的文件中,如许有利于后期的可持续性开辟和保护,rollup正好能协助我们构建出末了的编译效果

先装置rollup

npm install -g rollup

增加对ES6的支撑

npm install --save-dev rollup-plugin-babel
npm install --save-dev babel-preset-es2015-rollup

建立.babelrc文件在项目根目录,通知babel转义时运用哪一个presets

{
  "presets": ["es2015-rollup"],
}

好了剩下末了一步,定义我们的rollup.config.js配置文件

import babel from 'rollup-plugin-babel';

export default {
  // 进口文件
  entry: 'app.js',
  // 输出花样,这里运用commonJS
  format: 'cjs',
  // 输出文件
  dest: 'dist/charts.js',
  // 运用babel举行ES6转ES5
  plugins: [
      babel({
          exclude: 'node_modules/**',
      })
  ]
};

rollup会从进口文件最先,查找我们的依靠(import),逐级往下深切,把依靠的文件悉数网络起来并兼并到一同,末了输出到我们定义的dest文件中

实行

rollup -c

好了,我们就获得了我们末了的项目编译文件charts.js

下期预报

下一期中我一同议论下有技术含量的内容,关于图表中案牍显现的检测碰撞题目,也许效果会是如许的,红框部份案牍发生了碰撞,这里完成了躲避,可以一般显现

《在微信小顺序中绘制图表(part3)》

    原文作者:musiq1989
    原文地址: https://segmentfault.com/a/1190000007876976
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞