用p5.js 进行“运动”主题创作
第四维即时间(根据爱因斯坦相对论),在时间上的重复,在传统静态绘画中是不可能实现的,但用编程就可以做到。
在各种自媒体平台上,我们会看到很多会“动”的海报、设计图,这比静态的图画有时候会显得更吸引人。动态现在被看作一种全新的“媒介”,它可以用于表现以往的静态构成方式所无法表达的美感。
用p5.js做出的成品
我将之前做的静态码绘加了几行代码,也变成了动态,小熊从“摘星星”,变成了看流星,感觉变得更有趣了:
像是这幅动态码绘,如果我想表现出他的“运动”,就会在星星的下方画出几条长短不一的线,来表达“流星”的概念,这也是漫画等常常用到的手段。
function setup() {
// put setup code here
createCanvas(600, 800);
//画布的坐标系统为,左上角(0,0)
//x方向水平向右,y垂直向下
}
function draw() {
// put drawing code here
background(255, 255, 255);
bg();
textl();
bear();
love();
fill(255,248,220);
push();
translate(60, 10);
rotate(frameCount / -100.0);
star(300, 200, 3, 7, 5);
star(100, 500, 3, 7, 5);
star(200, 100, 3, 7, 5);
star(290, 130, 3, 7, 5);
pop();
}
function bg()
{
noStroke();
fill(208, 100, 113);
quad(70, 20, 430, 20, 430, 480, 70, 480);
fill(43, 77, 122);
quad(100, 50, 400, 50, 400, 450, 100, 450);
fill(255, 255, 255);
ellipse(160, 340, 9 , 9);
//ellipse(290, 90, 8 , 8);
ellipse(350, 400, 5 , 5);
ellipse(350, 230, 5 , 5);
ellipse(150, 220, 5 , 5);
fill(255, 255, 255);
textSize(30);
textStyle(BOLD);
text('MORE', 120, 62);
fill(255, 255, 255);
textSize(15);
textStyle(NORMAL);
text('more bright', 330, 442);
}
function textl()
{
fill(0,0,0);
var d = day();
var m=month();
textSize(10);
textStyle(NORMAL);
text('Today: ' +m+'.'+d, 80,460);
}
function bear(){
//stroke(0,0,0);
//strokeWeight(4);
fill(20, 20, 20);
ellipse(240, 182, 30, 30);
ellipse(273, 180, 30, 30);//ears
ellipse(258, 192, 47, 45);//face
ellipse(258, 230, 49, 70);//body
//ellipse(250, 260, 28, 50);//feet
ellipse(268, 260, 27, 50);
ellipse(245, 220, 46, 35);//hands
push();//左脚旋转
translate(157, -93);
rotate(-100);
ellipse(250, 260, 28, 50);//feet
pop();
push();//右手旋转
translate(-70, 170);
rotate(100);
ellipse(275, 220, 46, 28);
pop();
fill(238, 223, 204);
ellipse(240, 182, 20, 20);
ellipse(273, 180, 20, 20);//ears
ellipse(258, 192, 37, 35);//face
ellipse(258, 230, 39, 60);//body
ellipse(268, 260, 17, 40);
push();
translate(157, -93);
rotate(-100);
ellipse(250, 260, 18, 40);//feet
pop();
ellipse(245, 220, 33, 20);//hands
push();
translate(-70, 170);
rotate(100);
ellipse(275, 220, 35, 20);
pop();
}
function love(){
//fill(255,255,255);
ellipse(245, 305, 50, 50);
ellipse(285, 305,50, 50);
// triangle(235,322,314,323,275,365);
//ellipse(265, 305, 20, 20);
fill(208, 100, 113);
ellipse(245, 305, 40, 40);
ellipse(285, 305, 40, 40);
triangle(225,312,304,313,265,355);
ellipse(265, 305, 15, 15);
}
function star(x, y, radius1, radius2, npoints) {
var angle = TWO_PI / npoints;
var halfAngle = angle/2.0;
beginShape();
for (var a = 0; a < TWO_PI; a += angle) {
var sx = x + cos(a) * radius2;
var sy = y + sin(a) * radius2;
vertex(sx, sy);
sx = x + cos(a+halfAngle) * radius1;
sy = y + sin(a+halfAngle) * radius1;
vertex(sx, sy);
}
endShape(CLOSE);
}
这是我借鉴、模仿了意大利设计师Marco Oggian的一幅码绘,也是我第二次试验所做的内容:
鼠标点击时眼泪会落下;
随意敲击鼠标可以使“love more”转换成“hate less;
左半部分的圆点和文字根据代码自动漂浮在左侧区域。
第二个版本加了随机生成的画线,感觉很有意思,因为random本来就自带一种美感,颜色也会从白线逐渐变成黑线。加这个函数的原因是因为我感觉手绘没有办法在随机过程中连续画一条渐变的曲线,很奇妙,很有意思。具体的函数是在这里:
function setup() {
// put setup code here
createCanvas(400, 600);
for ( var i = 0; i < num; i++ ) {
ax[i] = width / 2;
ay[i] = height / 2;
}
frameRate(30);
//画布的坐标系统为,左上角(0,0)
//x方向水平向右,y垂直向下
// stroke(0);
a = 300 / 2;
b = 120;
}
function draw() {
// put drawing code here
background(255, 255, 255);
for ( var i = 1; i < num; i++ ) {
ax[i - 1] = ax[i];
ay[i - 1] = ay[i];
}
// Put a new value at the end of the array
ax[num - 1] += random(-range, range);
ay[num - 1] += random(-range, range);
// Constrain all points to the screen
ax[num - 1] = constrain(ax[num - 1], 0, 200);
ay[num - 1] = constrain(ay[num - 1], 0, 300);
// Draw a line connecting the points
for ( var j = 1; j < num; j++ ) {
var val = j / num * 204.0 + 51;
stroke(val);
line(ax[j - 1], ay[j - 1], ax[j], ay[j]);
}
bg();
fill(0, 0, 0);
keyboard();
textl();
eyes();
cry();
}
在我计算做左侧圆点的漂浮运动时,其实我也并没有精确计算圆点会落在哪里,用一个for循环让它们来回重复的漂浮,使用-号它们会向上,+会向下,也是很有意思的。这是我用手绘很难体现出的“动态”。
做背景的时候,需要计算一下三角形、眼睛等部位的具体位置,其实并不难。几何图形的绘画总体来说还是简单易做的。但是在我手绘的时候,就只需要随手估计一下大概位置就好了。
交互是“运动”主题海报我觉得和手绘的作品差异最大的地方了吧,当然我自己做的还不够完善,但是如果涉及一个动态海报,用户可以根据自己的不同操作获得不同样式、形状的独一无二的艺术品,这会大大提高用户的使用感,用户和作品互动,拉近了二者之间的距离,我认为这比欣赏一幅远远地挂着的静态艺术品更加有意思,但是也有可能一定程度上改变原作者对作品的诠释和理解。
对于手绘来说,是相比之下更为感性的、随意的(但是像我的这幅动态手绘,是很难体现出“运动”的)。当我画自己编程做出来的码绘的时候,因为图案不是特别复杂,一会儿就画好了,但是背景的颜色如果要全部涂满,就占用我的一些时间,而且因为力度不好掌握,涂出来也会斑驳、不均匀,这是码绘绝不需要担心的问题。手绘可以更生动的表现作者的感情,也许会出错,但这也恰恰是人性的可爱之处,让作品更加有趣,比如说我这张图画了“着火的车”:
尽管我所能表达的只是静态的图像,可因为常识,和我在周围加的一些阴影、曲线、圆圈,被人们看到就会默认它为“飘动”的火焰,这就是手绘可以表达的“形态”,在这幅手绘周围我也画了很多出错的线条,但是留着它们,却可以让这幅画看起来更加生动。
如果要表达自己强烈的艺术情感,手绘当然是首选,我可以用画笔画出各种各样不规则,夸张的形状而不用理性的推导公式和算法,让感情不间断的通过画笔流露在画纸上;而如果我要做出一个精密、完美的物品来,则更需要理性的推导,此时的码绘则更胜一筹。光码绘的例子系统,就可以变幻出无数个奇妙又有趣的场景。
我们可以在许多场景看到不同的手绘:比如说我之前去过西交利物浦的地下通道,都是社团成员们精心画出的各种动漫、手绘,我们学校南门附近的集装箱,、甚至水面、沙滩即兴作画都可以,但是码绘基于电子数码产品,对场景的要求也比较严苛,呈现方式比较单一。
Marco的作品风格都比较抽象有趣,设计配色大胆,类似的作品我还找了其他两张图:
“重复本身就是一项高级的绘画手法,只要运用得当,可以制造出极大的丰富性、特殊的风格、引人入胜的趣味感 ”。
重复与美:
https://blog.csdn.net/magicbrushlv/article/details/77917540
类似于这样的动图还有很多,应该就是短短几帧,但却有很有生活的氛围,配色清新,让人有耳目一新的感觉。
这是我经过自己理解,以及借鉴学习官网https://p5js.org上的实例后所写的代码
.
var a;
var b;
function setup() {
// put setup code here
createCanvas(400, 600);
//画布的坐标系统为,左上角(0,0)
//x方向水平向右,y垂直向下
stroke(0);
a = 300 / 2;
b = 120;
}
function draw() {//画出背景
// put drawing code here
background(255, 255, 255);
fill(165, 42, 42);
quad(200, 0, 400, 0, 400, 500, 200, 500);
fill(0, 0, 0);
quad(160, 0, 200, 0, 200, 500, 160, 500);
fill(165, 42, 42);
triangle(0, 500, 200, 500, 200, 300);
fill(0, 0, 0);
triangle(400, 500, 200, 500, 200, 300);
// fill(0, 0, 0);
// triangle(160,340, 0, 500, 0, a);
textSize(30);
textStyle(BOLD);
text('BUY ART', 5, a);
fill(165, 42, 42);
textSize(30);
textStyle(BOLD);
text('BUY ART', 5, 22+a);
fill(0,0,0);
textSize(30);
textStyle(BOLD);
text('BUY ART', 5, 44+a);
fill(165, 42, 42);
textSize(30);
textStyle(BOLD);
text('BUY ART', 5, 66+a);
fill(0,0,0);
textSize(30);
textStyle(BOLD);
text('BUY ART', 5, 88+a);
fill(165, 42, 42);
ellipse(b, b, b-130, b-130);
fill(0, 42, 42);
ellipse(a-20, a+100, a-200, a-200);
fill(0, 0, 42);
ellipse(a+20, a+10, 20, 20);
a = a - 1;
if (a < 0) {
a = 300;
}
b = b - 0.5;
if (b < 0) {
b = 260;
}
fill(0, 0, 0);
keyboard();
textl();
eyes();
cry();
}
function keyboard() {//随意键按下可变换文字
if (keyIsPressed == true) { // If the key is pressed,
textSize(42);
textStyle(ITALIC);
text('HATE LESS', 180, 530);
}
else { // Otherwise,
textSize(40);
textStyle(ITALIC);
text('LOVE MORE', 5, 530);
}
}
function textl()//显示今日日期
{
var d = day();
textSize(10);
textStyle(NORMAL);
text('Today: ' + d, 150, 450);
}
function eyes(){//右上角眼睛
noStroke();
fill(255, 255,255);
ellipse(295, 100, 150, 60);
fill(139, 35, 35);
ellipse(295, 100, 55, 55);
}
function tears(){//眼泪
noStroke();
fill(255, 255, 255);
triangle(275, 150, 325, 150, 300, 100);
fill(255, 255, 255);
arc(300, 150, 50, 50, 0, PI);
}
function cry(){//鼠标点击事件:眼泪下落
if (mouseIsPressed == true) {
noStroke();
cursor(HAND);
fill(255, 255, 255);
triangle(275, 350, 325, 350, 300, 300);
fill(255, 255, 255);
arc(300, 350, 50, 50, 0, PI);
}
else {
noStroke();
fill(255, 255, 255);
triangle(275, 150, 325, 150, 300, 100);
fill(255, 255, 255);
arc(300, 150, 50, 50, 0, PI);
cursor(CROSS); // Draw cursor as cross
}
}
学习网址:
[1]: https://p5js.org/zh-Hans/learn/interactivity.html
[2]:《以编程的思想来理解绘画—— (一)用”一笔画“表现“过程美”》
https://blog.csdn.net/magicbrushlv/article/details/82634189
[3]: 用代码画画——搞艺术的学编程有啥用?
https://blog.csdn.net/magicbrushlv/article/details/77922119