柿饼M之画布 上一节我们介绍了基本的动画操作,但那些都是针对已有的页面,图形对象的。本篇教程将向大家介绍如何在屏上实现自定义的绘画。 首先,要进行绘图必然得有一个绘图的目标区域,在PersimM中,可以在页面上单独提供一块画布,在这个画布上就可以进行绘图操作了。首先,我们在设计器上,在一个Page中添加一个Canvas对象,背景色设置为白色,字体选择hz 16,如下图所示。
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 基于脚本的画布在设计器中我们把"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 ];
}
​
var point = { x: 200, y: 200 }; //圆心坐标,相对于画布
var radius = 150; //半径
var start = -0.5 * Math.PI; //起始弧度
​
for( var i = 0; i < data.length; i++ )
{
var stop = start + data[ i ] / total * 2 * Math.PI; //结束弧度
​
context.beginPath(); //开始新的路径
​
context.arc( point.x, point.y, radius, start, stop, false); //画一段圆弧
​
context.lineTo( point.x, point.y ); //连接圆弧终点和圆心
context.setFillStyle( colors[ i ] ); //设置填充颜色
context.fill(); //填充路径
​
context.closePath(); //关闭路径
start = stop; //起始弧度更新
}
​
context.draw(); //更新画布
}直接放到板子上,看看运行的效果,运行效果如下:
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
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;
​
for( index = 0; index < data.length; index++ )
{
max = data[index] > max ? data[index] : max;
}
​
max = Math.floor(max / 6);
​
/* 画浅灰色横线 */
context.beginPath(); //开启新路径
context.setStrokeStyle('#C0C0C0') //设置边框颜色
​
for( index = 0; index < 7; index++ )
{
var y = 30 + index * 50;
context.moveTo(60, y) //线条起点
context.lineTo(60 + 12 * 28 + 14, y) //线条终点
}
​
context.stroke() //画线
context.closePath(); //关闭当前路径
​
/* 画横纵坐标刻度 */
context.beginPath(); //开启新路径
context.setStrokeStyle('black') //设置边框颜色
​
context.fillText('用电量(度)', 5, 5) //绘制文字,坐标(5,5)
​
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)
}
​
context.moveTo(55, 30 + index * 50)
context.lineTo(60, 30 + index * 50)
context.fillText('0', 20, 30 + index * 50)
​
context.moveTo(60, 30)
context.lineTo(60, 30 + index * 50)
​
context.moveTo(60, 30 + index * 50)
context.lineTo(60 + 12 * 28 + 14, 30 + index * 50)
​
context.setTextAlign('center') //设置文本绘制横坐标对齐方式
​
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)
}
​
context.setTextAlign('left') //设置文本绘制横坐标对齐方式
context.fillText('时间(月)', 60 + 12 * 28 + 14, 390)
context.stroke()
context.closePath();
​
/* 画柱形 */
context.beginPath();
context.setStrokeStyle('#0094FF')
context.setLineWidth(18) //设置线条宽度
​
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)
}
​
context.stroke()
context.closePath();
​
context.draw();
}直接放到板子上,看看运行的效果,运行效果如下:
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
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; //起始弧度
​
context.setLineWidth(30)
context.setStrokeStyle('#91C7AE')
context.setFillStyle('#91C7AE');
​
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;
​
if (i >= 5)
context.fillText(v.toString(), x - 20, y);
else
context.fillText(v.toString(), x, y);
​
if (i == 10)
break;
​
context.beginPath(); //开始新的路径
​
context.arc( point.x, point.y, radius, start, stop - 0.003 * Math.PI, false); //画一段圆弧
​
context.stroke(); //填充路径
​
context.closePath(); //关闭路径
start = stop;
​
if (i == 1)
{
context.setStrokeStyle('#63869E')
context.setFillStyle('#63869E');
}
else if (i == 7)
{
context.setStrokeStyle('#C23531')
context.setFillStyle('#C23531');
}
}
​
radius = 170;
start = -1.25 * Math.PI;
context.setLineWidth(22)
context.setStrokeStyle('#91C7AE')
​
for( var i = 0; i < 50; i++ )
{
var stop = start + 0.03 * Math.PI ;
​
context.beginPath();
​
context.arc( point.x, point.y, radius, start, stop - 0.003 * Math.PI, false);
​
context.stroke();
​
context.closePath();
start = stop;
​
if (i == 9)
{
context.setStrokeStyle('#63869E')
}
else if (i == 39)
{
context.setStrokeStyle('#C23531')
}
}
​
{ //画指针
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;
​
context.beginPath();
​
context.setFillStyle('#91C7AE');
context.moveTo(x, y)
​
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);
​
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);
​
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);
​
context.fill();
​
context.setTextAlign('center')
context.fillText(value.toString(), 200, 250)
​
context.closePath();
}
​
context.draw();
}直接放到板子上,看看运行的效果,运行效果如下:
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
[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
|