微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

适用于javascript开发者的Processing.js入门教程

这个入门指导是为javascript开发者写的。读这个文档之前,你最好掌握javascript和web开发编程,并还会非常基本的 Processing 知识。 目录:

为没有耐心看长篇大论的人准备:

如果你很着急入门,那么你就需要知道以下几点: 1、Processing.js 把 Processing 代码转变成能够在浏览器端运行的javascript代码,实质是通过标签来实现绘图的; 2、为了使用它,你的首先下载 Processing.js; 3、创建你的 后缀名为".pde"的 Processing 文件,它和通常你创建的普通文本文件一样,例如: hello-web.pde 4、创建一个 html 页面,然后在页面里外引用 Processing.js文件,再添加一个标签,该标签上指明有你的 sketch file(顾名思义,草图文件,就是Processing 文件),sketch file 可以有多个文件,多个文件用空格隔开。例如:

rush:js;">

Processing.js Test

This is my first Processing.js web-based sketch:

页面加载完(on page load),processing.js将会自动浏览web页面的document,去查找属性data-processing-sources,然后用XMLHTTPRequest去下载 这些文件,将它们塞进从porcessing到javascript的翻译器,翻译后的javascript将会通过eval 函数来执行。

预编译 processing 代码 为 javascript

Processing.js 自动下载并将所有Processing 代码转成 javascript。它做这些是使用Processing.compile()方法来完成的,并且 那些相关的processing构建工具 或者实用工具也可以做同样的事情。 为了获得 从Processing 代码编译后的代码(例如,JavaScript适用于processing.js运行),请按如下操作:

rush:js;"> // hard-coded Processing code,text from an HTML widget,downloaded text,etc. var processingCode = "..."; var jsCode = Processing.compile(processingCode).sourceCode;

例如,转化如下的Processing 代码生成 在它之下的 编译的来的javascript代码

rush:js;"> // Processing code void setup() { size(200,200); background(100); stroke(255); ellipse(50,50,25,25); println("hello web!"); }

// "Comiled" JavaScript code
// this code was autogenerated from PJS
(function(processing,$constants) {
function setup() {
processing.size(200,200);
processing.background(100);
processing.stroke(255);
processing.ellipse(50,25);
processing.println("hello web!");
}
processing.setup = setup;
})

只写 javascritp的 processing.js code

前面的方法把 processing 代吗生成了 javascript 代码,但是你也可以单独写javascript。processing.js的解析器将Processing代码转化成javascript方法,然后运行它。因此,完全有可能跳过Processing代码,只写javascript 方法,将方法传给一个Processing实例。这有个例子如下:

rush:js;"> function sketchProc(processing) { // Override draw function,by default it will be called 60 times per second processing.draw = function() { // determine center and max clock arm length var centerX = processing.width / 2,centerY = processing.height / 2; var maxArmlength = Math.min(centerX,centerY);

function drawArm(position,lengthScale,weight) {
processing.strokeWeight(weight);
processing.line(centerX,centerY,centerX + Math.sin(position 2 Math.PI) lengthScale maxArmlength,centerY - Math.cos(position 2 Math.PI) lengthScale maxArmlength);
}

// erase background
processing.background(224);

var Now = new Date();

// Moving hours arm by small increments
var hoursPosition = (Now.getHours() % 12 + Now.getMinutes() / 60) / 12;
drawArm(hoursPosition,0.5,5);

// Moving minutes arm by small increments
var minutesPosition = (Now.getMinutes() + Now.getSeconds() / 60) / 60;
drawArm(minutesPosition,0.80,3);

// Moving hour arm by second increments
var secondsPosition = Now.getSeconds() / 60;
drawArm(secondsPosition,0.90,1);
};
}

var canvas = document.getElementById("canvas1");
// attaching the sketchProc function to the canvas
var processingInstance = new Processing(canvas,sketchProc);

这儿是创建了一个 sketch 方法,这个方法就和解析器生成代码一样。这个方法需要一个参数,它是一个指向某个由Processing构造器生成的processing对象(例如,Processing运行时对象)的引用,任何 Procesing方法或者对象都一个作为它的属性来访问。 一旦这个方法完成,并且通过,随着就有一个引用指向canvas,一个引用指向 Processing构造器(记得用"new")。

一个 Processing 和 javascript结合的文件

人们经常问的第一个问题就是processing.js是否可以读取来自正在运行Processing sketch的文件的值。或者反过来的观点。答案是肯定的。 Processing.js 转化 Processing 代码一个含有函数闭包javascript代码。所有你创建的变量和方法没有被绑定到全局变量上(即:window)。然而,你仍然可以访问他们。 1)、从Processing里访问 javascript对象 从Processing代码转化成javascript并且和其他函数一样运行起来,所有Processing代码都可以访问全局对象。这意味着你可以在全局脚本模块里创建一个变量或者方法,它们就可以自动被Processing来访问。考虑这样一个例子: 首先是 Processing 文件,mixed.pde:

rush:js;"> String processingString = "Hello from Processing!";

void setup() {
printMessage(jsstring + " " + processingString);
}

接下来是web页面

rush:xhtml;"> Hello Web - Accessing JavaScript from Processing

这里 Processing.js允许使用的变量和方法声明在 Processing代码的外边。 2)、javascript 和 Processing代码的混合 前面的例子使得javascript和processing代码各自放在单独的文件里,当它们之间的界限不是分的很近时。 因为Processing.js在转化代码时,也可能直接将他们直接混在一起。Processing.js解析器保留包含在Processing代码里的 javascript不变,这样就允许开发者能写processing和javascript的混合代码(注意:这也就是为什么 processing.js里没有使用纯processing解析器的原因)。这是一个之前也是用这个方法写的例子:

