首页 > web前端 > H5教程 > 正文

画出自己的UI组件的详情

黄舟
发布: 2017-03-01 15:54:11
原创
1708人浏览过

html5开源引擎lufylegend-1.7.1版的下载包内包含了lufylegend.ui-0.1.0.js文件,它是一个lufylegend.js引擎的专用ui组件,我在api的介绍里也说了,这个ui组件是专门为懒人准备的,包含按钮,单选框,多选框,组合框,滚动条等ui。

下面我来具体说一说这些UI的绘制过程,也方便大家更好的理解和扩展新的UI组件。

1,矩形按钮LButtonSample1

首先来看看LButtonSample1按钮的绘制。

在lufylegend.js引擎中可以利用LButton类来添加一个按钮,但是你需要传入按钮弹起和按钮按下的两个状态的可视对象,可以是LSprite,也可以是LBitmap,想要漂亮一点的按钮的朋友们可以使用一张漂亮的图片,一般做法如下

1

2

btn01 = new LButton(new LBitmap(new LBitmapData(imglist["replay_button_up"])),

new LBitmap(new LBitmapData(imglist["replay_button_over"])));

登录后复制

当然,也可以使用LSprite对象的graphics属性绘制一个图形,一般做法如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

var up = new LSprite();

up.graphics.drawRect(1,"black",[0, 0, 100, 30],true,"#999999");

var txt = new LTextField();

txt.x = 10;

txt.y = 5;

txt.text = "测试按钮";

up.addChild(txt);

var over = new LSprite();

over.graphics.drawRect(1,"black",[0, 0, 100, 30],true,"#cccccc");

var txt1 = new LTextField();

txt1.x = 10;

txt1.y = 5;

txt1.text = "测试按钮";

over.addChild(txt1);

var btn = new LButton(up,over);

登录后复制

上面的代码只是绘制了两个不同颜色的矩形而已,当然不够美观,LButtonSample1对象就是在这种方法的基础上来制作的。

看LButtonSample1的构造器代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

function LButtonSample1(name,size,font,color){

    var s = this;

    if(!size)size=16;

    if(!color)color = "white";

    if(!font)font = "黑体";

    s.backgroundCorl = "black";

    var btn_up = new LSprite();

    btn_up.shadow = new LSprite();

    btn_up.back = new LSprite();

    btn_up.addChild(btn_up.shadow);

    btn_up.addChild(btn_up.back);

    labelText = new LTextField();

    labelText.color = color;

    labelText.font = font;

    labelText.size = size;

    labelText.x = size*0.5;

    labelText.y = size*0.5;

    labelText.text = name;

    btn_up.back.addChild(labelText);

    var shadow = new LDropShadowFilter(4,45,"#000000",10);

    btn_up.shadow.filters = [shadow];

 

    var btn_down = new LSprite();

    btn_down.x = btn_down.y = 1;

    labelText = new LTextField();

    labelText.color = color;

    labelText.font = font;

    labelText.size = size;

    labelText.x = size*0.5;

    labelText.y = size*0.5;

    labelText.text = name;

    btn_down.addChild(labelText);

    base(s,LButton,[btn_up,btn_down]);

    s.width = labelText.getWidth() + size;

    s.height = 2.2*size;

    s.backgroundSet = null;

    btn_up.shadow.graphics.drawRoundRect(0,"#000000",[1,1,s.width-2,s.height-2,s.height*0.1],true,"#000000");

    s.addEventListener(LEvent.ENTER_FRAME,s._onDraw);

}

登录后复制

可以看到它继承自LButton,所以它有LButton的所有方法和属性,同时利用了btn_up和btn_down作为按钮的两个状态,传给了它的父类LButton。

btn_up作为按钮的弹起的状态,它包含了两个LSprite对象(shadow和back)和一个LTextField对象,shadow用来给按钮设置阴影效果,LTextField对象用来显示按钮文字。

按钮的绘制过程是在_onDraw函数中,如下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

