OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4489|回复: 0

带你走进绚丽多彩的柿饼M(4)

[复制链接]

55

主题

134

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
388
金钱
388
注册时间
2018-8-7
在线时间
55 小时
发表于 2018-10-30 10:42:11 | 显示全部楼层 |阅读模式
柿饼M之画布
上一节我们介绍了基本的动画操作,但那些都是针对已有的页面,图形对象的。本篇教程将向大家介绍如何在屏上实现自定义的绘画。
首先,要进行绘图必然得有一个绘图的目标区域,在PersimM中,可以在页面上单独提供一块画布,在这个画布上就可以进行绘图操作了。首先,我们在设计器上,在一个Page中添加一个Canvas对象,背景色设置为白色,字体选择hz 16,如下图所示。 lesson04_01.png
file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/lesson04_01.png?lastModify=1540866846
具体关于画布的API请查阅Canvas API文档
基于脚本的画布
在设计器中我们把"Canvas1"画布对象拖放出来,会发现它的区域默认是没有其他额外的显示。要对画布对象操作,我们必须使用脚本的方式,我们在脚本中可以通过以下的方式返回这个名字为"Canvas1"的画布对象:
var context = pm.createCanvas("Canvas1", this);一般的画布操作饼图
在这一小节中,我们将介绍如何在画布上绘制一个饼图:
var data = [ 20, 30, 40, 50, 60, 70 ];  //饼图数据
var colors = [ "#ff0000", "#ffff00", "#ff00ff", "#00ff00", "#00ffff", "#0000ff"];   //饼图颜色
var context = pm.createCanvasContext('Canvas1', this)   //获取画布对象
if (context)
{
    var total = 0;  //饼图数据总和
​
    for( var index = 0; index < data.length; index++ )
    {
        total += data[ index ];
    }
&#8203;
    var point = { x: 200, y: 200 };     //圆心坐标,相对于画布
    var radius = 150;                   //半径
    var start = -0.5 * Math.PI;         //起始弧度
&#8203;
    for( var i = 0; i < data.length; i++ )
    {
        var stop = start + data[ i ] / total * 2 * Math.PI;     //结束弧度
&#8203;
        context.beginPath();    //开始新的路径
&#8203;
        context.arc( point.x, point.y, radius, start, stop, false);     //画一段圆弧
&#8203;
        context.lineTo( point.x, point.y );     //连接圆弧终点和圆心
        context.setFillStyle( colors[ i ] );    //设置填充颜色
        context.fill();                         //填充路径
&#8203;
        context.closePath();                    //关闭路径
        start = stop;                           //起始弧度更新
    }
&#8203;
    context.draw();     //更新画布
}
直接放到板子上,看看运行的效果,运行效果如下: lesson04_02.png
file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/lesson04_02.png?lastModify=1540866846
  • 实际效果

demo1.png

file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/photo/lesson4/demo1.png?lastModify=1540866846
柱形图
在这一小节中,我们将介绍如何在画布上绘制一份表示一年的月用电量的柱形图:

var index = 0
var data = [ 20, 30, 40, 50, 32, 56, 12, 34, 21, 23, 13, 46 ];  //柱形图数据
var context = pm.createCanvasContext('Canvas1', this)           //获取画布对象
if (context)
{
    var max = 0;
&#8203;
    for( index = 0; index < data.length; index++ )
    {
        max = data[index] > max ? data[index] : max;
    }
&#8203;
    max = Math.floor(max / 6);
&#8203;
    /* 画浅灰色横线 */
    context.beginPath();                //开启新路径
    context.setStrokeStyle('#C0C0C0')   //设置边框颜色
&#8203;
    for( index = 0; index < 7; index++ )
    {
        var y = 30 + index * 50;
        context.moveTo(60, y)                   //线条起点
        context.lineTo(60 + 12 * 28 + 14, y)    //线条终点
    }
&#8203;
    context.stroke()        //画线
    context.closePath();    //关闭当前路径
&#8203;
    /* 画横纵坐标刻度 */
    context.beginPath();            //开启新路径
    context.setStrokeStyle('black') //设置边框颜色
&#8203;
    context.fillText('用电量(度)', 5, 5)    //绘制文字,坐标(5,5)
&#8203;
    context.setTextBaseline('middle')         //设置文本绘制纵坐标对齐方式
    for( index = 0; index < 7; index++ )
    {
        var y = 30 + index * 50;
        var value = max * (7 - index);
        /*纵坐标刻度*/
        context.moveTo(55, y)
        context.lineTo(60, y)
        context.fillText(value.toString(), 20, y)
    }
&#8203;
    context.moveTo(55, 30 + index * 50)
    context.lineTo(60, 30 + index * 50)
    context.fillText('0', 20, 30 + index * 50)
&#8203;
    context.moveTo(60, 30)
    context.lineTo(60, 30 + index * 50)
&#8203;
    context.moveTo(60, 30 + index * 50)
    context.lineTo(60 + 12 * 28 + 14, 30 + index * 50)
&#8203;
    context.setTextAlign('center')  //设置文本绘制横坐标对齐方式
&#8203;
    for( index = 1; index <= 12; index++ )
    {
        var x = 60 - 14 + index * 28;
        /*横坐标刻度*/
        context.moveTo(x, 380)
        context.lineTo(x, 385)
        context.fillText(index.toString(), x, 395)
    }
&#8203;
    context.setTextAlign('left')    //设置文本绘制横坐标对齐方式
    context.fillText('时间(月)', 60 + 12 * 28 + 14, 390)
    context.stroke()
    context.closePath();
&#8203;
    /* 画柱形 */
    context.beginPath();
    context.setStrokeStyle('#0094FF')
    context.setLineWidth(18)        //设置线条宽度
&#8203;
    for( index = 0; index < data.length; index++ )
    {
        var x = 60 - 14 + 28 + index * 28;
        var y = data[index] * 350 / (max * 7)
        context.moveTo(x, 380)
        context.lineTo(x, 380 - y)
    }
&#8203;
    context.stroke()
    context.closePath();
&#8203;
    context.draw();
}
直接放到板子上,看看运行的效果,运行效果如下: lesson04_03.png
file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/lesson04_03.png?lastModify=1540866846
  • 实际效果