rush:js;"> var jsstring = "Hello from JavaScript!"; var printMessage = function(msg) { document.getElementById('msg').innerHTML = "Message: " + msg; };

String processingString = "Hello from Processing!";

void setup() {
printMessage(jsstring + " " + processingString);
}

有些javascript语法很难用这种方式混在一起写(例如:正则语法)。如果是那样的情况的话,你可以简单地将纯javasript代码移到一个

在DOM结构中有2个按钮,他们被用来让用户选择开始或暂停正在运行的Processing sketch. 他们直接在javascript中控制Processing实例(在页面里你可能有多个,或者藏在div中),通过调用Processing的方法:loop()和noLoop()。这些Processing 的方法可以在其他的文件中找到。

作为一个使用Processing.js的开发者必须知道的事情:

当 Processing.js试图去完全兼容 Processing时,就有些不同的事情或者需要解决办法。我们也增加了一些web规范的功能来使Processing更容易被使用。 这里有一些技巧和提示在你开始使用Processing.js做复杂的sketch时可能有帮助。

Processing.js提供通过“externals”属性来访问各种 DOM/javascript对象

每个Processing 实例(即:Processing.instances)包含有一个"external"属性,它是一个对象,包含各种指向非常有用的非Processing 的DOM/javascritp 对象,例如:

rush:js;"> canvas--sketch被绑定上的画板 context--画板的执行上下文 onblur and onfocus--事件处理器

如果一个除法表达式期望产生一个整型值,那么这可能需要显式转换

当将Processing代码转化成javascript,涉及整型 vs 浮点型的除法的时候,有一个有bug的class会出现这个问题。 在Processing代码中出现某个东西直接除以整数的代码块,当被转化成Processing时,可能有时出现问题,因为,整型编程双精度型,被引入了一个小数部分。修补这个bug的方法是 显式转换任何除法,正如展示的做法:

rush:js;"> // before int g = mouseX / i;

// after
int g = (int)(mouseX / i);

Processing.js有个欺骗在模拟 Processing的异步输入输出

Processing 使用一个同步输入输出的模型,这就意味着 像loadImage()方法这样,需要相对长时间去执行,然而当他们执行期间,又没有任何事发生,程序等到它loadImage()执行完才去执行下一行语句。这就意味这可以依靠像loadImage()这样的方法返回的值用在接下来的代码中。 但是web浏览器却不是这样的,它使用的是异步输入输出模型,这意味着加载外部资源的方法不能使得程序等到他们加载完再执行。为了实现Processing的load方法,你不得不使用一个特殊的Processing的指令。 Processing.js指令提示浏览器,指令是写在注释里而不是Processing自身代码。这是一个典型的 Processing sketch,它需要同步加载一个图片然后画出它:

rush:js;"> PImage img;

void setup() {
img = loadImage("picture.jpg");
image(img,0);
}

这些代码在含有Processing.js的浏览器里将不会执行,因为图片文件 picture.jpg被加载完之前就被调用了。修补这个bug的办法是让在sketch 开始执行前就把图片加载好,并且缓存起来,就是所说的预加载技术。这是修改后的代码

rush:js;"> /* @pjs preload="picture.jpg"; */ PImage img;

void setup() {
img = loadImage("picture.jpg");
image(img,0);
}

注意:放在代码顶部的额外的注释行。"@jps"指令是给Processjing.js用的,不是给开发者用的。可以把它认为成额外的代码行,它们将在程序执行前就被执行了。 如果你有多个图片被加载,可以使用如下列表:

rush:js;"> /* @pjs preload="picture.jpg,picture2.jpg,picture3.png"; */

Processing.js需要更多的注意在变量的命名上比Processing javascript其中一个最强大的特性就是它的动态,弱类型的性质。因为java是强类型的语言,所以Processing也是,他们能重复命名而不用还怕产生歧义(例如:方法的重载),Processing.js就不行。不能进入javascript的内部工作,所以对Processing.js的开发者来说,最好的建议就是不要用 function/class/etc/,也不要用来自Processing的名字来命名变量。例如,一个叫 line的变量可能看起来合理,但是它会导致问题,因为它和Processing与Procesing.js内置的函数名line()一样。 当要覆盖重载的父类方法时,Processing需要你的帮助 如果你的代码使用子类覆盖一个或多个父类里重载的方法,你需要“假”覆盖,因为,每个方法签名,你通常就没改动过:

rush:js;"> class X { void doSomething() { ... }

void doSomething(float x,float y)
{
...
}
}

class Y extends X
{
void doSomething()
{
// different code from compared to the super class
}

// even though we don't override this method,// its signature must be added to prevent Pjs
// from getting the method chain wrong:
void doSomething(float x,float y)
{
super.doSomething(x,y);
}
}

尽管在Processing里 你不需要实现拥有(float,float)签名的空方法doSomething,但是这样做几乎是必须的,这是为了确保Processing.js在调用方法时不被搞晕。 直接将Processing 代码放在web页面里也是可以的 在canvas上,用一个 data-processing-source属性包含Processing.js加载的外部文件的做法是首选,但是推荐的方式在web页面里外引用脚本。但是写成行内引用也是可以的。 把上边例子的代码作为行内引用的方式,有必要的改动一点:

rush:js;">

这些代码是更复杂了,因为它没有指出那个canvas配那个脚本文件(即:你可以在一个页面引用多个Processing sketch,同样也可以有多个canvas)。也没有说明脚本的"type"属性,这个属性是用来区别javascript和Processing代码的(浏览器将忽略 Processing 脚本)。最后,注意:"id"和"target"属性用法,它俩是用来连接Processing脚本和相关的canvas的。

以上就是本文的全部内容,希望大家对Processing.js有所认识。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