Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >开源跨平台移动项目Ngui【Action动作系统】

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

作者头像
IMWeb前端团队
发布于 2017-12-29 02:24:34
发布于 2017-12-29 02:24:34
1K00
代码可运行
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队
运行总次数:0
代码可运行

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。这个过程是动作自身发生的变化并且带动与之相关的视图一同发生改变,请记住这个过程视图是被动的,而动作才是主动的发生改变。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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样式表类似。

看下面的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 这是有效的动作
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()方法里实现的。

看例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 这是创建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()只做简单的转发。

典型应用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
view.transition({
    time: 1000,
    y: 100, 
    x: 100,
})

具体可查阅手册。

View.onActionKeyframe与View.onActionLoop

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

  • View.onActionKeyframe为动作执行到达关键帧时触发。因为画面渲染是固定的帧率,触发总是发生在帧的渲染时,所以可能会与理想中的时间值有所误差提前或延后,这个延时值会保存在事件数据的delay上。提前为负数,延时为正数。
  • View.onActionLoop动作循环开始时触发,第一次执行动作并不会触发。同样它也会有延时,也同样记录在delay
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
stream 流的使用技巧总结,这些你必须知道
我们都知道Stream,是jdk8的一大新特性,极大的提高了道友们的开发效率(用过的道友都知道的),也使我们的代码看起来也更加地简洁,但Stream中除了Lambda表达式,另一块就是函数编程了,这块对于刚开始使用Stream的道友们来说,就得开始头疼抓狂了;别担心,下面我们就来总结一下常用技巧。
前端小tips
2021/11/28
3910
stream 流的使用技巧总结,这些你必须知道
工作经验|lambada处理集合的常用10种实战骚操作,我都记录下来了
最近在项目上面经常使用lambada表达式,但是总是记不住,一直都在百度,写完之后就忘记了,感觉很费时间;这次就花点时间,把一些常用的lambada 处理集合的实例都保存了下来(去重,分组,求和,list转map等等),以后就不用到处找了,刚好也可以给同学们分享下;另外也把一些关于使用lambada时遇到的坑也给大家一起分享下,所有代码拿来即用!!!本文档持续更新...
AI码师
2021/02/03
6120
工作经验|lambada处理集合的常用10种实战骚操作,我都记录下来了
Java8编程小技巧,提高代码效率100%!超级实用!
大家好,我是小义,今天分享几个Java8编程小技巧,提高代码逼格,写出优雅代码,让同事看了也直呼内行。
程序员小义
2024/05/20
1870
Java8编程小技巧,提高代码效率100%!超级实用!
Java8的List Object 去重
假设Object为User,此处User类中省略getting/setting以及相关构造方法。
WindCoder
2020/01/21
1.9K0
List对象去重及按属性去重的8种方法-java基础总结第六篇
最近在写一些关于java基础的文章,但是我又不想按照教科书的方式去写知识点的文章,因为意义不大。基础知识太多了,如何将这些知识归纳总结,总结出优缺点或者是使用场景才是对知识的升华。所以我更想把java相关的基础知识进行穿针引线,进行整体上的总结。
字母哥博客
2020/09/23
8.1K0
List对象去重及按属性去重的8种方法-java基础总结第六篇
Java常用工具类2 - 崔笑颜的博客
方法一:简单粗暴,直接使用copy(),如果目标存在,先使用delete()删除,再复制;
崔笑颜
2021/02/02
4820
Java 集合去重
例如:不重写 equals 方法的情况下,根据 Employee 的 id 字段进行去重处理
Power
2025/04/03
380
Stream流用于按照对象中某一属性来对集合去重+简单数据类型集合的去重
上次对Stream流来进行分组的文章很多人看,想看的可以来这: Stream流来进行集合分组 这次小编又带来Stream的去重,话不多数,直接上代码:
掉发的小王
2022/07/11
1.6K0
阿里字节技术大佬都在用的List集合去重方案!
碰到List去重的问题,除了遍历去重,我们常常想到利用Set集合不允许重复元素的特点,通过List和Set互转,来去掉重复元素。
JavaEdge
2021/12/07
2680
阿里字节技术大佬都在用的List集合去重方案!
使用 Java8的 stream对list数据去重,使用filter()过滤列表,list转map「建议收藏」
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/141093.html原文链接:https://javaforall.cn
全栈程序员站长
2022/08/24
4.1K0
Java中的对象去重工具类——灵活、高效的去重解决方案
在日常开发中,我们经常会遇到需要对对象列表进行去重的需求。比如,从数据库中查询出一批用户数据,但其中可能存在重复记录,我们需要根据某些字段(如姓名、年龄等)来去除重复项。今天,我将分享一个非常实用的Java工具类——DeduplicationUtils,它可以帮助我们轻松实现基于对象字段的灵活去重。
訾博ZiBo
2025/01/24
750
Java8 Stream 中 Collectors 的24个操作
Collectors,可以说是Java8的最常用操作了,用来实现对队列的各种操作,包括:分组、聚合等,官方描述是:
用户4396583
2024/08/13
1210
List Stream 的常规用法
// 遍历后判断赋给另一个List集合,保持原来顺序 public static void ridRepeat1(List<String> list) { System.out.println("list = [" + list + "]"); List<String> listNew = new ArrayList<String>(); for (String str : list) { if (!listNew.contains(str)) { listNew.add(str); } } System.out.println("listNew = [" + listNew + "]"); }
小马哥学JAVA
2022/11/21
4350
lambda
List<BigDecimal> lis = new ArrayList<BigDecimal>();
用户6019926
2024/01/04
1300
Java 集合数据处理技巧:使用 Stream API 实现多种操作
在处理 List 数据时,有时需要根据对象的某个属性进行去重。可以使用 TreeSet 和 Stream 来实现这一功能。以下是示例代码:
小码农薛尧
2025/02/26
1790
Java 集合数据处理技巧:使用 Stream API 实现多种操作
Java8 用 Stream 快速实现List转Map 、分组、过滤等操作
这篇文章主要介绍了java8快速实现List转map 、分组、过滤等操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
搜云库技术团队
2020/09/01
25.4K0
拥抱JAVA
2、获取当前时间,SimpleDateFormat 不是线程安全的,在多线程环境会有并发安全问题,DateFormatUtils是线程安全的
adu
2022/10/30
3070
Lambda表达式和函数式编程
迭代器内第一个参数为初始值,第二个参数为一个lambda表达式,因为这个循环是个死循环所以这边limit了前10个元素
后端码匠
2021/04/02
1.3K0
Java8特性大全(最新版)
随着对 Java8 新特性理解的深入,会被 Lambda 表达式(包含方法引用)、流式运算的美所迷恋,不由惊叹框架设计的美。
赛先生和泰先生
2022/01/19
2.1K1
Java8特性大全(最新版)
4.2.Java8 Stream简单的应用
        元素序列:像集合一样,流也提供了一个接口,可以访问特定元素类型的一组有序值,因为集合是数据结构,所以他的主要目的是以特定的时间/空间复杂度存储和访问元素,但流的目的在于表达计算。集合讲的是数据,流讲的是计算。
itjim
2019/11/22
7550
4.2.Java8 Stream简单的应用
推荐阅读
相关推荐
stream 流的使用技巧总结,这些你必须知道
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验