开源跨平台移动项目Ngui【Action动作系统】

Ngui简介

这是一个GUI的排版显示引擎和跨平台的GUI应用程序开发框架,基于NodeJS/OpenGL,这也是第一个在移动端Android/iOS融合NodeJS的前端GUI项目,至此JavaScript成为了真正意义上前后端通吃的语言。

Ngui的目标:在此基础上开发GUI应用程序可拥有开发WEB应用般简单与速度同时兼顾Native应用程序的性能与体验。

什么是Action动作

什么是动作呢?顾名思义它是管理运行环境中所有动作的中枢,通俗点讲就是动画。它也是总个框架核心组件之一,它提供动作的创建、删除、插入,以及提供对关键帧与过渡的诸多操作。关键帧的过渡可以使用三次贝塞尔曲线,或内置的曲线 linear/ease/ease_in/ease_out/ease_in_out,这也和大多数主流框架以及游戏引擎类似。

动作是什么原理

动作怎么驱动视图进行流畅运动的呢?其实原理很简单,我们可以把动作系统看做一个独立的系统与视图或渲染完全不相关。它们之间的关系是动作自身的变化最终会映射调视图,这个过程是通过调用视图暴露的公有方法或属性来完成的。这个过程完全是单向的,且视图不会向动作发出任何指令。 比如说现在创建了一个新的关键帧动作,给它设置两个关键帧,且x的值经过1秒钟从0变化到100。这个过程是动作自身发生的变化并且带动与之相关的视图一同发生改变,请记住这个过程视图是被动的,而动作才是主动的发生改变。

import { ngui, Div } from 'ngui';
import KeyframeAction from 'ngui/action';
var div = new Div();
var act = new KeyframeAction();
act.add({ x: 0, time: 0 });
act.add({ x: 100, time: 1e3/*毫秒*/ });
div.width = 50;
div.height = 50;
div.backgroundColor = '#f00';
div.action = act;
div.appendTo(ngui.root);
act.play();

动作类别

以下是框架提供的几个类型与继承联系

注:带*号的为抽象类型或协议没有构造函数

Action*

这是所有动作的基础类型,也是抽象类型不可以直接被实例。 提供了一些基本的api操作,播放停止跳转 等,具体可查看API手册。

GroupAction*

这是个集合的动作类型,提供子动作的添加删除插入。有了子动作就可以帮你实现更加复杂的动画场景。 它也有两个具体的子类型 SpawnActionSequenceAction

SpawnAction

并行动作顾名思义即就是它的子动作都是并行运行的。并且以最长子动作的时长做为自身的时长来执行动作,较短时长的子动作则在结尾等待动作的结束或一个循环的的终止。

SequenceAction

串行动作这个比较好理解,子动作一个接着一个执行,全部执行完成后结束或开始新的循环。

KeyframeAction与Frame

关键帧动作这是动作系统的核心。所有动作的实现均在这里完成它是动作系统基本单元,前面的GroupAction只有包含KeyframeAction类型的动作才有真正的义意。 而关键帧动作又包含理更加基本的元素关键帧Frame,关键帧包含的属性与CSS属性是同名的且与所有视图的属性都是对应关键。通俗的说比如View上会有x属性而Frame上也会有x属性,如果关键帧上有视图上并不存在的属性,那么这个属性对视图是无效的。比如View上就不存在width属性那么这个属性的改变不会影响到View,但如果绑定的视图是Div那么width的改变一定会影响到它,这与CSS样式表类似。

看下面的例子:

// 这是有效的动作
var act1 = new KeyframeAction();
var div = new Div();
div.backgroundColor = '#f00';
act1.add({ width: 10, height: 10 });
act1.add({ width: 100, height: 100, time: 1e3 });
div.action = act1;
act1.paly();
// 这是无效的
var act2 = new KeyframeAction();
var view = new View();
act2.add({ width: 10, height: 10 });
act2.add({ width: 100, height: 100, time: 1e3 });
view.action = act2;
act2.paly();

View.action属性

View.action做为View的一个属性可接收多种类型的参数,之前给大家展示的例子中创建动作是很繁琐的,但active提供多种类型的参数类型的支持,包括json数据与Action对像实例本身。前面的例子中已介绍过Action方式,下面着重说json数据方法。大家也可研读ngui.jsaction.js中的源代码,其它View.action属性只是做简单的调用转发,功能的实现其实是在action.js文件中的create()方法里实现的。

看例子:

// 这是创建KeyframeAction
var div = new Div();
div.action = {
    keyframe: [
        { x: 0 },
        { x: 100, time: 500 },
        { x: 0, time: 1000 },
    ],
    loop: -1,
};
var div2 = new Div();
div.action = [
    { x: 0 },
    { x: 100, time: 500 },
];

// 这是创建SequenceAction
var div3 = new Div();
div3.action = {
    seq: [
        [ // 这是个子KeyframeAction
            { x: 0 },
            { x: 100, time: 1e3 },
        ],
        { // 这是个子SpawnAction
            spawn: [
                [ // 这是个子KeyframeAction
                    { y : 100 }, { y: 200, time: 2e3 }
                ],
                [ // 这是个子KeyframeAction
                    { width : 200 }, { width: 100, time: 1e3 }
                ],
            ] 
        }
    ],
};

// 这是创建SpawnAction
var div4 = new Div();
div4.action = {
    spawn: [ // 这里只包含一个子KeyframeAction
        {x: 0}, {x: 200, time: 2e3} 
    ]
};

大家可以看到上面的例子中有4种典型的创建方法。主要看你给的json数据是否存在这三个属性seqspawnkeyframe,对应SpawnActionSequenceActionKeyframeAction,外加一个json数据类型检查,数据类型为数组就创建KeyframeAction。并且这可以嵌套使用。

View.transition()方法

这是一个简单创建简单过渡动画的方法,实现原型为action.jstransition()方法,与View.action一样View.transition()只做简单的转发。

典型应用:

view.transition({
    time: 1000,
    y: 100, 
    x: 100,
})

具体可查阅手册。

View.onActionKeyframe与View.onActionLoop

这两个事件是由动作产生并发送的。

  • View.onActionKeyframe为动作执行到达关键帧时触发。因为画面渲染是固定的帧率,触发总是发生在帧的渲染时,所以可能会与理想中的时间值有所误差提前或延后,这个延时值会保存在事件数据的delay上。提前为负数,延时为正数。
  • View.onActionLoop动作循环开始时触发,第一次执行动作并不会触发。同样它也会有延时,也同样记录在delay

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏从零开始学 Web 前端

从零开始学 Web 之 Vue.js(一)Vue.js概述,基本结构,指令,事件修饰符,样式

在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。现在就让我们一起进入 Web 前端学习的冒险之旅吧!

662
来自专栏闻道于事

JavaScript事件与例子(三)

两个例子,好友选中效果和左侧右侧子菜单 一、好友选中效果 可以通过设置属性的方式判断当前是否被选中,也可以通过获取当前元素的颜色从而得知当前元素状态是否被选中,...

2736
来自专栏一个会写诗的程序员的博客

JQuery中bind和unbind函数

测试: 页面代码: <body> <input type="button" name="aaa" value="点击我"> <input type="c...

852
来自专栏Django中文社区

Django Pagination 完善分页

在 Django Pagination 简单分页 中,我们实现了一个简单的分页导航效果。但效果有点差强人意,我们只能点上一页和下一页的按钮进行翻页。比较完善的分...

2885
来自专栏前端儿

jQuery的 delegate问题

支持为动态生成的标签元素绑定事件也许就live和delegate了吧,不过新版本已经不支持live了,只有delegate

721
来自专栏Java帮帮-微信公众号-技术文章全总结

CSS Selectors Level 4新特性全面解析

前言 当看到 CSS Selectors Level 4 很多人会理所当然地喊出 CSS4。但是,这里必须明确一个概念,目前所谓的 CSS3 和 CSS4 都是...

2897
来自专栏zaking's

CSS(CSS3)选择器(2)

该部分主要为CSS3新增的选择器 接上一篇 CSS(CSS3)选择器(1) 一.通用兄弟选择器:                         24:E ~ ...

2626
来自专栏xingoo, 一个梦想做发明家的程序员

【前端开发系列】—— CSS3属性选择器总结

想想自己为什么要学CSS,作为一个开发过前端的人员来说,调试一个图片花了半天的时间,最后发现分隔符用错了,实在是一件很丢人的事情。因此,痛下决心来学习CSS,...

1807
来自专栏个人随笔

初识CSS3

1.CSS规则由两部分构成,即选择器和声明器    声明必须放在{}中并且声明可以是一条或者多条    每条声明由一个属性和值构成,属性和值用冒号分开,每条语句...

3278
来自专栏郭少华

(第二季)Vue2.0-全局API

全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,说的简单些就是,在构造器外部用Vue提供给我们的API...

461

扫码关注云+社区