LButtonSample1.prototype._onDraw = function(s){

    if(s.backgroundSet == s.backgroundCorl)return;

    s.backgroundSet = s.backgroundCorl;

    var grd=LGlobal.canvas.createLinearGradient(0,s.y-s.height*0.5,0,s.y+s.height*2);

    grd.addColorStop(0,"white");

    grd.addColorStop(1,s.backgroundCorl);

     

    var grd2=LGlobal.canvas.createLinearGradient(0,s.y-s.height,0,s.y+s.height*2);

    grd2.addColorStop(0,"white");

    grd2.addColorStop(1,s.backgroundCorl);

     

    s.bitmap_up.back.graphics.clear();

    s.bitmap_over.graphics.clear();

    s.bitmap_up.back.graphics.drawRect(1,s.backgroundCorl,[0,0,s.width,s.height],true,grd);

    s.bitmap_up.back.graphics.drawRect(0,s.backgroundCorl,[1,s.height*0.5,s.width-2,s.height*0.5-1],true,grd2);

    s.bitmap_over.graphics.drawRect(1,s.backgroundCorl,[0,0,s.width,s.height],true,grd);

    s.bitmap_over.graphics.drawRect(0,s.backgroundCorl,[1,s.height*0.5,s.width-2,s.height*0.5-1],true,grd2);

};

登录后复制

在_onDraw函数中,显示新建了两个渐变的颜色,然后分别在按钮的两个状态中绘制了两个普通的矩形,这样一个按钮就绘制成功了,使用方法如下。

1

2

3

4

5

var button02 = new LButtonSample1("测试按钮2");

button02.backgroundCorl = "#008800";

button02.x = 150;

button02.y = 10;

layer.addChild(button02);

登录后复制

效果

2,圆角矩形按钮LButtonSample2

有了LButtonSample1,圆角矩形LButtonSample2就简单了,把绘制矩形部分换成圆角矩形就行了,但是构造器,我们也不需要再多写一遍了,直接让LButtonSample2继承LButtonSample1就可以了,如下

1

2

3

4

function LButtonSample2(name,size,font,color){

    var s = this;

    base(s,LButtonSample1,[name,size,font,color]);

}

登录后复制

然后就是_onDraw函数,如下。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

LButtonSample2.prototype._onDraw = function(s){

    if(s.backgroundSet == s.backgroundCorl)return;

    s.backgroundSet = s.backgroundCorl;

    var grd=LGlobal.canvas.createLinearGradient(0,s.y-s.height*0.5,0,s.y+s.height*2);

    grd.addColorStop(0,"white");

    grd.addColorStop(1,s.backgroundCorl);

     

    var grd2=LGlobal.canvas.createLinearGradient(0,s.y-s.height,0,s.y+s.height*2);

    grd2.addColorStop(0,"white");

    grd2.addColorStop(1,s.backgroundCorl);

     

    s.bitmap_up.back.graphics.clear();

    s.bitmap_over.graphics.clear();

    s.bitmap_up.back.graphics.drawRoundRect(1,s.backgroundCorl,[0,0,s.width,s.height,s.height*0.1],true,grd);

    s.bitmap_up.back.graphics.drawRoundRect(0,s.backgroundCorl,[1,s.height*0.5,s.width-2,s.height*0.5-1,s.height*0.1],true,grd2);

    s.bitmap_over.graphics.drawRoundRect(1,s.backgroundCorl,[0,0,s.width,s.height,s.height*0.1],true,grd);

    s.bitmap_over.graphics.drawRoundRect(0,s.backgroundCorl,[1,s.height*0.5,s.width-2,s.height*0.5-1,s.height*0.1],true,grd2);

};

登录后复制

区别就在于drawRoundRect函数,它是绘制圆角矩形,使用方法如下。

1

2

3

4

5

var button04 = new LButtonSample2("测试按钮4");

    button04.backgroundCorl = "blue";

    button04.x = 10;

    button04.y = 70;

    layer.addChild(button04);

登录后复制

效果

3,单选框LRadio

LRadio是由一个或多个LRadioChild对象组成的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

