>  기사  >  웹 프론트엔드  >  HTML5 Canvas를 기반으로 벡터 산업용 제어 팬 임펠러 회전을 구현하는 샘플 코드

HTML5 Canvas를 기반으로 벡터 산업용 제어 팬 임펠러 회전을 구현하는 샘플 코드

黄舟
黄舟원래의
2017-03-27 15:50:021521검색

토폴로지의 이전 애플리케이션은 모두 정적 이었습니다. 기본, 오늘은 토폴로지에서 움직이는 기본 요소인 임펠러 회전

우리가 달성한 최종 효과를 살펴보겠습니다. <.>

먼저 임펠러

모델

이 어떤 모습인지 살펴보겠습니다

모델에서 보면 이 임펠러 모델은 블레이드가 3개인데 각 블레이드가 불규칙한 모양이므로 당연히

HT

웹 기본 그래픽인데 어떻게 해야 할까요? HT for Web은 커스텀 그래픽을 위한 솔루션을 제공합니다. 나뭇잎을 그리기 전에 먼저 HT for Web의 사용자 정의 그래픽 그리기에 대한 기본 지식을 이해해야 합니다.

사용자 정의 그래픽을 그리려면 벡터

형태로 입력하고 점의 배열 배열을 통해 각 점 정보를 지정합니다. 점은 점 좌표를 저장하기 위해 [x1, y1, x2, y2, x3, y3, ...]로 표시됩니다. 곡선은 세그먼트의 배열 배열로 설명할 수 있으며 세그먼트는 [1, 2, 1, 3...] 형식으로 각 선 세그먼트를 설명합니다.

1: moveTo, 새로운 경로의 시작점을 나타내는 1포인트 정보를 차지합니다

2: lineTo는 1포인트 정보를 차지하며 마지막 포인트부터 이 지점까지의 연결을 나타냅니다

3: QuadraticCurveTo는 2개의 점 정보를 차지하며 첫 번째 점은 곡선 제어점, 두 번째 점은 곡선 끝점으로 사용

4 : bezierCurveTo는 3개의 점 정보를 차지하며, 첫 번째와 두 번째 점은 곡선 제어점으로, 세 번째 점은 곡선 끝점으로 사용됩니다

5: closePath, 점 정보를 차지하지 않고 이 경로 그리기의 끝을 나타내며 경로의 시작점에 닫힙니다.

세그먼트 매개변수를 설정하는 것 외에도 닫힌 다각형을 비교하기 위한 closePath 속성을 설정할 수도 있습니다. * closePath는 다각형이 닫혀 있는지 여부를 가져오고 설정합니다. 이 메서드는 닫힌 직선에 사용됩니다. 세그먼트 매개변수를 설정할 필요가 없습니다. 🎜>그럼 블레이드 디자인을 시작하겠습니다

ht.Default.setImage(&#39;vane&#39;, {
    width: 97,
    height: 106,
    comps: [
        {
            type: &#39;shape&#39;,
            points: [
                92, 67,
                62, 7,
                0, 70,
                60, 98
            ],
            segments: [
                1, 2, 2, 2
            ],
            background : &#39;red&#39;
        }
    ]
});

벡터

에 4개의 꼭지점을 정의하고, 이 4개의 꼭지점을 사용하여 블레이드의 일반적인 모양을 윤곽선으로 그렸습니다. 직선입니다. 다소 추상적이지만 제어점을 추가하고 세그먼트 매개변수를 변경하면 나뭇잎이 변형됩니다.


먼저 bezierCurveTo 메소드를 통해 첫 번째 꼭지점과 두 번째 꼭지점 사이의 선분에 두 개의 제어점을 추가하여 곡선을 그립니다.

points: [
    92, 67,
    93, 35, 78, 0, 62, 7,
    0, 70,
    60, 98
],
segments: [
    1, 4, 2, 2
]

이전 사진에 비해 한쪽 모서리가 살짝 휘어져 있어서 두 번째 모서리와 세 번째 모서리를 다루겠습니다

                                                  3개의 블레이드를 사용하여 임펠러에 접합하면 됩니다.

기존 리소스를 함께 연결하려면

Vector의 이미지 유형 클래스를 사용하여 새 벡터를 정의해야 합니다. 아아아아

在代码中,我们定义了三个叶片,并且对第二个和第三个叶片做了旋转和定位的处理,让这三个叶片排布组合成一个叶轮来,但是怎么能让叶轮中间空出一个三角形呢,这个问题解决起来不难,我们只需要在叶片的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(&#39;impeller&#39;);
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: &#39;attr@stateColor&#39;,
    value: &#39;yellow&#39;
}

数据绑定的用法已经介绍得很清楚了,我们不妨先试试绑定叶片的背景色吧,看下好不好使。在矢量vane中的background属性设置成数据绑定的形式,代码如下:

background : {
    value : &#39;red&#39;,
    func : &#39;attr@vane_background&#39;
}

在没有设置vane_background属性的时候,令其去red为默认值,那么接下来我们来定义下vane_background属性为blue,看看叶轮会不会变成蓝色:

node.setAttr(&#39;vane_background&#39;, ‘blue&#39;);

看下效果:

果然生效了,这下好了,我们就可以让叶轮旋转变得更加完美了,来看看具体该这么做。

首先,我们先在节点上定义一个自定义属性,名字为:impeller_rotation

node.setAttr(&#39;impeller_rotation&#39;, 0);

然后再定义一个名字为rotate_impeller的矢量,并将rotation属性绑定到节点的impeller_rotation上:

ht.Default.setImage(&#39;rotate_impeller&#39;, {
    width : 220,
    height : 220,
    comps : [
        {
            type : &#39;image&#39;,
            name : &#39;impeller&#39;,
            rect : [27, 20, 166, 180.666],
            rotation : {
                func : function(data) { 
                    return data.getAttr(&#39;impeller_rotation&#39;); 
                }
            }
        }
    ]
});

这时候我们在定时器中修改节点的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(&#39;impeller_rotation&#39;, 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를 기반으로 벡터 산업용 제어 팬 임펠러 회전을 구현하는 샘플 코드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.