Processing4Net





5.00/5 (23投票s)
释放你内心的随机艺术家。
引言
Processing4Net 是一个简单的 ASP.NET 包装器,围绕 processing.js,这是 John Resig 在 2008 年将 processing 编程语言移植到 JavaScript 的一个版本。Processing 是一种由 Casey Reas 和 Benjamin Fry 为电子艺术和视觉设计社区创建的编程语言。
Processing 最初的开发目的是作为软件速写本,并在视觉化背景下教授计算机编程的基础知识。从那时起,Processing 已经发展成为一种生成成熟专业作品的工具,如今有成千上万的艺术家、设计师、研究人员、学生和业余爱好者使用 Processing 进行学习、原型制作和生产。
几年前我第一次接触到 Processing 项目,发现它是一种创建赏心悦目的图形的绝佳工具,具有强大的功能。
上面的图像来自“Exit”,这是一个关于人类迁移数据的半小时沉浸式可视化,是完整的 Processing 系统有多强大的一个绝佳示例:http://stewd.io/w/exit/
Processing 是一种编程语言,旨在让创建图像、动画和交互变得容易。Processing 的理念是创建一个允许学生使用提供即时满足感的工具来学习编程的东西。添加一行代码,屏幕上就会出现一个圆圈,再添加几行代码,圆圈就会跟随鼠标移动,然后通过添加几行代码就可以改变圆圈的颜色。
这被称为“用代码进行速写”,用 Processing 编写的程序通常被称为“速写”。
虽然 Processing 基于 Java,但 Processing.js 允许 Processing 代码由任何支持 HTML5 的浏览器运行,包括当前版本的 Firefox、Safari、Chrome、Opera 和 Internet Explorer。即使 Processing.js 与其同源项目相比有一些限制,它仍然是基于 HTML5 的图形编程最强大的环境之一。
下面是由 Benjamin Blundell 使用 processing.js 实现的经典“小行星”游戏的截图。
Processing4Net 实现
在撰写本文时,processing.js 的当前版本是 1.3.6,因此 Processing4Net 是一个 ASP.NET 服务器控件的实现,允许我们轻松地将处理文件 (*.pde) 嵌入到我们的网页中。想法是,当我们想要在页面中添加 processing.js 功能时,能够写出像下面一样简单的内容会很不错:
<cc1:Processing ID="Processing1" runat="server" Sources="curves11.pde">
</cc1:Processing>
当我们想在页面中添加 processing.js 功能时——而无需考虑 canvas 或 JavaScript 相关的东西。
事实证明,创建一个 ASP.NET 服务器控件来处理 processing.js 非常简单,只要我们想做的是将处理文件加载到浏览器中。首先,我们创建一个名为 Processing4Net 的 C# 类库,然后创建名为 Processing 的控件。
[ToolboxData(@"<{0}:Processing runat=""server"" > </{0}:Processing>")]
public class Processing : Panel
{
}
我选择让 Processing 控件派生自 Panel,但暂时不要将其视为一个功能齐全的 Panel,因为子控件将无法正确处理。ToolboxData 属性定义了当您将控件拖放到页面设计器表面时添加到 ASP.NET 页面的标记代码。接下来,我们需要一个用于 Processing 文件的属性:
[
Bindable(true),
DefaultValue("")
]
public String Sources
{
get
{
return ToString(ViewState["data-processing-sources"]);
}
set
{
ViewState["data-processing-sources"] = value;
}
}
现在我们需要将 processing-1.3.6.js 添加到项目根目录,并将“Build Action”设置为“Embedded Resource”。接下来要做的是打开项目属性文件夹中的 AssemblyInfo.cs,并添加两个属性:
[assembly: WebResource("Processing4Net.processing-1.3.6.js", "text/javascript")]
[assembly: ScriptResource("Processing4Net.processing-1.3.6.js", "Processing4Net.Processing", "Processing4Net.Resource")]
这会将 JavaScript 文件定义为 Web 资源,允许 WebResource.axd HttpHandler 与 ClientScriptManager 类配合使用,动态输出嵌入式资源,使其可以通过客户端的 <script …> 标签访问。
现在,我们可以在控件的 pre-render 阶段将脚本注册到页面的 ClientScriptManager 中。
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
string resourceName = "Processing4Net.processing-1.3.6.js";
ClientScriptManager cs = this.Page.ClientScript;
cs.RegisterClientScriptResource(typeof(Processing4Net.Processing), resourceName);
}
所有剩下的就是将 canvas 添加到页面:
protected override void RenderChildren(HtmlTextWriter writer)
{
if (DesignMode == false)
{
string sources = Sources;
sources = this.Page.ResolveClientUrl(sources);
writer.Write("<canvas data-processing-sources=\"" +
sources + "\"></canvas>");
}
base.RenderChildren(writer);
}
以上就是实现 processing.js 的 ASP.NET 服务器控件所需的所有内容,现在我们可以使用 Processing 编程语言创建美丽、交互式的可视化。
processing.js 简介
项目源代码中包含一个小型 ASP.NET Web 应用程序,允许您创建无限数量或多或少赏心悦目的可视化效果。本文顶部的所有图像都是由该应用程序生成的,所以请尽情释放您内心的随机艺术家。
如果您试用一下,您会注意到可以通过在可视化表面上拖动鼠标来改变它——您也应该会注意到过渡是动画的。
首先,我们定义 setup() 函数。此函数在程序启动时调用一次。在这里,我们在 draw() 开始执行之前定义初始环境属性,如屏幕大小、背景颜色、加载图像等。每个 Processing 程序只能有一个 setup() 函数,并且在初始执行后不应再次调用它。
void setup()
{
size(600,600);
smooth();
frameRate(24);
initialize();
}
因此,此可视化的尺寸将是 600x600 像素,smooth() 告诉 Processing 使用抗锯齿绘图,而 frameRate(24) 指定每秒显示的帧数。如果处理器不够快,无法维持指定的速率,则无法实现。我们的 initialize() 函数看起来是这样的:
void initialize()
{
if (frequency.random)
{
fx = (int) random(frequency.x.min,frequency.x.max);
fy = (int) random(frequency.y.min,frequency.y.max);
phix = (int) random(frequency.phase_x.min,frequency.phase_x.max);
phiy = (int) random(frequency.phase_y.min,frequency.phase_y.max);
}
else
{
fx = (int) frequency.x.value;
fy = (int) frequency.y.value;
phix = (int) frequency.phase_x.value;
phiy = (int) frequency.phase_y.value;
}
if (modulation.random)
{
mfx = (int) random(modulation.x.min,modulation.x.max);
mfy = 0;
}
else
{
mfx = (int) modulation.x.value;
mfy = (int) modulation.y.value;
}
numberOfPoints = (int) random(200,1000);
span = random(numberOfPoints*0.4,numberOfPoints*0.9);
r = random(width/4,width/2);
b = (int)random(60);
factor = width*(random(0.25,0.375));
points = new PVector[numberOfPoints];
for (int p = 0; p <= numberOfPoints; p++)
{
PVector l = calculateLissajousPoint(p);
points[p] = new AnimatedPoint(l.x,l.y,l.z);
}
backgroundColor = color(0,0,0);
lissajousColor = color(random(100,255),random(100,255),random(100,255));
noFill();
}
initialize() 设置将在稍后由我们的 draw 函数使用的全局变量。
void draw()
{
// update animation
for (int i=0; i<=numberOfPoints; i++)
{
points[i].animate();
}
background(backgroundColor);
stroke(lissajousColor);
strokeWeight(1);
beginShape();
for (int i=0; i<=numberOfPoints; i++)
{
float d = PVector.dist(points[i].position, new PVector(width/2.0,height/2.0));
float a = pow(1/(d/r+1), 3);
stroke(lissajousColor,a*255);
vertex(points[i].position.x, points[i].position.y);
}
endShape();
for (int i = 0; i < span; i++)
{
int i1 = (int) i;
int i2 = (int)((i1+span)%numberOfPoints);
int c1 = (int) ((i1+b)%numberOfPoints);
int c2 = (int) ((i2+b)%numberOfPoints);
float d = PVector.dist(points[i1].position, points[i2].position);
float a = pow(1/(d/r+1), 3);
stroke(lissajousColor,a*255);
strokeWeight((i/span)*2);
bezier(points[i1].position.x, points[i1].position.y,points[c1].position.x,
points[c1].position.y, points[i2].position.x, points[i2].position.y,
points[c2].position.x, points[c2].position.y);
}
}
这个 Processing 脚本比通常的“hello world”程序更进一步,然后可视化效果可能更具趣味性。
历史
- 2012 年 6 月 4 日 - 初次发布。