function LRadioChild(value,layer,layerSelect){

    var s = this;

    base(s,LSprite,[]);

    s.value = value;

     

    if(!layer){

        layer = new LSprite();

        layer.graphics.drawArc(2,"#000000",[0,0,10,0,2*Math.PI],true,"#D3D3D3");

    }

    if(!layerSelect){

        layerSelect = new LSprite();

        layerSelect.graphics.drawArc(0,"#000000",[0,0,4,0,2*Math.PI],true,"#000000");

    }

    s.layer = layer;

    s.layerSelect = layerSelect;

    s.addChild(s.layer);

    s.addChild(s.layerSelect);

    s.layerSelect.visible = false;

    s.checked = false;

    s.addEventListener(LMouseEvent.MOUSE_UP,s._onChange);

}

LRadioChild.prototype._onChange = function(e,s){

    s.parent.setValue(s.value);

};

LRadioChild.prototype.setChecked = function(v){

    this.layerSelect.visible = this.checked = v;

};

登录后复制

LRadioChild其实就是由两个重叠的可视对象layer和layerSelect组成的,通过setChecked设定layerSelect对象是否显示,从而改变它的外观,当点击LRadioChild对象时,调用它父级即上一级对象的setValue方法,再来看看LRadio代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

function LRadio(){

    base(this,LSprite,[]);

}

LRadio.prototype.setChildRadio = function(value,x,y,layer,layerSelect){

    var s = this;

    var child = new LRadioChild(value,layer,layerSelect);

    child.x = x;

    child.y = y;

    s.addChild(child);

};

LRadio.prototype.push = function(value){

    this.addChild(value);

};

LRadio.prototype.setValue = function(value){

    var s=this,child,k;

    for(k in s.childList){

        child = s.childList[k];

        child.setChecked(false);

        if(child.value == value){

            s.value = value;

            child.setChecked(true);

        }

    }

};

登录后复制

通过setChildRadio或者push来添加子LRadioChild对象,然后当setValue函数被调用时,改变所有子LRadioChild对象的状态,将点击的子对象设为选中。

使用方法如下:

1

2

3

4

5

6

7

var radio = new LRadio();

radio.x = 50;

radio.y = 130;

radio.setChildRadio(1,0,0);

radio.setChildRadio(2,50,0);

radio.setChildRadio(3,100,0);

layer.addChild(radio);

登录后复制

效果



4,多选框LCheckBox

多选框比较简单

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

function LCheckBox(layer,layerSelect){

    var s = this;

    base(s,LSprite,[]);

     

    if(!layer){

        layer = new LSprite();

        layer.graphics.drawRect(2,"#000000",[0,0,20,20],true,"#D3D3D3");

    }

    if(!layerSelect){

        layerSelect = new LSprite();

        layerSelect.graphics.drawLine(5,"#000000",[2,10,10,18]);

        layerSelect.graphics.drawLine(5,"#000000",[10,18,18,2]);

    }

    s.layer = layer;

    s.layerSelect = layerSelect;

    s.addChild(s.layer);

    s.addChild(s.layerSelect);

    s.layerSelect.visible = s.checked = false;

    s.addEventListener(LMouseEvent.MOUSE_UP,s._onChange);

}

LCheckBox.prototype._onChange = function(e,s){

    s.checked = !s.checked;

    s.layerSelect.visible = s.checked;

};

LCheckBox.prototype.setChecked = function(value){

    s.checked = value;

    s.layerSelect.visible = s.checked;

};

登录后复制

可以看到,它的原理和LRadioChild是一样的,同样通过两个重叠的可视对象来控制多选框的状态。

使用方法如下:

1

2

3

4

5

6

7

8

var check1 = new LCheckBox();

check1.x = 50;

check1.y= 160;

layer.addChild(check1);

var check2 = new LCheckBox();

check2.x = 100;

check2.y= 160;

layer.addChild(check2);

登录后复制

效果



5,组合框LComboBox

这个相对复杂一些,因为不想单选或多选框,只是点击改变状态而已,它需要根据点击动作不同,让它内部的列表上下滚动,先看构造器。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

