之前在拓扑上的应用都是些静态的图元,今天我们将在拓扑上设计一个会动的图元——叶轮旋转。
先看看最后我们实现的效果:http://www.hightopo.com/demo/fan/index.html
我们先来看下这个叶轮模型长什么样
从模型上看,这个叶轮模型有三个叶片,每一个叶片都是不规则图形,显然无法用上我们HT for Web的基础图形来拼接,那么我们该怎么做呢?很简单,在HT for Web中提供了自定义图形的方案,我们可以通过自定义图形来绘制像叶片这种不规则图形。
在绘制叶片之前,我们得先来了解下HT for Web的自定义图形绘制的基本知识:
绘制自定义图形需要制定矢量类型为shape,并通过points的Array数组指定每个点信息, points以[x1, y1, x2, y2, x3, y3, ...]的方式存储点坐标。曲线的多边形可通过segments的Array数组来描述, segment以[1, 2, 1, 3 ...]的方式描述每个线段:
1: moveTo,占用1个点信息,代表一个新路径的起点
2: lineTo,占用1个点信息,代表从上次最后点连接到该点
3: quadraticCurveTo,占用2个点信息,第一个点作为曲线控制点,第二个点作为曲线结束点
4: bezierCurveTo,占用3个点信息,第一和第二个点作为曲线控制点,第三个点作为曲线结束点
5: closePath,不占用点信息,代表本次路径绘制结束,并闭合到路径的起始点
对比闭合多边形除了设置segments参数外,还可以设置closePath属性: * closePath获取和设置多边形是否闭合,默认为false,对闭合直线采用这种方式,无需设置segments参数。
好了,那么接下来我们开始设计叶片了
ht.Default.setImage('vane', { width: 97, height: 106, comps: [ { type: 'shape', points: [ 92, 67, 62, 7, 0, 70, 60, 98 ], segments: [ 1, 2, 2, 2 ], background : 'red' } ] });
我们在矢量中定义了4个顶点,并且将这4个顶点通过直线勾勒出叶片的大致形状,虽然有些抽象,但是,接下来将会通过增加控制点和改变segment参数来让这个叶片发生蜕变。
首先我们通过bezierCurveTo方式向第一个和第二个顶点之间的线段添加两个控制点,从而绘制出曲线,以下是points及segments属性:
points: [ 92, 67, 93, 35, 78, 0, 62, 7, 0, 70, 60, 98 ], segments: [ 1, 4, 2, 2 ]
这时候与上一个图相比较,有一条边一件有些弧度了,那么接下来就来处理第二条边和第三条边
points: [ 92, 67, 93, 35, 78, 0, 62, 7, 29, 13, 4, 46, 0, 70, 28, 53, 68, 60, 60, 98 ], segments: [ 1, 4, 4, 4 ]
看吧,现在是不是有模有样了,现在叶片已经有了,那么接下来要做的就是使用三个这样的叶片拼接成一个叶轮。
将已有的资源拼接在一起需要用到矢量中的image类型类定义新的矢量,具体的使用方法如下:
ht.Default.setImage('impeller', { width: 166, height: 180.666, comps : [ { type: 'image', name: 'vane', rect: [0, 0, 97, 106] }, { type: 'image', name: 'vane', rect: [87.45, 26.95, 97, 106], rotation: 2 * Math.PI / 3 }, { type: 'image', name: 'vane', rect: [20.45, 89.2, 97, 106], rotation: 2 * Math.PI / 3 * 2 } ] });
在代码中,我们定义了三个叶片,并且对第二个和第三个叶片做了旋转和定位的处理,让这三个叶片排布组合成一个叶轮来,但是怎么能让叶轮中间空出一个三角形呢,这个问题解决起来不难,我们只需要在叶片的points属性上再多加一个顶点,就可以填充这个三角形了,代码如下:
points: [ 92, 67, 93, 35, 78, 0, 62, 7, 29, 13, 4, 46, 0, 70, 28, 53, 68, 60, 60, 98, 97, 106 ], segments: [ 1, 4, 4, 4, 2 ]
在points属性上添加了一个顶点后,别忘了在segments数组的最后面添加一个描述,再来看看最终的效果:
到这个叶轮的资源就做好了,那么接下来就是要让这个叶轮旋转起来了,我们先来分析下:
要让叶轮旋转起来,其实原理很简单,我们只需要设置rotation属性就可以实现了,但是这个rotation属性只有在不断的变化中,才会让叶轮旋转起来,所以这个时候就需要用到定时器了,通过定时器来不断地设置rotation属性,让叶轮动起来。
恩,好像就是这样子的,那么我们来实现一下:
首先是创建一个节点,并设置其引用的image为impeller,再将其添加到DataModel,令节点在拓扑中显示出来:
var node = new ht.Node(); node.setSize(166, 181); node.setPosition(400, 400); node.setImage('impeller'); dataModel.add(node);
接下来就是添加一个定时器了:
window.setInterval(function() { var rotation = node.getRotation() + Math.PI / 10; if (rotation > Math.PI * 2) { rotation -= Math.PI * 2; } node.setRotation(rotation); }, 40);
OK了,好像就是这个效果,但是当你选中这个节点的时候,你会发现这个节点的边框在不停的闪动,看起来并不是那么的舒服,为什么会出现这种情况呢?原因很简单,当设置了节点的rotation属性后,节点的显示区域就会发生变化,这个时候节点的宽高自然就发生的变化,其边框也自然跟着改变。
还有,在很多情况下,节点的rotation属性及宽高属性会被当成业务属性来处理,不太适合被实时改变,那么我们该如何处理,才能在不不改变节点的rotation属性的前提下令叶轮转动起来呢?
在矢量中,好像有数据绑定的功能,在手册中是这么介绍的:
绑定的格式很简单,只需将以前的参数值用一个带func属性的对象替换即可,func的内容有以下几种类型:
1. function类型,直接调用该函数,并传入相关Data和view对象,由函数返回值决定参数值,即func(data, view);调用。
2. string类型:
2.1 style@***开头,则返回data.getStyle(***)值,其中***代表style的属性名。
2.2 attr@***开头,则返回data.getAttr(***)值,其中***代表attr的属性名。
2.3 field@***开头,则返回data.***值,其中***代表data的属性名。
2.4 如果不匹配以上情况,则直接将string类型作为data对象的函数名调用data.***(view),返回值作为参数值。
除了func属性外,还可设置value属性作为默认值,如果对应的func取得的值为undefined或null时,则会采用value属性定义的默认值。 例如以下代码,如果对应的Data对象的attr属性stateColor为undefined或null时,则会采用yellow颜色:
color: { func: 'attr@stateColor', value: 'yellow' }
数据绑定的用法已经介绍得很清楚了,我们不妨先试试绑定叶片的背景色吧,看下好不好使。在矢量vane中的background属性设置成数据绑定的形式,代码如下:
background : { value : 'red', func : 'attr@vane_background' }
在没有设置vane_background属性的时候,令其去red为默认值,那么接下来我们来定义下vane_background属性为blue,看看叶轮会不会变成蓝色:
node.setAttr('vane_background', ‘blue');
看下效果:
果然生效了,这下好了,我们就可以让叶轮旋转变得更加完美了,来看看具体该这么做。
首先,我们先在节点上定义一个自定义属性,名字为:impeller_rotation
node.setAttr('impeller_rotation', 0);
然后再定义一个名字为rotate_impeller的矢量,并将rotation属性绑定到节点的impeller_rotation上:
ht.Default.setImage('rotate_impeller', { width : 220, height : 220, comps : [ { type : 'image', name : 'impeller', rect : [27, 20, 166, 180.666], rotation : { func : function(data) { return data.getAttr('impeller_rotation'); } } } ] });
这时候我们在定时器中修改节点的rotation属性改成修改自定义属性impeller_rotation就可以让节点中的叶轮旋转起来,并且不会影响到节点自身的属性,这就是我们想要的效果。
在2D上可以实现,在3D上一样可以实现,下一章我们就来讲讲叶轮旋转在3D上的应用,今天就先到这里,下面附上今天Demo的源码,有什么问题欢迎大家咨询。
http://www.hightopo.com/demo/fan/index.html
ht.Default.setImage('vane', { width : 97, height : 106, comps : [ { type : 'shape', points : [ 92, 67, 93, 35, 78, 0, 62, 7, 29, 13, 4, 46, 0, 70, 28, 53, 68, 60, 60, 98, 97, 106 ], segments : [ 1, 4, 4, 4, 2 ], background : { value : 'red', func : 'attr@vane_background' } } ] }); ht.Default.setImage('impeller', { width : 166, height : 180.666, comps : [ { type : 'image', name : 'vane', rect : [0, 0, 97, 106] }, { type : 'image', name : 'vane', rect : [87.45, 26.95, 97, 106], rotation : 2 * Math.PI / 3 }, { type : 'image', name : 'vane', rect : [20.45, 89.2, 97, 106], rotation : 2 * Math.PI / 3 * 2 } ] }); ht.Default.setImage('rotate_impeller', { width : 220, height : 220, comps : [ { type : 'image', name : 'impeller', rect : [27, 20, 166, 180.666], rotation : { func : function(data) { return data.getAttr('impeller_rotation'); } } } ] }); function init() { var dataModel = new ht.DataModel(); var graphView = new ht.graph.GraphView(dataModel); var view = graphView.getView(); view.className = "view"; document.body.appendChild(view); var node = new ht.Node(); node.setSize(220, 220); node.setPosition(200, 400); node.setImage('rotate_impeller'); node.setAttr('impeller_rotation', 0); node.setAttr('vane_background', 'blue'); dataModel.add(node); var node1 = new ht.Node(); node1.setSize(166, 181); node1.setPosition(500, 400); node1.setImage('impeller'); dataModel.add(node1); window.setInterval(function() { var rotation = node.a('impeller_rotation') + Math.PI / 10; if (rotation > Math.PI * 2) { rotation -= Math.PI * 2; } node.a('impeller_rotation', rotation); node1.setRotation(rotation); }, 40); }
相关推荐
在这个“基于html5 canvas实现的动态文字特效代码”项目中,我们将探讨如何利用Canvas API来创建引人注目的文字动画效果。 Canvas API提供了一系列方法,如`fillText()`和`strokeText()`,用于在画布上绘制文本,而...
"HTML5 Canvas三维立体的旋转物体动画"这个主题涉及到的是利用Canvas API来实现三维空间中的物体旋转效果,这在游戏、数据可视化、用户界面设计等领域有广泛应用。 Canvas API提供了基础的绘图命令,如画线、填充...
标签“动画”提示我们关注的是动态效果,而“canvas”和“html5”则强调了这个效果是基于Web技术实现的。这样的动画效果不仅美观,而且具有良好的跨平台性,可以在支持HTML5的现代浏览器中运行。 在实际项目中,...
"基于HTML5 Canvas的矢量地图渲染"主题深入探讨了如何使用Canvas来实现交互式、高性能的地图展示。在这个项目中,我们看到一个名为"vector-map-master"的压缩包,它很可能包含了实现这一功能的源代码和资源。 首先...
在这个项目中,我们看到HTML5 Canvas被用来创建一个3D旋转物体的动画,同时结合CSS3的技术,实现了物体的模糊发光特效。 首先,让我们深入了解一下HTML5 Canvas的基本概念。Canvas是一个基于矢量图形的画布,通过...
HTML5的canvas元素是网页开发中的一个强大工具,它提供了在浏览器端动态绘制图形的能力,包括图片处理。在这个示例中,我们将深入探讨如何利用canvas进行图片的裁剪、旋转和缩放操作。 首先,我们需要在HTML文件中...
"html5 canvas实现旋转的心"这个主题,显然是关于如何使用Canvas API来绘制并动态旋转一个心形图案。这篇博客文章(博文链接:https://wjlgryx.iteye.com/blog/972463)可能会详细讲解这个过程。 首先,我们需要...
这个“基于html5_canvas 实现的简单思维导图制作工具 支持自由放置节点和自由关联节点.zip”压缩包文件包含了一个使用HTML5 Canvas API构建的思维导图编辑器项目,名为“JsMind-master”。让我们深入了解一下这个...
canvas拼图游戏,基于html + canvas画布实现
首先,HTML5 Canvas是一个基于矢量图形的画布,通过JavaScript API进行操作。开发者可以使用Canvas的绘图方法(如`fillRect`, `strokeRect`, `arc`, `beginPath`等)来绘制图形、线条、曲线等,并通过`...
在这个“html5 canvas绘制3D地球旋转动画特效”中,我们将深入探讨如何利用HTML5 Canvas API来创建一个逼真的3D地球模型,并实现其旋转的动画效果。 首先,我们需要理解Canvas的基本用法。Canvas是一个矩形区域,在...
在这个特定的场景中,我们讨论的是如何使用Canvas实现页面滚动时背景图片的旋转动画特效。这样的效果可以增加网页的视觉吸引力,为用户带来更生动的浏览体验。 首先,我们要了解Canvas的基本用法。Canvas是一个HTML...
这个“基于HTML5 Canvas实现的图片马赛克模糊特效”就是一个利用Canvas API创建图像处理效果的例子。这个插件通过操作像素数据来实现马赛克和模糊效果,使得用户可以在网页上轻松地对图片进行视觉处理。 首先,让...
基于Canvas实现的HTML5编辑器,更进一步地利用了HTML5的Canvas元素,这是一种用于在网页上绘制图形的JavaScript API。Canvas提供了一种动态、灵活的方式来创建和修改图像,使其成为构建富媒体应用和复杂交互式编辑...
html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效...
这个特效是利用Canvas API实现的“html5 canvas炫酷旋转银河系星空背景特效”,它为网站添加了一个动态且引人入胜的视觉元素。 首先,让我们深入了解一下HTML5 Canvas的基本概念。Canvas是一个基于矢量图形的画布,...
本项目"基于html2canvas生成带二维码的活动海报"提供了一个纯前端解决方案,使得开发者无需后端支持也能快速实现此类功能。html2canvas是一个JavaScript库,它能够将网页的DOM(文档对象模型)渲染为图片,从而解决...
在这个“html5 canvas实现的小游戏”中,我们可以通过Canvas API来理解并学习如何构建一个简单的游戏。 首先,Canvas API是HTML5的一个核心特性,它提供了一组JavaScript方法用于在画布上绘制图像、文本、线条、...
综上所述,这个项目展示了HTML5 Canvas的强大功能,特别是如何用JavaScript实现复杂的3D视觉效果。通过学习和理解这段源码,开发者不仅可以掌握Canvas的基本用法,还能深入理解3D图形渲染的原理,对提升前端开发技能...
本项目基于HTML5的Canvas技术,实现了商品的360度全方位展示,适用于Chrome、Firefox以及IE9及以上的浏览器。 HTML5是现代网页开发的标准,它引入了许多新的API和元素,Canvas就是其中之一。Canvas是一个二维绘图上...