蓝紫™
DDZEB 完全自主知识产权图形图像开发平台
开放源码 免费使用 在线运行
蓝紫程序解析及调度引擎,蓝紫动画渲染基础设施。
文件语言大小版本开发者最后更新
lands/runner productionJavaScript2.5KBv1.0.1YB2024-10-27查看
lands/runner source codeJavaScript9.4KBv1.0.1YB2024-10-27查看
一、简要介绍 二、蓝紫程序接口方法三、简易集成接口方法四、深度集成接口方法五、接口事件六、辅助接口一、简要介绍

蓝紫 runner 库特别小,同时也特别重要。它主要用于程序解析及渲染调度,在蓝紫集成开发环境里,它负责运行我们编写的蓝紫程序。当我们编写蓝紫程序的时候,蓝紫集成开发环境提供 runner,我们不需要导入它,只需要在程序里通过 Lan 变量进行访问。

$js
const canvas = await Lan.frag();
Lan.loop(canvas.render);

$fs
#define rot2(a) mat2(cos(a),-sin(a),sin(a),cos(a))
@run {
  FLUSH(vec3(abs(UVx2 * rot2(uTime * .5)), 0).rbg);
}

我们也可以在第三方平台使用 runner,一种方式是使用它解析和运行蓝紫程序,可以参考我们在 CodePen 上的例子:Basic Lands Integration。另一种方式是使用其调度功能,它不只是重复执行操作,更重要的是会管理执行环境信息,比如时间,帧数以及程序运行状态等。这种方式的使用例子可以参考:Lands runner Demo

二、蓝紫程序接口方法

以下接口方法是在蓝紫 IDE 里编写程序的时候需要用到的接口,我们通过全局变量 Lan 访问 runner 接口。

2.1、import(lib) => Promise

此接口是对 JavaScript 函数 import 的简单封装,我们可以使用它进行常规的包导入:

const {mouse} = await Lan.import('//ddzeb.com/lands/mouse');

这样就可以导入鼠标交互相关的功能。因为是导入的蓝紫程序包,我们可以简单一点:

const {mouse} = await Lan.import('mouse');

这就是在蓝紫里导入我们提供的程序包最常见的方式,具体例子请参考蓝紫向导程序:交互式画布

2.2、init(width, height)

该方法用于初始化画布,它唯一作的事情就是设置画布的 width 以及 height 这两个属性。我们可以使用这个函数获得原始画布:

const canvas = Lan.init(900, 600);

参数 width 和 height 可以不用传,也可以只传 width 不传 height,程序会根据 canvas 本身的设置进行计算。详细使用情况,可参考向导程序:Image Bitmap

2.3、核心渲染引擎接口

核心渲染引擎都可以通过 runner 提供的专门接口进行调用,比如 frag 引擎:

const canvas = await Lan.frag(900, 600, {options});
canvas.render();

实际上相当于如下流程:

const {frag} = await Lan.import('frag');
const canvas = Lan.init(900, 600);
await frag(canvas, {options});
canvas.render();

蓝紫所有的核心渲染引擎均可通过此方式使用,包括:fragcomputepixelscurvewebgl。这些接口全部都有相同的调用方式:

const canvas = await Lan.xxx(canvas_width, canvas_height, {options});

其中 xxx 为渲染引擎名称,注意使用 await 进行同步调用。canvas_width 以及 canvas_height 用于 init 画布,options 会被传给具体的渲染引擎,所有参数都是可选参数,可以有好几种方式:

const canvas = await Lan.xxx();
const canvas = await Lan.xxx({options});
const canvas = await Lan.xxx(canvas_width, {options});
const canvas = await Lan.xxx(canvas_width, canvas_height);
2.4、loop(callback, options = {}) => Promise

