Introduction to Darwing
出自OpenFace
第十二章 绘图介绍
第二部分 教程介绍
OpenFace提供二维图形的性能,您可以在<draw>元素内使用程序代码画线并填充其内部,这章我们可以看API的相关部分并且可以从几行代码中看到有趣的效果。
目录 |
绘图
<drawview> 类继承<view>类,因此它继承了<view>的所有特性。<drawview>标签创建了一个矩形的视图,乍看视图彼此之间很相像:
Example 12.1. view and drawview
<canvas height="75">
<simplelayout spacing="5" axis="x"/>
<view height="50" width="50" bgcolor="red"/>
<drawview height="50" width="50" bgcolor="blue"/>
</canvas>
<drawview>类继承了<view>类的所有属性,此外,<drawview>除了继承的属性之外有四个自己的属性。
fillStyle
globalAlpha
lineWidth
strokeStyle
这些属性可以通过<drawview>元素内的<method>标签中的程序代码来存取和操作,<drawview>类有10个相关方法。
线,形状,填充
画一条线,您将笔放在一个起点上,然后以X和Y坐标点连接向直线或曲线那样移动。这样的线在您"stroke"之前仍是不可见的。当您一定义的线宽和类型画一条应用于这条线的路径后,这条线就可见了。
例如:下面代码产生的结果是不可见的
Example 12.2. invisble drawing
<canvas>
<drawview>
<handler name="oninit">
this.moveTo(100,100)
this.lineTo(200,100)
this.quadraticCurveTo(120, 200, 300, 100)
</handler>
</drawview>
</canvas>
但是我们可以添加this.stroke()这个方法,如下面的例子:
Example 12.3. stroking the line
<canvas height="200">
<drawview>
<handler name="oninit">
this.moveTo(100,100)
this.lineTo(200,100)
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke();
</handler>
</drawview>
</canvas>
closePath()方法可以使画出的线是闭合的路径:
Example 12.4. Closing the path
<canvas>
<drawview>
<handler name="oninit">
this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()
</handler>
</drawview>
</canvas>
既然是封闭的形状,我们就可以填充它。首先要定义一种填充颜色,然后填充这个图形。
Example 12.5. fillstyle
<canvas>
<drawview>
<handler name="oninit">
this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
//fillSytles are hex numbers representing color.
this.fillStyle = 0xff00ff
this.fill()
</handler>
</drawview>
</canvas>
需要注意如果没有封闭图形却调用了fill()方法,路径会自行封闭。特殊情形请参阅相关内容。
不透明性和渐变
属性 globalAlpha 被用于设置线和填充物的透明度。它的取值在0(透明)-1(不透明)之间。
Example 12.6. Using globalAlpha
<canvas height="200">
<drawview>
<handler name="oninit">
this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
this.fillStyle = 0xff00ff
this.globalAlpha= .3
this.fill()
</handler>
</drawview>
</canvas>
记住这里的代码是程序性的,因此在调用stroke()或fill() 方法时 alpha 的值就对fillStyles and lineStyles属性起作用。
填充色可以是颜色渐变,也就是作用在图形区域上的一种混合色彩。使用渐变首先要创建它使用适当的(线性的或放射性的)构造函数。继而设置属性fillStyle为渐变。渐变是LzCanvasGradient类型的一个对象;您可以使用定义addColorStop()方法来定义渐变参数。addColorStop() 使用两个参数:渐变停止的数值,渐变颜色。
Example 12.7. adding a gradient
<canvas height="200">
<drawview>
<handler name="oninit">
this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
//the gradient starts at the x and y where the curved line starts
var g = this.createLinearGradient(200,100, 150, 300)
//opacity is 0 -- the fill is invisible
this.globalAlpha = 0;
//starting color is black
g.addColorStop(0, 0x000000);
//now the opacity is set to opaque
this.globalAlpha = 1;
//the gradient goes from black to purple
g.addColorStop(1, 0xff00ff);
this.fillStyle = g;
this.fill();
</handler>
</drawview>
</canvas>
为了看看渐变什么效果,可以改变结束的'x','y'的值。
也要记得<drawviews>是有背景颜色的。可以结合渐变和alpha值使用背景色。
Example 12.8. backgrounds and gradients
<canvas height="200">
<drawview height="150" width="300" bgcolor="blue">
<handler name="oninit">
this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.stroke()
var g = this.createLinearGradient(200,100, 150, 300)
this.globalAlpha = 0;
g.addColorStop(0, 0xffffff);
this.globalAlpha = 1;
g.addColorStop(.3, 0xff00ff);
this.fillStyle = g;
this.fill();
</handler>
</drawview>
</canvas>
起点
我们已经提到过,话线就犹如移动一支笔。那么,您如何在画布上收起这支笔让它移动到另一个点呢?
Example 12.9. beginPath
<canvas height="200">
<drawview>
<handler name="oninit">
this.moveTo(100,100);
this.lineTo(200,100);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()
this.beginPath()
this.moveTo(200,000);
this.lineTo(100,200);
this.quadraticCurveTo(120, 200, 300, 100)
this.closePath()
this.stroke()
</handler>
</drawview>
</canvas>
可以用clear()方法去掉不要的图形。
Example 12.10. Clearing the veiw
<canvas height="200">
<drawview>
<handler name="oninit">
this.moveTo(40,40)
this.lineTo(80,40)
this.lineTo(80, 80)
this.lineTo(40,90)
this.closePath()
this.stroke()
this.fillStyle = 0xff00ff;
this.fill()
</handler>
<handler name="onkeydown" reference="LzKeys">
this.clear();
</handler>
</drawview>
</canvas>
在OpenFace应用中整合drawview
Example 12.11. Draview with animator
<canvas width="300" height="300">
<class name="circle" extends="drawview" >
<attribute name="circlecolor" value="white"/>
<attribute name="r" value="100"/>
<method name="redraw" ><![CDATA[
this.clear();
this.beginPath();
this.moveTo(x+r, y);
var a = Math.tan(22.5 * Math.PI/180);
for (var angle = 45; angle<=360; angle += 45) {
// endpoint:
var endx = r*Math.cos(angle*Math.PI/180);
var endy = r*Math.sin(angle*Math.PI/180);
// control:
// (angle-90 is used to give the correct sign)
var cx =endx + r*a*Math.cos((angle-90)*Math.PI/180);
var cy =endy + r*a*Math.sin((angle-90)*Math.PI/180);
this.quadraticCurveTo(cx+x, cy+y, endx+x, endy+y);
}
var g = this.createLinearGradient(0, 0, 8, x+r, y+r, 0)
this.globalAlpha = 1;
g.addColorStop(0, 0xffffff);
this.globalAlpha = 0;
g.addColorStop(1, this.circlecolor);
this.fillStyle = g;
this.fill()
this.globalAlpha = 1;
this.linewidth= 5;
this.stroke();
]]>
</method>
</class>
<circle r="50" x="60" y="60" circlecolor="blue" oninit="this.redraw()"/>
<circle x="60" y="60" circlecolor="teal" oninit="this.redraw()">
<animatorgroup process="sequential" repeat="Infinity">
<animator attribute="x" from="20" to="0" duration="3000"/>
<animator attribute="y" from="0" to="20" duration="3000"/>
</animatorgroup>
</circle>
</canvas>

