`
xhload3d
  • 浏览: 208451 次
社区版块
存档分类
最新评论

基于HT for Web矢量实现2D叶轮旋转

阅读更多

之前在拓扑上的应用都是些静态的图元,今天我们将在拓扑上设计一个会动的图元——叶轮旋转。

我们先来看下这个叶轮模型长什么样

 

从模型上看,这个叶轮模型有三个叶片,每一个叶片都是不规则图形,显然无法用上我们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的源码,有什么问题欢迎大家咨询。

 

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);
}

 

 

2
1
分享到:
评论

相关推荐

    基于HT for Web矢量实现HTML5文件上传进度条

    标题中的“基于HT for Web矢量实现HTML5文件上传进度条”是指利用HT for Web库,结合HTML5的File API,来创建一个可以显示文件上传进度的矢量图形界面。HT for Web是一款强大的Web可视化工具,它允许开发者通过矢量...

    基于HT for Web矢量实现HTML5上传文件进度条

    在本文中,我们将深入探讨如何使用基于HT for Web的矢量技术实现HTML5上传文件进度条的功能。这个技术主要用于创建动态、高性能的Web应用程序,特别是在处理大文件上传时,能够提供用户友好的反馈,增强用户体验。 ...

    HT for Web - Box2d

    一直在找苦苦寻找一个Box2D的物理引擎javascript整合例子,发现 http://www.hightopo.com/blog/275.html 这篇文章的例子效果非常棒,通过HT for Web的3D引擎直观的呈现Box2D物理碰撞的实时运行效果,这么强大的3D...

    HT for Web Demo

    "HT for Web Demo" 是一个基于JavaScript的3D可视化演示项目,主要利用了海马云(Hightopo)提供的HT for Web库。海马云是一家专注于2D/3D图形渲染及数据可视化的技术提供商,其开发的HT for Web库是一个强大的Web...

    HT for Web 入门手册

    HT for Web是基于HTML5标准的企业应用图形界面一站式解决方案, 其包含通用组件、拓扑组件和3D渲染引擎等丰富的图形界面开发类库,提供了完全基于HTML5的矢量编辑器、拓扑编辑器及 3D场景编辑器等多套可视化设计工具...

    HT for Web 3d引擎示例加api说明文档

    HT for Web,通常简称为 HT,这是一个基于 JavaScript 开发的 WebGL 引擎。可用于 2D/3D 可视化开发,其核心文件只有一个,就是 ”ht.js”。在 index.html 中使用 script 标签进入后便可使用。 完全版本效果:...

    HT for Web基础动画介绍

    HT for Web是一款基于HTML5的2D/3D图形和交互开发工具,广泛应用于数据可视化、模拟仿真、工业互联网等领域。通过这个标题,我们可以推测文章将探讨如何利用HT框架创建基本的Web动画效果。 【描述】虽然描述部分为...

    hightopo HT for Web(hightopo.zip)

    4. **数据驱动**:HT for Web基于数据驱动的模型,使得数据和视图之间保持松耦合,更新数据就能自动刷新视图,大大简化了数据绑定和更新的逻辑。 5. **丰富的组件库**:HT for Web提供了一系列预设的UI组件,如表格...

    ht-for-web

    ht-for-web 的核心是基于 HTML5 和 JavaScript 编写的,因此它兼容现代浏览器,并且与WebGL技术结合,能实现高性能的图形渲染。同时,它也提供了与React、Vue等流行前端框架的集成方案,方便在现有项目中引入和使用...

    HT FOR WEB 自定义图标菜单

    HT FOR WEB 一套强大的基于 WebGL 技术的 3D 图形引擎,编辑器下,左边菜单可自定义控制多个不同的菜单操作。

    HT for Web列表和3D拓扑组件的拖拽应用

    NULL 博文链接:https://xhload3d.iteye.com/blog/2226706

    基于FPGA的高速高质量图像旋转1

    【基于 FPGA 的高速高质量图像旋转】技术主要针对图像处理领域中的图像旋转问题,通过优化算法和硬件实现,提高旋转速度并保证图像质量。该技术基于传统图像旋转矩阵的分解,将原本复杂的二维空间旋转运算转化为一维...

    基于HT32F1656芯片的智能饮水机设计.pdf

    本篇关于“基于HT32F1656芯片的智能饮水机设计”的文献,详细介绍了将传统饮水机升级为一款集触控、声控、Wi-Fi遥控功能于一体的智能饮水机的设计过程。文中主要使用HT32F1656作为主控制芯片,并通过集成多个模块...

    基于HT5017芯片的SoC单相智能电表_SOC_HT5017_电表_基于HT5017芯片的SoC单相智能电表_

    **基于HT5017芯片的SoC单相智能电表** 在当今的电力系统中,智能电表已经成为不可或缺的一部分,它们提供了精确的计量、实时数据传输和远程控制功能。HT5017是一款专为单相电表设计的片上系统(System on Chip, SoC...

    ht.js html5 canvas2d3d教程手册

    ht.js开发实例最新版本,通过这个版本开发html5工业设计智慧平台,经过在网上寻找发现 http://www.hightopo.com/blog/275.html 这篇文章的例子效果非常棒,通过HT for Web的3D引擎直观的呈现Box2D物理碰撞的实时运行...

    基于HT5017芯片的SoC单相智能电表的设计_SOC_HT5017_电表_基于HT5017芯片SoC单相智能电表_

    3. 通信接口:HT5017支持多种通信协议,如RS485、红外、载波通信等,可以实现电表与主站的远程通信,便于数据上传和远程控制。 4. 安全与加密:考虑到智能电表的安全性,HT5017内置了安全模块,支持DES/3DES/AES等...

    在ht5页面端实现threejs模型环绕观看

    Three.js是一个基于WebGL的JavaScript库,它简化了WebGL的复杂性,让开发者能够更容易地创建3D交互式场景。 在Three.js中,要实现3D模型的加载和环绕观看,我们需要经过以下几个步骤: 1. **设置场景(Scene)**:在...

    基于C语言的webserver小项目,实现客户端与服务端HT.zip

    基于C语言的webserver小项目,实现客户端与服务端HT

    基于HT66F004单片机的电解水杯控制电路设计.pdf

    以上内容基于提供的文件信息,详细介绍了基于HT66F004单片机的电解水杯控制电路设计的相关知识点,涵盖了硬件开发、硬件程序控制、系统电源、控制模块、升压和驱动模块设计等方面。这些知识点不仅对专业人员具有指导...

Global site tag (gtag.js) - Google Analytics