动画渲染的关键接口,重复执行任务。其中 callback 为需要执行的函数,options 为可选参数:

  • maxframes:控制最多执行多少次,缺省为无限制。

    要让循环停止运行,还可以在 callback 函数里返回 false 来达到同样目的。loop 在调用 callback 的时候,会传入一个对象参数,该对象具有如下属性:

  • time:loop 运行时间(去掉了暂停时间),单位为秒。
  • frame:帧计数,从 0 帧开始。

    蓝紫的核心渲染引擎大部分都提供了 render 方法,该方法接受的参数与 loop 提供的参数一致:

    const canvas = await Lan.frag(900, 600, {options});
    Lan.loop(canvas.render);

    这样我们就可以循环往复的调用 render 方法进行动画渲染了。

    2.5、log(msg)

    要在蓝紫程序里写日志,可以使用 Lan.log 方法。

    Lan.log("program started");
    三、简易集成接口方法

    如果想将蓝紫 IDE 里编写的程序移植到第三方平台上运行,最简单的方法就是调用 run 接口,将整个程序代码传进去运行即可。

    3.1、run(source, canvas)

    该方法解析并运行一个蓝紫程序,source 为程序代码,canvas 为目标渲染画布。

    import('//ddzeb.com/lands/runner').then((lands) => {
      const runner = lands.runner();
      runner.run(source, canvas);
    });
    CodePen 集成程序:Basic Lands Integration
    四、深度集成接口方法

    深度集成的时候,首先 bind 一个画布,然后 init,接下来就可以进行 loop 调用。参考例子:Lands runner Demo

    4.1、bind(canvas)

    绑定一个 canvas,准备进行渲染。

    4.2、unbind()

    解除 canvas 绑定,然后可以重新绑定。

    4.3、status()

    获取程序运行状态,参见本页 5.3 节。

    4.4、pause()

    请求暂停 loop 执行。

    4.5、resume()

    请求恢复 loop 执行。

    4.6、stop()

    请求停止 loop 执行。

    五、接口事件 5.1、oninit(canvas)

    初始化画布的时候会调用 oninit 事件,我们可以这样去配置:

    const lands = await import("https://ddzeb.com/lands/runner");
    const runner = lands.runner();
    runner.oninit = (canvas) => {
      // display information about the canvas
    };
    5.2、onlog(msg)

    蓝紫程序需要打印日志信息的时候需要配置好该事件处理函数。

    const lands = await import("https://ddzeb.com/lands/runner");
    const runner = lands.runner();
    runner.onlog = (msg) => {
      const div = document.createElement('div');
      div.innerText = msg;
      logcontainer.appendChild(div);
      return div;
    };

    通常,我们希望 onlog 能返回一个 Element,这样可以将一个长时间操作的结果信息添加(append)到它的末尾。

    5.3、onstatus(status)
    const lands = await import("https://ddzeb.com/lands/runner");
    const runner = lands.runner();
    runner.onstatus = (status) => {
      console.log(status);
    };

    其中的 status 参数取值如下:

  • 0:程序停止运行或未开始;
  • 1:程序运行中;
  • 2:程序正在进行 loop 循环;
  • 4:loop 已暂停。5.4、onloop()

    loop 开始前抛出该事件,如果这时候暂停(pause),则 loop 将等待 resume 命令才会真正开始。

    5.5、onfps(fps, time, frame)

    报告渲染帧率。

    5.6、onauth(msg)

    某些操作,比如播放音频,需要用户与页面进行交互之后才能播放,这时候就会调用 onauth 方法进行用户授权。我们可以弹出一个按钮让用户点击进行授权:

    const lands = await import("https://ddzeb.com/lands/runner");
    const runner = lands.runner();
    runner.onauth = (msg) => new Promise((resolve) => {
      // display the message and show a button
      // when the user clicks on the button, promise resolved
    });

    具体可参考蓝紫示例程序:Audio Visualization

    六、辅助接口 6.1、offscreenCanvas(width, height)

    创建一个离屏画布,参考:Canvas Texture