用p5.js实现一个小动画——故宫橘猫赏秋图

互动媒体第二次作业要求我们手绘一幅动画,再用代码实现出动画。由于时间原因,手绘并没有画动画,而是以插画的形式画了一张,然后p5实现了动画。
这里先放效果图:

板绘插图

码绘效果图


这里强烈建议直接运行代码!!!gif丢帧!!!可怜我的渐变啊啊啊啊!!!
下面附上完整代码:

var Width=600;
var Height=700;
var pixel=1;var Y_AXIS = 1;
var X_AXIS = 2;var skyHeight=190;
var wall_Width=600;
var wall_Height=300;
var wuyan_width=120;
var wuyan_height=20;
var quad_width=70;
var quad_height=30;
var center_x=500;
var center_y=115;
var cat_scale=111;var easing=1; var Time;//face_color=color(180,180,150,0.5*255);
function setup() {createCanvas(Width,Height); }function draw() { frameRate(5);drawwall();  drawsky();push();translate(10,-5);YinxingTree();pop();draw_wallshadow();if(center_x<-10)center_x=650;center_x-=15*easing;drawcat(cat_scale,center_x,center_y);translate(10,-25);noStroke();fill(30);rect(Width-10,0,200,Height);push();YinxingTree();pop();}function drawcat(cat_scale,center_x,center_y){stroke(200,200,240);noStroke();//肚子pos1_x=center_x-(cat_scale)/3;pos1_y=center_y+(cat_scale)*2/5-5;pos2_x=center_x+(cat_scale*1/3);pos2_y=center_y+(cat_scale)*2/5;//前体pos3_x=pos1_x-(cat_scale/5);pos3_y=center_y+(cat_scale)*2/5;pos4_x=pos1_x-(cat_scale/8);pos4_y=center_y+(cat_scale)/15;pos5_x=pos4_x-(cat_scale/8);pos5_y=pos4_y-(cat_scale)/20;//头pos6_x=pos5_x-(cat_scale/4);pos6_y=pos5_y-(cat_scale)/6;pos7_x=pos5_x-(cat_scale/6);pos7_y=pos5_y-(cat_scale)/30;pos8_x=pos5_x-(cat_scale)*3/8;pos8_y=pos5_y+(cat_scale)/8;pos9_x=pos8_x+(cat_scale)/5;pos9_y=pos8_y+(cat_scale)/5;//屁股pos10_x=pos2_x-(cat_scale/4)*0;pos10_y=pos2_y-(cat_scale)*1/3;pos11_x=pos10_x+(cat_scale*1/8);pos11_y=pos10_y+(cat_scale)/10;fill(220,200,180);triangle(center_x,center_y,pos1_x,pos1_y,pos2_x,pos2_y);triangle(center_x,center_y,pos1_x,pos1_y,pos3_x,pos3_y);fill(150,70,10);triangle(center_x,center_y,pos3_x,pos3_y,pos4_x,pos4_y);triangle(pos3_x,pos3_y,pos4_x,pos4_y,pos5_x,pos5_y);triangle(pos3_x,pos3_y,pos5_x,pos5_y,pos6_x,pos6_y);fill(150,70,10);triangle(pos3_x,pos3_y,pos7_x,pos7_y,pos8_x,pos8_y);fill(180,100,10);triangle(pos8_x,pos8_y,pos9_x,pos9_y,pos5_x,pos5_y);fill(150,70,10);triangle(center_x,center_y,pos2_x,pos2_y,pos10_x,pos10_y);triangle(pos2_x,pos2_y,pos10_x,pos10_y,pos11_x,pos11_y);fill(180);feetControl(pos1_x-6,pos1_y);feetControl(pos2_x-4,pos2_y);noFill();weiba(pos11_x,pos11_y);}function weiba(x,y){push();strokeWeight(10);stroke(150,70,10);x1=x-20;y1=y;x2=x+20;y2=y-20;x3=x+25;y3=y+5;x4=x+55;y4=y-20;bezier(x1,y1,x2,y2,x3,y3,x4,y4);noStroke();pop();}function feetControl(x,y){if(x%2==0){rect(x-(cat_scale)/10,y-8,(cat_scale)/10,(cat_scale)*1/3+8);    }else{quad(x,y-10,x-(cat_scale)/10,y-10,x-(cat_scale)/10+(cat_scale/10),y+(cat_scale)*1/3,x+(cat_scale/10),y+(cat_scale)*1/3);quad(x,y-15,x-(cat_scale)/10,y-15,x-(cat_scale)/10-(cat_scale/5),y+(cat_scale)*1/3,x-(cat_scale/5),y+(cat_scale)*1/3);}}function segment(trans_x, trans_y, a,segLength) {push();translate(trans_x, trans_y);rotate(a);rect();pop();}function draw_wallshadow(){noStroke();var c1=color(160,10,0);var c2=color(80,10,80);setGradient(0,600,Width,150,c1,c2,1);noStroke();fill(160,10,0);for(var i=0;i<Width;i++){arc(i,600,50,15,PI,0);i=i+80;}}function drawwall(){noStroke();fill(100,10,0);rect(0, 0, Width, Height);fill(190,70,20);rect(0, Height-wall_Height, wall_Width, wall_Height);drawWuYan1();   drawWuYan2(); drawWuYan3();drawWuYan4();}function drawWuYan1(){stroke(20);fill(190,100,10);for(var i=0;i<Width;i++){rect(i-5,wall_Height+70,wuyan_width,wuyan_height);i=i+wuyan_width;} }function drawWuYan2(){var cwu2_1=color(50,120,30);var cwu2_2=color(60,10,0);for(var j=0;j<Width+80;j++){setGradient(j-65,wall_Height+35,wuyan_width,wuyan_height+10,cwu2_1,cwu2_2,1);stroke(180,130,20);rect(j-65,wall_Height+36,wuyan_width,wuyan_height+10);j=j+wuyan_width;} var cwu3_1=color(10,20,10);var cwu3_2=color(80,100,20);fill(50,120,30);setGradient(0,wall_Height-15,Width,50,cwu3_1,cwu3_2,1);}function drawWuYan3(){noStroke();fill(190,150,90);for(var k=0;k<Width;k++){rect(k,skyHeight,wuyan_width,10);k=k+wuyan_width;}fill(190,100,10);rect(0,skyHeight+15,Width,12);fill(190,110,30);rect(0,skyHeight+35,Width,35);}function drawPIdwon(x_trans){stroke(90,50,50);push();translate(x_trans, skyHeight+100);rotate(0.0);fill(140,100,50);arc(0, 0, quad_width, quad_width-15, 0, PI);pop();}function drawPIdwon_shadow(x_trans,shadow){noStroke();push();translate(x_trans, skyHeight+100);rotate(0.0);fill(10,20,10);arc(0, 0, quad_width+shadow, quad_width+shadow, 0, PI);pop();}function drawquad(i,j,x_trans){var c1=color(90,50,50);var c2=color(180,90,50);setGradient(x_trans-(quad_width/2)+i, skyHeight+93-j,quad_width,5,c1,c2,2);}function drawCicle(x_trans,angle,c1,c2,c3,i)
{push();noStroke();fill(c1,c2,c3);translate(x_trans-i+7,skyHeight+70+i*3);rotate(angle);arc(0,0,50,50, 0, PI/2);pop();
}function drawCicle_all(x_trans)
{for(var i=0;i<8;i++){drawCicle(x_trans+quad_width-8,24.5,100,10,10,i);drawCicle(x_trans+quad_width-8,-2.2,130,110,90,i);drawCicle(x_trans+quad_width-8,1,70,20,10,i);drawCicle(x_trans+quad_width-8,-3.5,200,160,80,i);}stroke(50,10,10);fill(140,100,50);ellipse(x_trans+60,skyHeight+95,50,50);fill(80,60,20);ellipse(x_trans+60,skyHeight+95,35,35);
}function drawWuYan4()
{for(var x_trans=50;x_trans<Width;x_trans++){drawPIdwon_shadow(x_trans+10,10);drawPIdwon(x_trans);for(var i=0;i<5;i++){yp=i*5;drawquad(i,yp,x_trans);}drawCicle_all(x_trans);x_trans=x_trans+120;}}function YinxingTree()
{push();drawtree(220,180,0,-20,20,random(0.6));drawtree(120,60,0,-100,100,random(0.01));drawtree(120,60,0,-50,160,random(0.01));drawtree(180,160,0,40,160,random(0.05));drawtree(200,100,0,-20,100,random(1));drawtree(200,160,0,0,120,random(0.5));drawtree(220,160,0,55,160,random(0.1));drawtree(240,200,0,50,100,random(0.3));drawtree(240,200,0,50,180,random(0.3));drawtree(240,200,0,80,190,random(1));drawtree(220,180,0,-50,80,random(0.1));translate(150,90);drawtree(220,180,0,-50,150,random(0.5));translate(-100,-150);drawtree(240,200,120,-100,100,random(0.01));pop();
}function drawtree(c1,c2,c3,pos_x,pos_y,pos_angle)
{push();rotate(pos_angle);var trans_x;var trans_y;var trans_angle;fill(c1,c2,c3);for(var i=0;i<20;i++){trans_x=random(50);trans_y=random(20);trans_angle=random(-0.5);push();translate(trans_x,trans_y);rotate(trans_angle);drawYinXing(pos_x,pos_y);pop();}pop();}function drawYinXing(pos_x,pos_y){stroke(200,150,60);push();translate(pos_x, pos_y);rotate(0.0);arc(0, 0, 30, 30, 0, PI/2);pop();}function drawsky(){var c1 = color(90,150,205);var c2 = color(190,200,220);noStroke();setGradient(0, 0, Width, skyHeight,c1,c2,1);}function setGradient(x, y, w, h, c1, c2,axis) {noFill();if (axis == Y_AXIS) {  // Top to bottom gradientfor (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 == X_AXIS) {  // Left to right gradientfor (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);}}}
代码结构解析

1.背景:
其实画背景还挺简单的,基本物体就是红墙,屋檐,银杏树,天空。
天空是渐变的,用了一个函数,p5官网里面也有:

function drawsky(){var c1 = color(90,150,205);var c2 = color(190,200,220);noStroke();setGradient(0, 0, Width, skyHeight,c1,c2,1);}function setGradient(x, y, w, h, c1, c2,axis) {noFill();if (axis == Y_AXIS) {  // Top to bottom gradientfor (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 == X_AXIS) {  // Left to right gradientfor (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 drawCicle(x_trans,angle,c1,c2,c3,i)
{push();noStroke();fill(c1,c2,c3);translate(x_trans-i+7,skyHeight+70+i*3);rotate(angle);arc(0,0,50,50, 0, PI/2);pop();
}function drawCicle_all(x_trans)
{for(var i=0;i<8;i++){drawCicle(x_trans+quad_width-8,24.5,100,10,10,i);drawCicle(x_trans+quad_width-8,-2.2,130,110,90,i);drawCicle(x_trans+quad_width-8,1,70,20,10,i);drawCicle(x_trans+quad_width-8,-3.5,200,160,80,i);}stroke(50,10,10);fill(140,100,50);ellipse(x_trans+60,skyHeight+95,50,50);fill(80,60,20);ellipse(x_trans+60,skyHeight+95,35,35);
}

还有瓦片上的阴影,也用了渐变过渡,这里就不贴代码了。

银杏树
一开始对银杏树没什么头绪,观察了好几棵学校里的银杏,在大风刮过之时,金黄树叶在风中颤抖摇晃,我突然有了灵感——色块堆积。我可以不用准准确确的画出这棵树长啥样,我只需要保证它在运动中是符合这棵树的逻辑的,那么这棵树就是成功的。
下面贴上代码:

function YinxingTree()
{push();drawtree(220,180,0,-20,20,random(0.6));drawtree(120,60,0,-100,100,random(0.01));drawtree(120,60,0,-50,160,random(0.01));drawtree(180,160,0,40,160,random(0.05));drawtree(200,100,0,-20,100,random(1));drawtree(200,160,0,0,120,random(0.5));drawtree(220,160,0,55,160,random(0.1));drawtree(240,200,0,50,100,random(0.3));drawtree(240,200,0,50,180,random(0.3));drawtree(240,200,0,80,190,random(1));drawtree(220,180,0,-50,80,random(0.1));translate(150,90);drawtree(220,180,0,-50,150,random(0.5));translate(-100,-150);drawtree(240,200,120,-100,100,random(0.01));pop();
}function drawtree(c1,c2,c3,pos_x,pos_y,pos_angle)
{push();rotate(pos_angle);var trans_x;var trans_y;var trans_angle;fill(c1,c2,c3);for(var i=0;i<20;i++){trans_x=random(50);trans_y=random(20);trans_angle=random(-0.5);push();translate(trans_x,trans_y);rotate(trans_angle);drawYinXing(pos_x,pos_y);pop();}pop();}function drawYinXing(pos_x,pos_y){stroke(200,150,60);push();translate(pos_x, pos_y);rotate(0.0);arc(0, 0, 30, 30, 0, PI/2);pop();}

大量使用radom可以让这棵树更自然。

2.动画主角——猫
这里我先对猫进行了一些处理——低多边形处理。
吸取了第一个实验的教训,这次我先设置了一个中心点,然后在根据这个点扩充出有关猫的肢干总共12个点,然后画三角形,形成一个没有四肢,没有尾巴的橘猫。

尾巴用了贝塞尔曲线,坐标也跟中心点关联。
猫的四肢是运动视觉的关键!!!动画之所以能动是因为有承上启下的连续性动作。猫行走从侧面看过去就是两腿相互交叉变换。所以在写动画逻辑之前你需要先画出关键帧状态。
关键帧状态确定了就可开始着手动画逻辑:首先视觉上我们先要营造出猫在原地踏步的感觉。我们有两个关键帧状态,所以可以运用模运算,在运动的中心坐标基础上模2,结果对应两个状态。
附上代码:

function feetControl(x,y){if(x%2==0){rect(x-(cat_scale)/10,y-8,(cat_scale)/10,(cat_scale)*1/3+8);    }else{quad(x,y-10,x-(cat_scale)/10,y-10,x-(cat_scale)/10+(cat_scale/10),y+(cat_scale)*1/3,x+(cat_scale/10),y+(cat_scale)*1/3);quad(x,y-15,x-(cat_scale)/10,y-15,x-(cat_scale)/10-(cat_scale/5),y+(cat_scale)*1/3,x-(cat_scale/5),y+(cat_scale)*1/3);}}

至此,动画完成。

手绘与码绘的对比

在动画这个应用上,其实两者各有千秋。手绘能做到画面更加精致有更多细节,更能体现质感,但同时,它又太过费时。而码绘在运动这一方面有着得天独厚的优势,它能更平滑的完成动画操作。

发现的问题

码绘在建立场景的过程中,发现对于环境色这一概念,几乎还是一个空白领域。

用p5.js实现一个小动画——故宫橘猫赏秋图相关推荐

  1. 用P5.js绘制一个看着鼠标的章鱼哥

    用P5.js绘制一个看着鼠标的章鱼哥 用P5.js绘制一个看着鼠标的章鱼哥. 章鱼哥组成 头为椭圆 脸为方块 嘴为用椭圆遮住大半部分的圆,再由圆装饰 眼为椭圆 眼珠为方块 皱纹为半椭圆 代码 func ...

  2. 用P5 JS绘制二维动画场景——静态篇

    绘画 根据wiki百科的定义,绘画是在技术层面上,是一个以表面作为支撑面,再在其之上加上颜色的行为,那些表面可以是纸张.油画布.木材.玻璃.漆器或混凝土等,加颜色的工具可以是画笔.也可以是刀.海绵或是 ...

  3. 用three.js写一个小场景

    上次我们用three.js写了一个下雨的动画,主要是用粒子.这次是用three.js搭建了一个小场景. 项目地址依然是:https://github.com/alasolala/threejs-tut ...

  4. 使用p5.js绘制一个“禁止通行”标志

    效果图没有上传成功: CSDN对GoogleChrome的支持还不完善啊.发现了几个bug: 1. 添加个人分类标签时不能输入超过一个字符的标签 2. 不能通过复制粘贴方式上传图片(2019-01-2 ...

  5. html js 做的小游戏,用js做一个小游戏平台 (一)

    记得上班写代码时,我们技术总监总说是要先"设计",那就先"设计"吧. ps:我是新手大家多多见谅. .网页游戏区域.就是说需要知道游戏在网页上的区域,如下: 在 ...

  6. python Turtle做一个小动画

    详细代码功能在注解里面 import turtle #导入库 t = turtle.Pen() #创建一个Pen画笔 for i in range(0,4): #第一种方法画画 使用fort.forw ...

  7. 用html语言编写彩虹雨流动代码,HTML5 P5.js 彩虹雨 | 下雨动画

    JavaScript 语言: JaveScriptBabelCoffeeScript 确定 var raindrops = []; var numOfDrops; function setup() { ...

  8. p5.js实现细胞免疫动画

    文章目录 前言 准备工作 vscode初始化p5项目 本地运行项目 免疫过程 1 细胞结构 2 病毒出现 3 信号细胞运动 4 出现免疫细胞 5 病毒被消灭 总结 前言 前段时间写了个小demo,要求 ...

  9. p5.js 光速入门中文教程

    本文简介 点赞 + 关注 + 收藏 = 学会了 本文的目标是和各位工友一起有序的快速上手 p5.js ,会讲解 p5.js 的基础用法. 本文会涉及到的内容包括: 项目搭建 p5.js 基础2D图形 ...

最新文章

  1. $m$ 整除 $10^k$ 的一个充分条件
  2. maven可选依赖(Optional Dependencies)和依赖排除(Dependency Exclusions)
  3. 8.动态规划(1)——字符串的编辑距离
  4. 如何在React中使用功能组件
  5. BZOJ 2286 消耗战 (虚树+树形DP)
  6. Tkinter教程之Frame篇
  7. Coursera视频无法播放问题解决
  8. Matlab求解线性方程组Ax=b
  9. vc模拟 tabletpc_业力和TabletPC笔
  10. 浪潮服务器u盘安装系统_浪潮服务器系统安装怎样从光驱引导
  11. The inferior stopped because it received a signal from the Operating system signal name: SIGSEGV
  12. 李宏毅机器学习 Regression
  13. 【转】perl中$#ARGV是什么意思
  14. 速卖通流量新赛道,AE Mall商家享有权益和招商标准,看这篇文章就好了
  15. Android StatusBar 更改
  16. tuxedo错误码6_TUXEDO错误解析
  17. 《奇点来临》——Linked-In上“奇点临近”论坛的观点
  18. CSS3自定义滚动条样式 -webkit-scrollbar
  19. Alfred实现搜索印象笔记功能
  20. phpaaCMS V0.3 存在注射oday漏洞

热门文章

  1. 暑假学习计划回顾总结二
  2. 【HUAWEIH3C】对比华为和华三的IPSec配置
  3. DC-DC开关电源电感选型指南
  4. DFS递归之迷宫问题
  5. 评测3款高颜值的安卓mobi阅读器
  6. win7 蓝屏 0x000000c5
  7. 支撑5亿用户、1.5亿活跃用户的Twitter最新架构详解及相关实现
  8. 【oracle分区:分区表/分区索引查看,在线重建分区索引】
  9. 第16届智能车竞赛双车接力组—直立车经验语录
  10. 图式理论(Schema Theory)