function LComboBox(size,color,font,layer,layerUp,layerDown){

    var s = this;

    base(s,LSprite,[]);

    s.list = [];

    s.selectIndex = 0;

    s.value = null;

    s.selectWidth = 100;

    if(!size)size=16;

    if(!color)color = "black";

    if(!font)font = "黑体";

    s.size = size;

    s.color = color;

    s.font = font;

    s.refreshFlag = false;

     

    if(!layer){

        s.refreshFlag = true;

        layer = new LSprite();

        layerUp = new LSprite();

        layerDown = new LSprite();

        s.layer = layer;

        s.layerUp = layerUp;

        s.layerDown = layerDown;

        s.refresh();

    }

    s.addChild(layer);

    s.addChild(layerUp);

    s.addChild(layerDown);

    s.layer = layer;

    s.layerUp = layerUp;

    s.layerDown = layerDown;

     

    s.runing = false;

     

    s.textLayer = new LSprite();

    s.textLayer.x = 5;

    s.textLayer.y = s.size * 0.4;

    s.addChild(s.textLayer);

    s.layerUp.addEventListener(LMouseEvent.MOUSE_UP,s._onChangeUp);

    s.layerDown.addEventListener(LMouseEvent.MOUSE_UP,s._onChangeDown);

}

登录后复制

layer就是组合框的样式了,而layerUp和layerDown分别是它的向上和向下的控制按钮,通过点击这两个按钮,分别调用_onChangeUp和_onChangeDown函数,另外组合框的内部列表会添加到textLayer层上。

看一下,setChild函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

LComboBox.prototype.setChild = function(child){

    var s = this;

    if(!child || !child.value || !child.label)trace("the child must be an object like:{label:a,value:b}");

     

    var text = new LTextField();

    text.size = s.size;

    text.color = s.color;

    text.font = s.font;

    text.text = child.label;

    text.y = (s.size * 1.5 >>> 0) * s.list.length;

    s.textLayer.addChild(text);

    if(s.list.length == 0){

        s.value = child.value;

    }

    s.list.push(child);

    s.selectWidth = 100;

    s.refresh();

     

};

登录后复制

这个函数为组合框的列表添加一个元素,使用LTextField对象来显示。

接着看_onChangeUp和_onChangeDown函数。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

LComboBox.prototype._onChangeDown = function(e,b){

    var s = b.parent;

    if(s.runing)return;

    if(s.selectIndex >= s.list.length - 1)return;

    s.runing = true;

    for(k in s.list){

        s.textLayer.childList[k].visible = true;

    }

    s.selectIndex++;

    s.value = s.list[s.selectIndex].value;

    var mask = new LSprite();

    mask.graphics.drawRect(2,"#000000",[0,0,s.selectWidth,s.size*2]);

    s.textLayer.mask = mask;

    var my = s.textLayer.y - (s.size * 1.5 >>> 0);

    var fun = function(layer){

        var s = layer.parent;

        layer.mask = null;

        s.runing = false;

        s.refresh();

    };

    LTweenLite.to(s.textLayer,0.3,

    {

        y:my,

        onComplete:fun,

        ease:Strong.easeOut

    });

};

LComboBox.prototype._onChangeUp = function(e,b){

    var s = b.parent;

    if(s.runing)return;

    if(s.selectIndex <= 0)return;

    s.runing = true;

    for(k in s.list){

        s.textLayer.childList[k].visible = true;

    }

    s.selectIndex--;

    s.value = s.list[s.selectIndex].value;

    var mask = new LSprite();

    mask.graphics.drawRect(2,"#000000",[0,0,s.selectWidth,s.size*2]);

    s.textLayer.mask = mask;

    var my = s.textLayer.y + (s.size * 1.5 >>> 0);

    var fun = function(layer){

        var s = layer.parent;

        layer.mask = null;

        s.runing = false;

        s.refresh();

    };

    LTweenLite.to(s.textLayer,0.3,

    {

        y:my,

        onComplete:fun,

        ease:Strong.easeOut

    });

};

登录后复制

这两个函数,通过LTweenLite来让组合框的textLayer层进行向上或者向下的缓动。