demo2.png

file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/photo/lesson4/demo2.png?lastModify=1540866846
仪表盘
在这一小节中,我们将介绍如何在画布上绘制一份仪表盘:

var context = pm.createCanvasContext('Canvas1', this)   //获取画布对象
if (context)
{
    var point = { x: 200, y: 200 };     //圆心坐标,相对于画布
    var radius = 150;                   //半径
    var start = -1.25 * Math.PI;        //起始弧度
&#8203;
    context.setLineWidth(30)
    context.setStrokeStyle('#91C7AE')
    context.setFillStyle('#91C7AE');
&#8203;
    for( var i = 0; i <= 10; i++ )
    {
        var stop = start + 0.15 * Math.PI ;     //结束弧度
        var x = Math.floor(130 * Math.cos(start)) + 200;
        var y = Math.floor(130 * Math.sin(start)) + 200;
        var v = 10 * i;
&#8203;
        if (i >= 5)
            context.fillText(v.toString(), x - 20, y);
        else
            context.fillText(v.toString(), x, y);
&#8203;
        if (i == 10)
            break;
&#8203;
        context.beginPath();    //开始新的路径
&#8203;
        context.arc( point.x, point.y, radius, start, stop - 0.003 * Math.PI, false);     //画一段圆弧
&#8203;
        context.stroke();                         //填充路径
&#8203;
        context.closePath();                    //关闭路径
        start = stop;
&#8203;
        if (i == 1)
        {
            context.setStrokeStyle('#63869E')
            context.setFillStyle('#63869E');
        }
        else if (i == 7)
        {
            context.setStrokeStyle('#C23531')
            context.setFillStyle('#C23531');
        }
    }
&#8203;
    radius = 170;
    start = -1.25 * Math.PI;
    context.setLineWidth(22)
    context.setStrokeStyle('#91C7AE')
&#8203;
    for( var i = 0; i < 50; i++ )
    {
        var stop = start + 0.03 * Math.PI ;
&#8203;
        context.beginPath();
&#8203;
        context.arc( point.x, point.y, radius, start, stop - 0.003 * Math.PI, false);
&#8203;
        context.stroke();
&#8203;
        context.closePath();
        start = stop;
&#8203;
        if (i == 9)
        {
            context.setStrokeStyle('#63869E')
        }
        else if (i == 39)
        {
            context.setStrokeStyle('#C23531')
        }
    }
&#8203;
    {   //画指针
        var value = 60;     //表盘当前值
        var radius = 130;
        var x = Math.floor(radius * Math.cos((-1.25 * Math.PI + value * 1.5 * Math.PI / 100))) + point.x;
        var y = Math.floor(radius * Math.sin((-1.25 * Math.PI + value * 1.5 * Math.PI / 100))) + point.y;
&#8203;
        context.beginPath();
&#8203;
        context.setFillStyle('#91C7AE');
        context.moveTo(x, y)
&#8203;
        radius = 10;
        x = Math.floor(radius * Math.cos((-0.75 * Math.PI + value * 1.5 * Math.PI / 100))) + point.x;
        y = Math.floor(radius * Math.sin((-0.75 * Math.PI + value * 1.5 * Math.PI / 100))) + point.y;
        context.lineTo(x, y);
&#8203;
        radius = 20;
        x = Math.floor(radius * Math.cos((-0.25 * Math.PI + value * 1.5 * Math.PI / 100))) + point.x;
        y = Math.floor(radius * Math.sin((-0.25 * Math.PI + value * 1.5 * Math.PI / 100))) + point.y;
        context.lineTo(x, y);
&#8203;
        radius = 10;
        x = Math.floor(radius * Math.cos((0.25 * Math.PI + value * 1.5 * Math.PI / 100))) + point.x;
        y = Math.floor(radius * Math.sin((0.25 * Math.PI + value * 1.5 * Math.PI / 100))) + point.y;
        context.lineTo(x, y);
&#8203;
        context.fill();
&#8203;
        context.setTextAlign('center')
        context.fillText(value.toString(), 200, 250)
&#8203;
        context.closePath();
    }
&#8203;
    context.draw();
}
直接放到板子上,看看运行的效果,运行效果如下: lesson04_04.png
file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/lesson04_04.png?lastModify=1540866846
  • 实际效果

demo3.png

  • file:///F:/file/Desktop/%25E6%259F%25BF%25E9%25A5%25BC%25E5%2590%2588%25E8%25BE%2591/PersimmonM%25E5%2590%2588%25E8%25BE%2591/PersimmonM/figures/photo/lesson4/demo3.png?lastModify=1540866846

[size=0.9][
[size=1em]1
]    figures/photo/lesson4/demo1.png
[size=0.9][
[size=1em]2
]    figures/photo/lesson4/demo2.png
[size=0.9][
[size=1em]3
]    figures/photo/lesson4/demo3.png
论坛二维码.jpg

demo1.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-2 08:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表