提高篇Word文档下载推荐.docx

上传人:b****5 文档编号:19139691 上传时间:2023-01-04 格式:DOCX 页数:27 大小:69.37KB
下载 相关 举报
提高篇Word文档下载推荐.docx_第1页
第1页 / 共27页
提高篇Word文档下载推荐.docx_第2页
第2页 / 共27页
提高篇Word文档下载推荐.docx_第3页
第3页 / 共27页
提高篇Word文档下载推荐.docx_第4页
第4页 / 共27页
提高篇Word文档下载推荐.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

提高篇Word文档下载推荐.docx

《提高篇Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《提高篇Word文档下载推荐.docx(27页珍藏版)》请在冰豆网上搜索。

提高篇Word文档下载推荐.docx

r、g、b、alpha的值,其范围均是是(0——255)。

有了这样的理论逻辑我们可以通过canvas上的任意一点(x,y)计算出imageData中表示次像素的第一个元素的索引值。

计算方式如下代码:

functiongetStartIndex(x,y){

returny*width*4+x*4;

}

有了上面的理论知识,大家应该知道我们下面要做什么了吧?

对就是利用中点画圆算法对每一个像素进行颜色值(rgb)的修改。

2.光栅学——中点画圆

首先我们通过圆的对称性将其分为8个部分。

现在我们假设,这个圆的中点位于(0,0)的位置。

设d是点p(x,y)到圆心的距离:

则我们得到这样的圆方程FX(X,Y) 

=d。

这里我们按照Bresenham算法,推出:

(此部分可能需要有图形学学习经验的同学,再以后的随笔中可能会介绍Bresenham算法)。

如果dM<

0,表示下一点M在圆内,得

如果dM>

0,表示下一点M在圆外,得

有了上面的理论知识,我们就可以轻松的写出绘制圆的算法了:

//中点画圆法

