P5.js实现动态绘画

    xiaoxiao2025-02-01  60

    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); }
    最新回复(0)