作者:心叶
时间:2020-09-01 00:13

  • 开源不易,去Github给个_Star_吧!

我们演示如何绘制一个圆弧。

因为位图的画布是基于Canvas,而矢图基于SVG,因此我们需要先假设页面有一个SVG标签。

获取画笔

var painter=$$('svg').attr({ "width":300, "height":300 }).painter();

可以看到,除了传递的结点变成了SVG外没有区别,我们同样设置了画布大小。

配置画笔

painter.config({ 'strokeStyle':'red', 'lineWidth':3, 'lineDash':[5] });

绘制简单图形

画笔获取并配置好了以后,同样的,我们直接调用画笔上的方法试试:

painter.strokeArc(150, 150, 100, 130, Math.PI/2, Math.PI/2*3);

很可惜,报错了(打开浏览器控制台查看):

Uncaught Error: Need a <path> ! 
    at t (image2d:17) at Object.t \[as strokeArc\] (image2d:17) 
    at example\-2.html:40

通过打印的错误提示可以看到,我们缺乏一个path结点,为什么会这样,不是已经有画布了吗?

SVG和Canvas画布的区别

由于Canvas是位图,绘制类似在一块画布上不停的涂鸦,而SVG有点类似普通的HTML类型标签(比如输入框是input),SVG绘制的各种图形其实也需要对应页面中一个SVG类型标签,上面就是对应一个path标签。

因此,我们把最后一行绘制的方法稍微改造一下(下面涉及的bind和appendTo方法请查看矢图画笔一节中的说明):

painter
    .bind('<path>') 
    .appendTo() 
    .strokeArc(150, 150, 100, 130, Math.PI/2, Math.PI/2\*3);

再次运行,一个圆弧就绘制好了,可以点击此处查看运行效果。

数据绑定

接下来我们要演示如何使用SVG画布快速的绘图,相关的API请点击此处查阅。

如何快速绘制柱状图

假设现在我们有一堆数据:

// 准备好数据 
var datas =[220,182,191,234,290,330,310,123,442,321,90,149,210,122,133,334,198,123,125,220\];

通过前面我们已经知道了,因为柱状图其实就是一个个小矩形(也就是rect),因此我们首先需要让页面中rect的个数和数组中元素的个数一样:

// 首先查找页面中的rect 
var imageObject = $$('rect'); 
// 然后把数据绑定到rect结点上,返回的是更新对象 
var update = imageObject.data(datas); 
// 因为页面中rect结点可能不够,不足的进行补充 
var enter = update.enter('<rect>').appendTo('svg');

这个时候你通过浏览器调试工具的Elements来查看rect结点个数,发现已经和数据对应起来了。

// 一切准备好了,进行绘制 
$$([imageObject, enter]).loop(function (data, index, target) { 
    // 绘制图像 
    // data是当前结点对象target维护的数据,index是当前结点对象序号 
    painter.bind(target).fillRect(index * 30 + 5, 500 - data, 20, data); 
});

至此,柱状图就绘制完成了,可以点击此处查看运行效果。

看到这里,你可能直接使用for循环等也可以很轻松的实现,可是,如果我们的数据是随机生成的,而且每隔一段时间就改变一下滴?接着看。

数据个数动态改变如何绘制

比如我们通过下面的方法随机生成datas,数据的个数和内容都随机改变的:

// 先确定条目个数 
var num = (Math.random() * 30).toFixed(0) - -5; 
var datas = []; 
for (let i = 0; i < num; i++) { 
    datas.push(Math.random() * 500); 
}

每隔一段实现重新根据datas绘制,可是数据的个数不定,因此,现在的情况变了,rect除了不足需要补充外,也可能需要把多余的删除了,我们把调整元素的那段代码改造一下:

// 首先查找页面中的rect 
var imageObject = $$('rect'); 

// 然后把数据绑定到rect结点上,返回的是更新对象 
var update = imageObject.data(datas); 

// 多余的删除 
update.exit().remove(); 

// 因为页面中rect结点可能不够,不足的进行补充 
var enter = update.enter('<rect>').appendTo('svg');

对比一下可以看出来,其实就是多了第三行代码(多余的删除)。余下绘制的方法和上面的几乎一样,就不再赘述了。

你可以点击此处查看运行效果。怎么样,是不是挺简单的,数据绑定就是专门对齐结点和数据个数的一系列方法的集合。


心叶
304 声望114 粉丝

我还惊讶地意识到, 在我生命中有很多时刻, 每当我遇到一个遥不可及、令人害怕的情境,并感到惊慌失措时, 我都能够应付——因为我回想起了很久以前自己上过的那一课。