functioncircle(x,y,r,color){

vartx=0,ty=r,d=1-r;

while(tx<

=ty){

//利用圆的八分对称性画点

putpixel(x+tx,y+ty,color);

putpixel(x+tx,y-ty,color);

putpixel(x-tx,y+ty,color);

putpixel(x-tx,y-ty,color);

putpixel(x+ty,y+tx,color);

putpixel(x+ty,y-tx,color);

putpixel(x-ty,y+tx,color);

putpixel(x-ty,y-tx,color);

if(d<

0){

d+=2*tx+3;

}else{

d+=2*(tx-ty)+5;

ty--;

}

tx++;

putpixel函数用于将每一个像素的颜色值填入对应的数组当中,这里我们的颜色只表示灰度值,因为还没有对彩色做任何处理。

functionputpixel(x,y,color){

varindex=getStartIndex(x,y);

for(vari=0;

i<

4;

i++){

if(i==3){

imageData[index+i]=255;

else{

//varco=parseInt(Math.random()*255)

imageData[index+i]=color;

至此我们就已经把一个圆的像素填入我们的像素数组当中,最后将像素对象放回原来的canvas当中,就实现了圆的光栅画法:

cxt.putImageData(data,0,0);

3.案例 

下面这个案例以1w个圆的边界碰撞检测运动为例,说明了我们实现的光栅图形性能完全可以胜任各种bt场景。

(首要推荐chrome18其他浏览器可能解析js代码比较慢)

开始停止

下次提高班预告:

实现光栅算法中的画线算法。

本课题是我今年毕业设计的课题,现在我边做边跟大家分享,希望能通过“canvas矢量图形渲染器”让大家对canvas元素和其中的性能优化有更深的理解。

1.首先说说这个矢量渲染器是什么。

canvas元素封装了很对对图形绘制的接口,但是他跟flex相比最大的区别是我们通过fill()或是stroke()方法绘制的图形是一张像素图片,当放大或是缩小的时候会出现模糊等各种状况。

所以直接调用canvasAPI来绘制矢量图形非常不合适。

这样我们就需要设计一渲染器,里面封装了各种图形的绘制接口,并通过调用渲染器的绘制方法按照我们想发来绘制每一个矢量元素。

每一个矢量元素都是一个继承自矢量图形基类的对象,比如可以使点,线,面等。

每一个图形有自己的大小和位置信息,我们依次把每个图形送入渲染器,渲染器结合自己当前的属性(缩放百分比,中心点等)就可以计算出每一个图形需要绘制的真实像素位置,之后再调用canvas的底层API实现图形的绘制。

基本的类图结构如下(在设计的过程当中可能会增加一些新的功能类):

 

一些点、线、面的基本矢量元素继承自Geometry类,Geometry定义了矢量图形的形状信息。

同时也是Vector类的一个属性,Vector类里面还包括矢量元素的其他信息(如id、添加时间等)。

Layer类表示了当前图层的一些基本信息,例如声明了一个图层(大小是400px*400px),同时我在坐标为(0,0)的点放置了一个半径为50px的圆,当前的缩放为100%,视图中心点也是(0,0)则我们会得到下面的这样一张图片:

注:

Layer类所表示的属性:

外侧的方框代表当前的视图范围(viewBounds),坐标(0,0)点则代表视图的中心点(center),zoom的值代表当前的缩放百分比。

Vector类所表示的属性:

拥有一个Geometry属性表示半径为70像素的圆,且拥有一个Style属性表示填充的颜色为橙色。

下面说说Layer类,Vector类和Canvas类是如何协调工作的:

Canvas类也就是渲染器类,是本课题的核心,其中定义了各种绘制Geometry图形的方法。

但是我们该如何调用他进行绘制呢?

1.我们声明一个Vector类的实例V1(他表示一个矢量图形,其形状信息保存在Geometry属性当中)。

2.我们的Layer类必然有一个接口,用于接收由Vector声明的实例V1(比如addVectors方法),当我们把所有的矢量图形都接收到Layer当中后,我们就想要在浏览器当中看到我们所创建的的矢量图形。

3.之后我们就应该请渲染器类出场了,他接收了Layer的所有矢量图形的引用、当前的缩放级别、当前的视图范围和当前的中心点,之后渲染器通过一大堆的计算就神奇的把Geometry中的属性变成了CanvasAPI中可以调用的数据。

就拿上个例子来说圆的中心点是(0,0),半径是70像素,通过渲染器的一系列计算最后我们会调用“context.arc(200,200,70,Math.PI*2,true);

context.fill()”这两句代码。

(200,200)这两个位置便是渲染器所要计算的绘制中心点,而70这个半径参数是通过70*zoom(当前为100%)得到的。

当然我们不能单单考虑这么简单的一种情况,后面会跟大家介绍这些Geometry对应的点到底是如何计算的。

2.从构建基本的几何基类、点开始。

1.geometry类。

这个类是一个几何图形的基类。

functionGeometry(){

this.id=CanvasSketch.getId("

geomtry_"

//bounds属性定义了当前Geometry外接矩形范围。

Geometry.prototype.bounds=null;

//定义Geometry的id属性。

Geometry.prototype.id=null;

//定义对bounds基类克隆的方法

Geometry.prototype.clone=function(){

returnnewGeometry();

//销毁当前的Geometry

Geometry.prototype.destroy=function(){

this.bounds=null;

this.id=null;

其中的SketchCanvas.getId方法会返回一个唯一的id值。

这个方法其实很简单就是用一个全局变量不断加1(后面的下载中有提供)。

2.Point类,继承自Geometry。

point类作为继承自Geometry最简单的类,我们首先来介绍他。

functionPoint(x,y){

Geometry.apply(this,arguments);

this.x=x;

this.y=y;

Point.prototype=newGeometry();

//point类的横坐标。

Point.prototype.x=null;

//point类的纵坐标。

Point.prototype.y=null;

//得到点的范围。

Point.prototype.getBounds=function(){

if(!

this.bounds){

varx=this.x;

vary=this.y;

this.bounds=newCanvasSketch.Bounds(x,y,x,y);

returnthis.bounds;

}else{

//clone方法。

Point.prototype.clone=function(){

returnnewPoint(this.x,this.y);

这个Point类定义了几个比较基本,简单的方法:

getBounds、clone,使用prototype进行对Geometry类的继承。

最重要的是Point会接受两个参数(x、y)也就是其位置信息。

这样我们就可以用以下的语句声明一个点了:

varpoint=newPoint(0,0);

这样的声明让我们的程序看起来更加简洁,扩展性会更强。

点在图形当中所充当的是一个无大小、只表示位置的几何对象。

但是,通常我们需要为点设置一个半径,以便让大家可以看到。

所以说点在任何缩放级别下的半径大小都是一个固定的像素值。

同样,线的宽度也可以这样理解。

3.添加、显示矢量图形

上面我们已经讲了如何创建一个矢量的点,但是我们该如何把这个点显示到我们的浏览器当中呢?

一个方法就是把这些矢量图形先存放到一个图层当中,这个图层中的一些属性(中心点、缩放百分比、视图范围)共同影响着矢量图形的显示结果。

当然我们可以将绘制的核心代码写到这个图层类当中,但是更好的做法就是用一个渲染器类控制关于显示的方法,使以后可以更好的维护、扩展。

1.图层类

这个课题的第一节,我们的图层类只有几个必须的方法,以控制添加、显示。

在以后的随笔中会更深入的增加图层的功能。

(同样渲染器类也是如此)

//图层类

functionLayer(div){

varstyle=div.style;

varsize=newCanvasSketch.Size(parseInt(style.width),parseInt(style.height));

this.size=size;

this.div=div;

this.maxBounds=newCanvasSketch.Bounds(-size.w/2,-size.h/2,size.w/2,size.h/2);

this.bounds=newCanvasSketch.Bounds(-size.w/2,-size.h/2,size.w/2,size.h/2);

this.zoom=100;

this.vectors={};

//加入矢量图形的总个数。

this.vectorsCount=0;

//创建一个渲染器。

this.renderer=newCanvas(this);

Layer.prototype.addVectors=function(vectors){

this.renderer.lock=true;

for(vari=0,len=vectors.length;

i<

len;

if(i==len-1){this.renderer.lock=false;

this.vectors[vectors[i].id]=vectors[i];

this.drawVector(vectors[i]);

this.vectorsCount+=vectors.length;

Layer.prototype.drawVector=function(vector){

vector.style){

style=newCanvasSketch.defaultStyle();

this.renderer.drawGeometry(vector.geometry,style);

定义过图层类后,我们就可以为一个div创建图层。

首先我们得在DOM树中创建一个div,作为图层的容器,如:

<

bodyonload="

init()"

>

<

divstyle="

width:

400px;

height:

300px;

"

id="

renderer"

/div>

/body>

这样我们就可以在init函数中为这个id为“renderer”的div创建图层了:

vardiv=document.getElementById("

varlayer=newLayer(div);

之后我们所要做的就是声明一个矢量图形数组,调用layer.addVectors来为我们的图层添加矢量元素。

for(vari=0;

1000;

varpoint=newPoint((Math.random()*400-200),(Math.random()*300-150));

vectors.push(newVector(point));

layer.addVectors(vectors);

创建1000个x坐标随机在(-200,200)和y坐标随机在(-150,150)之间的点,并添加到图层当中。

上面的代码中,我们通过newVector()创建一个矢量图形,其几何信息就是之前声明的point变量。

Vector类的声明如下(在目前看来Vector类,就是将geometry和attributes整合到一起的一个类,但是以后会为这个Vector增加更多的方法和属性的)

functionVector(geometry,attributes){

vector"

this.geometry=geometry;

if(attributes){

this.attributes=attributes;

下一篇随笔会介绍渲染器类的构建方法,在下面提供的源码当中有今天所有讲过的类、和没有涉及到的类(一些工具类,和渲染器类)。

这一节我们只是构建了一个大体的渲染器使用框架,在后面的随笔中会完善他的功能~

下面这个demo展示了我们这个渲染器的基本用法。

运行示例

尝试一下:

改变for循环的个数可以控制产生多少个点,可以自定义x,y值来精确定位点。

下次随笔预告:

1.重点介绍渲染器类的构建。

2.大家发现没有上面的demo是以左上角为中心点缩放的,下次添加缩放中心点。

3.增加更多的几何类型(圆和矩形)。

请关注~

本次随笔的所有源码+Demo,点击下载。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1