您的位置:首页 > Web前端 > JavaScript

P5.js实现动态绘画

2019-05-26 16:06 931 查看

P5.js实现动态绘画

1.码绘简介

“码绘”及用代码作画,利用计算机程序实现动态和交互的绘画效果,可以获得与手绘截然不同的作品。

2.作品介绍

本文使用P5.js工具包,绘制了一幅动态的“雪梅图”,为了使画面更具有动感,我设计让梅花和雪动起来。利用P5的鼠标工具,还可以实现一个小小的交互效果——任意点击位置即可“盛开”一朵花。
由于转换成动图太影响画质,这里只放静态图,可以在https://editor.p5js.org/chestnut/sketches/PMgqP26Br 运行查看动态效果。

3.关键代码

(1)背景

首先画出背景——蓝天和草地,给蓝天和草地都做了渐变效果。

//天空
function sky(){
var c1 = color(90,150,205);
var c2 = color(190,200,220);
noStroke();
setGradient(0, 0, 800, 600,c1,c2,1);
}
function setGradient(x, y, w, h, c1, c2,axis) {
noFill();
if (axis == 1) {
for (var i = y; i <= y+h; i++) {
var inter = map(i, y, y+h, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x+w, i);
}
}
else if (axis == 2) {
for (var k = x; k <= x+w; k++) {
var interk = map(k, x, x+w, 0, 1);
var ck = lerpColor(c1, c2, interk);
stroke(ck);
line(k, y, k, y+h);
}
}
}
//草地
function grass(){
push();
var c1 = color(0,255,0);
var c2 = color(0,150,0);
noStroke();
setGradient(0, 600, 800, 200,c1,c2,1);
}
function setGradient(x, y, w, h, c1, c2,axis){
noFill();
if (axis == 1) {
for (var i = y; i <= y+h; i++) {
var inter = map(i, y, y+h, 0, 1);
var c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x+w, i);
}
}
else if (axis == 2) {
for (var k = x; k <= x+w; k++) {
var interk = map(k, x, x+w, 0, 1);
var ck = lerpColor(c1, c2, interk);
stroke(ck);
line(k, y, k, y+h);
}
}
pop();
}

(2)飘雪效果

(3)动态花朵

//画花朵
function drawFlower(cx,cy,z){
push();
var a=second();
translate(cx, cy);
for (var i = 0; i < z; i++) {
//f = (i % 2 == 0)? color(238) :color(34);
if(i!==z-1)f=color(255);
if (i == z - 1) f = color(225, 76, 69);
v=(300 - (295 / z * i))*0.08*sin(0.1*a)
flower(v, f, i);
}
theta += TWO_PI / frms;
pop();
}
//花朵形状
function flower(diam, col, n) {
push();
fill(col);
beginShape();
var d = 0;
for (var i = 0; i < 800; i++) {
var angle = TWO_PI / num * i;
var s = 0.5 + 0.5 * map(sin(theta + angle * 4.0), -1, 1, -1, 1);
d = 0.25 + 0.4 * pow(s, 0.3);
d += 0.05 * pow(0.5 + 0.5 + cos(8 * angle), 1.0);
var x = cos(angle) * d * diam;
var y = sin(angle) * d * diam;
vertex(x, y);
}
endShape(CLOSE);
pop();
}

(4)树干

//树枝
function tree(){
//var rx = 800;
//var ry = 700;
push();
stroke(190,70,20);
//树干
strokeWeight(30);
line(rx,ry,rx+8,ry-20);
line(rx+8,ry-20,rx+8,ry-50);
line(rx+8,ry-50,rx-15,ry-150);
//左
strokeWeight(18);
line(rx-15,ry-140,rx-50,ry-130);
line(rx-50,ry-130,rx-90,ry-135);
line(rx-90,ry-135,rx-170,ry-220);
strokeWeight(12);
line(rx-120,ry-150,rx-160,ry-120);
line(rx-170,ry-220,rx-150,ry-260);
line(rx-170,ry-220,rx-200,ry-240);
//中
strokeWeight(20);
line(rx-15,ry-160,rx-40,ry-170);
line(rx-40,ry-170,rx-90,ry-280);
strokeWeight(18);
line(rx-90,ry-280,rx-120,ry-310);
strokeWeight(15);
line(rx-90,ry-280,rx-40,ry-340);
line(rx-120,ry-310,rx-170,ry-330);
strokeWeight(10);
line(rx-60,ry-320,rx-60,ry-360);
//右
strokeWeight(15);
line(rx-10,ry-90,rx+15,ry-170);
line(rx+15,ry-170,rx+10,ry-220);
line(rx+10,ry-220,rx+12,ry-280);
strokeWeight(12);
line(rx+12,ry-280,rx+22,ry-315);
strokeWeight(10);
line(rx+10,ry-220,rx+50,ry-250);
line(rx+12,ry-280,rx-2,ry-320);
pop();
}

(5)绘制

function setup() {
createCanvas(800, 800);
frameRate(10);
noStroke();
}
function draw(){

background(240);
back();
snow();
noStroke();
tree();

//左
drawFlower(rx-50,ry-130,3);
drawFlower(rx-130,ry-135,4);
drawFlower(rx-170,ry-220,5);
//中
drawFlower(rx-60,ry-240,3);
drawFlower(rx-90,ry-280,4);
drawFlower(rx-60,ry-320,5);
drawFlower(rx-170,ry-330,4);
//右
drawFlower(rx+15,ry-170,4);
drawFlower(rx+12,ry-280,6);
drawFlower(rx+50,ry-250,5);

if(mouseIsPressed)
{
x=mouseX;
y=mouseY;
}
drawFlower(x,y,4);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: