三個跳
why.pde
Bouncer[] bouncer = new Bouncer[3];
void setup() {
size(200,200);
frameRate(24);
stroke(#cce833);
fill(#43cee0);
bouncer[0] = new Ball(width/3-20,20,20);
bouncer[1] = new Box(width/2-10,20,20,20);
bouncer[2] = new Ball((2*width/3)+20,20,20);
}
void draw() {
for(int b=0, end=bouncer.length; b<end;b++) {
bouncer[b].computeNextStep(width, height, frameRate);
}
background(#f7c6ed);
for(int b=0, end=bouncer.length; b<end;b++) {
bouncer[b].draw();
}
}
void mousePressed() {
for(int b=0, end=bouncer.length; b<end;b++) {
if(bouncer[b].mouseOver(mouseX, mouseY)) {
bouncer[b].mousePressed();
}
}
}
void mouseReleased() {
for(int b=0, end=bouncer.length; b<end;b++) {
bouncer[b].mouseReleased();
}
}
void mouseDragged() {
for(int b=0, end=bouncer.length; b<end;b++) {
bouncer[b].mouseDragged(mouseX, mouseY);
}
}
abstract class Bouncer
{
int x, y;
boolean canmove = true;
int step = 0;
int xoffset = 0;
int yoffset = 0;
void computeNextStep(int width, int height, float framerate) {
if(canmove) {
reallyComputeNextStep(width, height, framerate);
}
}
abstract void reallyComputeNextStep(int width, int height, float framerate);
abstract void draw();
abstract boolean mouseOver(int mx, int my);
void mousePressed() {
canmove = false;
}
void mouseReleased() {
canmove = true;
x += xoffset;
y += yoffset;
xoffset = 0;
yoffset = 0;
}
void mouseDragged(int mx, int my) {
if(!canmove) {
xoffset = mx-x;
yoffset = my-y;
}
}
}
class Ball extends Bouncer
{
int radius;
Ball(int x, int y, int r) {
this.x = x;
this.y = y;
this.radius = r;
}
void reallyComputeNextStep(int sketch_width, int sketch_height, float frame_rate) {
step = (int)((step+1) % frame_rate);
float sin_value = abs(sin(PI*step/(float)frame_rate));
float bounce_height = sketch_height/2 * sin_value;
float ball_height = sketch_height - (bounce_height + radius);
y = (int) (ball_height);
}
void draw() { ellipse(x+xoffset,y+yoffset,radius,radius); }
boolean mouseOver(int mx, int my) {
return sqrt((x-mx)*(x-mx) + (y-my)*(y-my)) <= radius;
}
}
class Box extends Bouncer
{
int w,h;
int step=0;
Box(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
void reallyComputeNextStep(int sketch_width, int sketch_height, float frame_rate) {
step = (int)((step+1) % frame_rate);
float sin_value = abs(sin(PI/2.0 + (PI*step/(float)frame_rate)));
float bounce_height = sketch_height/2 * sin_value;
float ball_height = sketch_height - (bounce_height + h);
y = (int) (ball_height);
}
void draw() { rect(x+xoffset,(y-h/2)+yoffset,w,h); }
boolean mouseOver(int mx, int my) {
return x<=mx && mx<=x+w && (y-h/2)<=my && my<=(y+h/2);
}
}
th.html
<!DOCTYPE html>
<html>
<head>
<title>hello processing</title>
<meta charset="utf-8">
<style>
</style>
</head>
<body>
<script src="processing.js"></script>
<canvas data-processing-sources="why.pde"></canvas>
</body>
</html>
processing.js http://processingjs.org/download/ 下載
當然也可以內聯
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="utf-8">
5 <title>My Processing Page</title>
6 <script type="text/javascript" src="processing.js"></script>
7 </head>
8 <body>
9 <script type="application/processing" target="mysketch">
10 void setup() { ... }
11 void draw() { ... }
12 class SomeClass {
13 ...
14 }
15 </script>
16 <canvas id="mysketch"></canvas>
17 </body>
18 </html>
但這些並不是什麼好用的方法,因爲如果你的草圖有bug,甚至都不知道要怎麼改,因爲調試器不會指出你的草圖哪裏代碼有問題,只會說processing.js哪裏有問題。如果一定要用這種方法,可以現在processing IDE中調好了再拿過來。
讓你的草圖和頁面能互相“看見”
也就是上篇所說的混用。
先看看如何實現。
最關鍵的是“草圖函數”。
var mysketch = Processing.getInstanceById('mysketchid');
灰常關鍵的一步,有了它就可以直接訪問草圖。
1、讓javascript“看見”草圖
seeu.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Processing Page</title>
<script type="text/javascript" src="processing.js"></script>
<script type="text/javascript">
function drawSomeText(id) {
var pjs = Processing.getInstanceById(id);
var text = document.getElementById('inputtext').value;
pjs.drawText(text); }
</script>
</head>
<body>
<canvas id="mysketch" data-processing-sources="seeme.pde"></canvas>
<input type="textfield" value="see you" id="inputtext">
<button type="button" onclick="drawSomeText('mysketch')">place</button>
</body>
</html>
see me.pde
void setup() {
size(200,200);
noLoop(); // 關掉動畫,不需要!
stroke(#e439f2);
fill(#FFEE88);
background(#000033);
text("",0,0); // 強制processing加載一些字
textSize(24); // 字體大小
}
void draw() { }
void drawText(String t)
{
background(#000033);
// 獲取文本寬度
float twidth = textWidth(t);
// 文本居中
text(t, (width - twidth)/2, height/2);
}
processing.js …
圖有點小。。。但足以說明效果,網頁上我們添加的文本到了草圖上,說明js訪問P5成功了!
2、讓草圖“看見”javascript
最好的混用就是把所有要實現的功能都封裝到函數中。
seeuagain.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Processing Page</title>
<script type="text/javascript" src="processing.js"></script>
<script type="text/javascript">
var bound = false;
function bindJavascript() {
var pjs = Processing.getInstanceById('mysketch');
if(pjs!=null) {
pjs.bindJavascript(this);
bound = true; }
if(!bound) setTimeout(bindJavascript, 250);
}
bindJavascript();
function showXYCoordinates(x, y) {
document.getElementById('xcoord').value = x;
document.getElementById('ycoord').value = y;
}
</script>
</head>
<body>
<canvas id="mysketch" data-processing-sources="seemeagain.pde"></canvas>
<div id="coordinates">
x/y: <input type="textfield" id="xcoord">/<input type="textfield" id="ycoord">
</div>
</body>
</html>
seemeagain.pde
interface JavaScript {
void showXYCoordinates(int x, int y);
}
void bindJavascript(JavaScript js) {
javascript = js;
}
JavaScript javascript;
void setup() {
size(500,500);
stroke(255);
background(0);
noLoop();
}
void draw() {
fill(0,0,0,40);
rect(-1,-1,width+2,height+2);
}
void mouseMoved() {
line(mouseX,0,mouseX,height);
line(0,mouseY,width,mouseY);
redraw();
if(javascript!=null){
javascript.showXYCoordinates(mouseX, mouseY);
}
}
processing.js …
效果:
草圖訪問js的鼠標座標捕捉函數了,但是前提就是我們先要“告訴”它。