因为大三互动媒体技术课程需要使用p5.js画图显示动态效果,并和自己手绘作品进行对比,查了查网上好像没有做风车相关的教程,就在这里简单介绍下吧。
js编辑器(我用的是visual studio code2017)和p5.js库,具体下载和配置步骤这里就不讲了。不清楚的朋友可以参考下这篇博客: p5.js入门教程.
画个风车很简单,四个同样大小的半圆和一根竖线就行了。
新建一个p5.js工程,代码如下:
function setup() {
createCanvas(800, 800);
noStroke();
}
function draw(){
background(204);//设置背景 遮盖之前作图
fill(0);
rect(300,300,10,400);//一条竖线 颜色为黑色
fill(255,0,0);//红色
arc(400, 300, 200, 200, PI, TWO_PI);//半圆
fill(255,0,0);
arc(200, 300, 200, 200, 0, PI);//半圆
fill(255,0,0);
arc(300, 200, 200, 200, 0.5*PI, 1.5*PI);//半圆
fill(255,0,0);
arc(300, 400, 200, 200, 1.5*PI, 0.5*PI);//半圆
}
创建一个.html文件,将之前创建的js文件和p5.js链接到此html文件中,例如:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.js">script>
<script src="4.js">script>
head>
<body>
body>
html>
我刚开始做的时候直接使用PI进行运算,结果报错说我没有定义PI。后来查过之后才知道使用之前要加上“Math.”
为了以防万一,后面的所有三角函数之前我也把“Math.”补上了,最后成功实现动态效果。下面看代码:
//初始化
var x1=400;
var y1=300;
var x2=200;
var y2=300;
var x3=300;
var y3=200;
var x4=300;
var y4=400;
var w=Math.PI/6;
var w1=Math.PI;
var w2=2*Math.PI;
var w3=0;
var w4=Math.PI;
var w5=1.5*Math.PI;
var w6=0.5*Math.PI;
var w7=0.5*Math.PI;
var w8=1.5*Math.PI;
//旋转角度
var w0=0;
function setup() {
createCanvas(800, 800);
frameRate(20);//设置每秒20帧
noStroke();
}
function draw(){
//200<=x<=400
//200<=y<=400
background(220);//设置背景 遮盖之前作图
fill(0);
rect(300,300,10,400);
fill(255,0,0);
arc(x1, y1, 200, 200, w1, w2);
fill(255,0,0);
arc(x2, y2, 200, 200, w3, w4);
fill(255,0,0);
arc(x3, y3, 200, 200, w5, w6);
fill(255,0,0);
arc(x4, y4, 200, 200, w7, w8);
w0=w0+w;
w1=Math.PI+w0;
w2=2*Math.PI+w0;
w3=w0;
w4=Math.PI+w0;
w5=1.5*Math.PI+w0;
w6=0.5*Math.PI+w0;
w7=0.5*Math.PI+w0;
w8=1.5*Math.PI+w0;
// (x1-300)^2+(y1-300)^2=100^2;
x1=300+100*Math.cos(w0);
x2=300+100*Math.cos(w0+Math.PI);
x3=300+100*Math.cos(w0+0.5*Math.PI);
x4=300+100*Math.cos(w0+1.5*Math.PI);
y1=300+100*Math.sin(w0);
y2=300+100*Math.sin(w0+Math.PI);
y3=300+100*Math.sin(w0+0.5*Math.PI);
y4=300+100*Math.sin(w0+1.5*Math.PI);
}
效果如下:
上面代码成功让风车动起来了,但画面上只有一个风车显得太单调,给它加点雪花背景吧,p5.js官网例子中就有现成的代码,这里我直接改一改拿来用了。
//初始化
var x1=400;
var y1=300;
var x2=200;
var y2=300;
var x3=300;
var y3=200;
var x4=300;
var y4=400;
var w=Math.PI/6;
var w1=Math.PI;
var w2=2*Math.PI;
var w3=0;
var w4=Math.PI;
var w5=1.5*Math.PI;
var w6=0.5*Math.PI;
var w7=0.5*Math.PI;
var w8=1.5*Math.PI;
let snowflakes = []; // array to hold snowflake objects
//旋转角度
var w0=0;
function setup() {
createCanvas(800, 800);
frameRate(20);//设置每秒20帧
noStroke();
}
function draw(){
//200<=x<=400
//200<=y<=400
background(240);//设置背景 遮盖之前作图
fill(0);
rect(295,300,10,400);//画竖直黑线
fill(255,0,0);
arc(x1, y1, 200, 200, w1, w2);//半圆
fill(255,0,0);
arc(x2, y2, 200, 200, w3, w4);
fill(255,0,0);
arc(x3, y3, 200, 200, w5, w6);
fill(255,0,0);
arc(x4, y4, 200, 200, w7, w8);
fill(255);
ellipse(300,300,5,5);//风车中间的白色小圆
w0=w0+w;
w1=Math.PI+w0;
w2=2*Math.PI+w0;
w3=w0;
w4=Math.PI+w0;
w5=1.5*Math.PI+w0;
w6=0.5*Math.PI+w0;
w7=0.5*Math.PI+w0;
w8=1.5*Math.PI+w0;
// (x1-300)^2+(y1-300)^2=100^2;
x1=300+100*Math.cos(w0);
x2=300+100*Math.cos(w0+Math.PI);
x3=300+100*Math.cos(w0+0.5*Math.PI);
x4=300+100*Math.cos(w0+1.5*Math.PI);
y1=300+100*Math.sin(w0);
y2=300+100*Math.sin(w0+Math.PI);
y3=300+100*Math.sin(w0+0.5*Math.PI);
y4=300+100*Math.sin(w0+1.5*Math.PI);
//雪花
let t = frameCount / 60; // update time
// create a random number of snowflakes each frame
for (var i = 0; i < random(5); i++) {
snowflakes.push(new snowflake()); // append snowflake object
}
// loop through snowflakes with a for..of loop
for (let flake of snowflakes) {
flake.update(t); // update snowflake position
flake.display(); // draw snowflake
}
}
// snowflake class
function snowflake() {
// initialize coordinates
this.posX = 0;
this.posY = random(-50, 0);
this.initialangle = random(0, 2 * PI);
this.size = random(2, 5);
// radius of snowflake spiral
// chosen so the snowflakes are uniformly spread out in area
this.radius = sqrt(random(pow(width / 2, 2)));
this.update = function(time) {
// x position follows a circle
let w = 0.6; // angular speed
let angle = w * time + this.initialangle;
this.posX = width / 2 + this.radius * sin(angle);
// different size snowflakes fall at slightly different y speeds
this.posY += pow(this.size, 0.5);
// delete snowflake if past end of screen
if (this.posY > height) {
let index = snowflakes.indexOf(this);
snowflakes.splice(index, 1);
}
};
this.display = function() {
ellipse(this.posX, this.posY, this.size);
};
}
效果如下:
这样是不是就漂亮多了!
用p5.js画图并不难,还有更多画图函数和例子可以在p5.js官网查看,看完这篇博客赶快自己动手试试吧!