vue-pixi-renderer
使用vue的结构来渲染pixi页面。
Vue.js
PIXI.js
使用说明
目前有很大不足,极有可能出现各种各样的bug!
目前有较多bug
虚拟Node更改自simple-virtual-dom
。
每次该组件重新渲染时,重新生成Node Tree,然后diff、patch。
动画请在函数中直接控制node,而不是使用Vue传递一个不断变化的属性。(每次重新render都要遍历虚拟Node树,耗时较大);
其余皆为pixi属性,详情见PixiJS API Documentation
安装使用
提醒: 目前有较多bug
npm install -save vue-pixi-renderer
Vue;
基本介绍
<vroot></vroot>
以它为根部建立虚拟node Tree
<container></container>
一个容器。(除root外的任何元素都可作为容器)
创建一个相对坐标系。
<vtext>Text</vtext>
显示字体
<sprite>{src or id}</sprite>
显示图片
<zone></zone>
创建一个区域
<graphics></graphics>
使用pixi.Graphics创建自定义的绘制,需使用init方法
除<vroot></vroot>
外的所有元素均可使用pixiAPI对应的各项数据
比如 <vtext :x=100 :y=100 :anchor='{x: 0.5, y: 0.5}'>Text</vtext>
pixi元素基本属性
x
- 坐标xy
- 坐标yanchor
- { x: number[0-1], y: number[0-1] } - 图片锚点相对图片宽高的位置,xy均为0.5时为正中心。坐标x、y对应的点的位置也为锚点的位置。选择中心点位置为锚点位置。scale
- { x: number, y: number } - 放大倍数,sprite的width、height属性与之关联。直接调整width、height也会变化scale。tint
- number - 色调,颜色为hex的实际值,如0x0
vroot
<template> <vroot:='$stage' 在此传入stage,视为要渲染到的Container 如果没有传入stage,则应提供创建pixi 的参数,如width, 具体参数列表 //.///..:='$texture' 在此传入texture,标签中的id则从此对象里寻找 <>id1</sprite> id2: of Texture <sprite :='500'>id2</sprite> 则应表现为500ms一帧的AnimateSprite 如果没有传入参数,则<sprite>/img/logopng</sprite>视作地址src,将会尝试以该地址加载图片 请使用public里的图片路径,或import导入图片路径 > </vroot></template><script> { // 不应在data中赋值,避免生成响应式数据 this$stage = windowappstage; this$texture = myTextureObject };</script>
container
<container := := :='{x: 0.5, y: 0.5}'></container>
vtext
<vtext :='{fill: '#', fontSize:''}'></vtext>
具体style属性列表请访问
http://pixijs.download/release/docs/PIXI.TextStyle.html
sprite
sprite如果要填写src,请填写public路径里的位置或使用import导入图片。直接填写相对位置图片可能不能被正常导入。
具体是id还是src,请查看 vroot中texture值是否给出
<sprite>src or id</sprite>
zone
<zone := := :=. [~.]的一个值 :='red' := [~] := 的宽度 :='blue' := [~] := 相对zone的位置,如果为0.线宽一半在里面,一半在外面 为1表明全部在外面 ></zone>
graphics
<graphics :='drawLine' ></graphics><script> 请不要写在methods里,methods里的方法会bind Vue的this { return { this; this; this; } }</script>
更多绘制方法请看 http://pixijs.download/release/docs/PIXI.Graphics.html
class的使用
<vtext ='status'>字体</vtext> <script> { return class: status: class: 'font' style: fontSize: '17px' font: style: fill: '#ffffff' fontFamily: 'sans-serif' }</script>
class相当于一个包含所要填写属性的对象,class里面的值可以填
正常情况下,属性中的值会覆盖class对应的属性,class中的值也会覆盖掉内层引用class对应的值
fit的使用:自适应大小
- 以某个区域自适应大小
<vtext ="font" :="{zone:[x, y, width, height], ratio:[minRatio,maxRatio], :type=""}">哈哈哈</vtext>
zone: 为区域的x,y,width,height
type:为在区域的基本位置
-
Array: [dx,dy] dx,dy均为0~1中的一个值,表明在区域的位置
-
String: center, left, right, top, bottom
ratio: 放大的比例
-
number :锁定放大比例
-
Array: [minRatio, maxRatio] 最小放大比例,最大放大比例
- 以parent尺寸,自适应大小
<zone ="color" := :=> <vtext ="status" ="parent"> fit="parent": 尝试按照parent的大小resize :fit="{zone:'parent', ratio:[minRatio,maxRatio], type:'center'}" 一些文字 </vtext></zone>
event的使用
<zone ="(enemy, index) in enemys" :="enemy.name" :="3 + (lineHeight+3)*index" :$='index' :="['bg', { select: index === select}]" @="clickIndex" > </zone>methods: { console thisselect = eventtarget$index; }
如果使用v-for生成多个结构,如何确定点击了哪一个?
使用
:$index='index'
, 如果仅仅使用@pointertap="clickIndex(i)"
,每次重新刷新,函数都要重新更新,因为传入的是重新生成的一个匿名函数,使用$index
,会直接在pixi属性元素中添加$index
属性($确保不会覆盖正常属性),这样在点击事件中,通过event.target.$index
即可访问到index。
具体event列表
http://pixijs.download/release/docs/PIXI.Sprite.html#event:click
左侧events栏
pointer是兼容mouse和touch的
-
pointerdown 按下
-
pointerup 松起
-
pointermove 移动
-
pointertap 点击
-
pointerout 移出该元素
function使用及淡入淡出效果的实现
-
:update 传入的方法 每帧执行一次,每秒60帧
-
:init 传入的方法 在生成该pixi元素时执行
-
:start 传入的方法,在pixi元素被加入时执行
-
:show :hide
- 如果传入方法
- show: 在init之后执行.
- hide: 第一个参数为回调函数,请以第一个参数作为该函数的回调
- 如果传入数字,则表明淡入或淡出时间
以下两种方式效果相同
<sprite := :=>/img/logopng</sprite><sprite :='show' :='hide'>/img/logopng</sprite>{return{this;}{this;}} - 如果传入方法
注意,请不要写在methods里,methods里的方法会bind Vue的this
<sprite ="icon" :="rotate">/img/logo</sprite><script> { return { thisangle += 1; } }</script>
function 中可使用的一些函数
this
<sprite :="logo" := := :='{x: 0.5,y:0.5}' :='loop' >/img/logopng</sprite><script> { return { this; } }</script>效果为透明度一直改变
this参数为2 个 为 to,time参数为3个 to,rime, callback from,to, callback参数为4个 from,to。time,callback
this;/* 不填参数默认为以自己建立一个tween,填参数则以参数对象具体使用方法见https://github.com/tweenjs/tween.js/blob/master/docs/user_guide.md */thisstart;
简单实例
<template> <vroot ='app' :='width' :='height'> <zone := := := := :=. :=. := ="blue" :=. @='clickMe' > <vtext ='text' ='parent'> button </vtext> </zone> <vtext ='text' :='show'> str </vtext> <sprite ="logo" :='rotate' :='loop'> logo </sprite> </vroot></template> <script>import logo from './assets/logo.png' name: 'App' { const width = 300; const height = 300; return logo width height str: 'vue-pixi-renderer' button: 'Click Me!' class: logo: x: width / 2 y: height / 2 anchor: x: 05 y: 05 text: style: fontSize: '22px' fill: 'red' fontFamily: 'sans-serif' { this; } { thisangle += 1; } { this; this; } } methods: { thisstr = 'you click Vue'; } { thisbutton = 'you click me QAQ'; ; } </script>
示例网站
工程相关
index.js - vue插件的导出
|— components :vue基本组件,functional组件,和 虚拟Tree的实例
—— vroot 为基本组件,附带一个Tree的实例
—— 其余组件均为functional 组件
|——lib
——diff.js - 虚拟node树的diff
——extend.js - 为避免热重载Ticker一直增加导致动画变快而分离开
——index.js - 整体模块的导出
——node.js - 虚拟Node的创建及渲染 以及从functional的参数h,context中创建node的方法
——nodes.js - pixi.js基本元素的包装,增加的一些方法
—— patch.js - 虚拟node树的patch
—— Render.js - 又一层包装,对一些参数的处理成nodes.js对应元素的参数,渲染Node由此处 —— texture.js - sprite中默认系统Sprite:Loading,error和 加载图片后更新node的方法
—— utils.js - 一些utils函数,比如颜色,deep assign, clone
目前BUG:
- 由于没有显式指定Key,在结构发生变化时,比如中间有几个元素消失时,diff判断不是直接移除中间部分,而是逐个比对,导致后续元素使用replace而增大工作量。Vue的functional没有this,暂时没有找到给每一个元素一个单独id作为key的方案。
- fit指定为'parent'时,内部元素改变时可能不能正常更新,父级元素改变时同样可能不能正常更新。
- Graphics重新绘制后可能width,height不重新改变,导致fit更新失败。
- 元素的复用有没有可能?清空一个元素再把值赋予?
TODO:
- 性能感觉不好。如果每帧渲染一次感觉是极大的负担,不建议更改属性完成某些动画操作。如何性能优化?不确定哪些属性更改了,要全盘比对,耗资源较大。感觉主要适用于一些ui的绘制。
- 提供:texture参数时 sprite的显示和报错未测试
更新日志:
4-5:
- 默认将所有node的interactiveChildren设为false,当一个node有事件时,向上将parent的interactiveChildren设置为true
- 修复了v-if使用中不能正常diff的问题。
- 完善了图片路径加载的报错提示、热重载、以及用系统警告图片代替加载失败的图片等。
- 增加了异步删除逻辑,可以在一个元素remove时,传入:remove函数实现消失动画。
4-7:
- 增加了 show,hide方法,用hide来代替:remove
- 修复了sprite加载热重载的bug