无论是setChild,还是_onChangeUp和_onChangeDown,里面都调用了refresh函数,看一下这个函数吧

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

LComboBox.prototype.refresh = function(){

    var s = this,k;

 

    for(k in s.list){

        s.textLayer.childList[k].visible = false;

        if(s.value == s.list[k].value)s.textLayer.childList[k].visible = true;

        if(s.selectWidth < s.textLayer.childList[k].getWidth() + s.size){

            s.selectWidth = s.textLayer.childList[k].getWidth() + s.size;

        }

    }

     

    s.layer.graphics.clear();

    s.layerUp.graphics.clear();

    s.layerDown.graphics.clear();

    s.layer.graphics.drawRect(2,"#000000",[0,0,s.selectWidth,s.size*2],true,"#D3D3D3");

    s.layerUp.x = s.selectWidth;

    s.layerUp.graphics.drawRect(2,"#000000",[0,0,s.size*2,s.size]);

    s.layerUp.graphics.drawVertices(2,"#000000",[[s.size*0.5*2,s.size*0.2],[s.size*0.2*2,s.size*0.8],[s.size*0.8*2,s.size*0.8]],true,"#000000");

    s.layerDown.x = s.selectWidth;

    s.layerDown.y = s.size;

    s.layerDown.graphics.drawRect(2,"#000000",[0,0,s.size*2,s.size]);

    s.layerDown.graphics.drawVertices(2,"#000000",[[s.size*0.5*2,s.size*0.8],[s.size*0.2*2,s.size*0.2],[s.size*0.8*2,s.size*0.2]],true,"#000000");

};

登录后复制

可以看到,这个函数其实就是对组合框做了一个重绘,利用drawRect绘制矩形,利用drawVertices绘制三角形。
组合框的用法如下:

1

2

3

4

5

6

7

8

var com = new LComboBox(20);

com.x = 50;

com.y= 210;

com.setChild({label:"测试一",value:"aaa"});

com.setChild({label:"测试二",value:"bbb"});

com.setChild({label:"测试三",value:"ccc"});

com.setChild({label:"测试四",value:"ddd"});

layer.addChild(com);

登录后复制

效果


6,滚动条LScrollbar

最后是滚动条,这个实现起来就有点难度了,还好以前我用AS3写过一个滚动条,直接copy移植过来了,移植过程中,我再次感叹,lufylegend.js的语法模仿AS3还是比较成功的。

这个比较麻烦,所以我在这里只说一下它的用法,感兴趣的朋友可以看一下代码,自己了解一下。

看一下官方API介绍

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

LScrollbar(showObject,maskW,maskH,scrollWidth,wVisible)

 

■作用:

 

带有滚动条的可视对象。

 

■参数:

 

showObject:需要加入滚动条的对象。

 

maskW:滚动条对象的可视大小的宽。

 

maskH:滚动条对象的可视大小的高。

 

scrollWidth:滚动条的宽。

 

wVisible:是否显示横向滚动条,未设定则为默认。

登录后复制

具体用法如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

var showObject = new LSprite();

showObject.graphics.drawRect(2,"#ff0000",[0,0,500,500],true,"#ff0000");

var t = new LTextField();

t.color = "#000000";

t.text = "あいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてとあいうえおかきくけこさしすせそたちつてと";

t.width = 300;

t.stroke = true;

t.size = 30;

t.setWordWrap(true,35);

showObject.addChild(t);

var sc = new LScrollbar(showObject,200,200);

sc.x = 450;

sc.y = 20;

layer.addChild(sc);

登录后复制

效果



在下美工设计极差,所以本篇纯属抛砖引玉,大家可以试着自己写几组漂亮的UI,或者有什么好的意见或想法的,可以联系我。

HTML5开源游戏引擎lufylegend1.7.1发布贴

http://blog.csdn.net/lufy_legend/article/details/8780821

lufylegend.js引擎官网

http://lufylegend.com/lufylegend

lufylegend.js引擎在线API文档链接

http://lufylegend.com/lufylegend/api

 以上就是画出自己的UI组件的详情的内容,更多相关内容请关注PHP中文网(www.php.cn)!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号