P5.js创意自画像编程

  • 要求
  • 自画像创作
  • 坐标的计算
  • 颜色填充
  • 动态背景与交互功能的添加
    • 背景动态图
    • 添加声音与图片
    • 时间停止效果
  • 最终代码

要求

主题:用编程方式创作一幅介绍自己的作品

作品: 一件编程创意作品,必须实现动态效果或交互效果;作品录制一段一分钟内的视频;作品可以是具象化地描绘自己的形象,也可以是任何形式表现自己的兴趣、追求、特色、经历等;

自画像创作

想了好久自己的自画像是什么样子,最后决定画一个JOJO的奇妙冒险里的迪奥。不是因为自己长得像,大概是我也不想做人了吧。因为是要码绘,所以过于复杂的图案代码敲起来太浪费时间,就设计了一个Q版的造型。最终图如下:

最终成果图:

坐标的计算

由于dio爷那飘逸的发型,图像中大部分需要运用曲线。查了查p5的参考https://p5js.org/zh-Hans/reference,p5中的曲线用的是贝塞尔曲线算法。

那么问题就出现了,如何才能准确的找到自己在纸上画的图案的控制点与锚点坐标呢?
看到贝塞尔曲线,突然想到之前做过的图形学作业,制作一个简单的画图系统。其中的曲线就用到了贝塞尔曲线算法,可以通过移动鼠标在屏幕获取鼠标坐标,就能看到锚点与控制点坐标了。于是就翻了翻之前的作业,虽然简陋了点,但刚好能解决这个问题。不管白猫黑猫,逮到耗子就是好猫。剩下的只是繁重的坐标的记录。

颜色填充

用bezier曲线画好图形后,用fill()函数填充。发现并不能达到我们想要的效果。

虽然已经形成封闭的形状,但fill()函数并没有完美的填充,大概是顶点的遍历问题。解救办法是改用bezierVertex()函数。

动态背景与交互功能的添加

背景动态图

因为人物来自动漫,并且是dio爷标志性”扣no迪奥哒“动作,所以背景希望添加上漫画的网线效果。具体代码参考了网上的生成光芒线的代码https://wow.techbrood.com/fiddle/32556

var angle = 0;
var offset = 30;
var offset2 = 20000;
var scalar = 90;
var speed = 1;function setup() {createCanvas(500, 500);background(200);stroke(255, 0, 0)strokeWeight(.1);
}function draw() {var y1 = offset + sin(angle) * scalar;var y2 = offset2 + sin(angle + 0.4) * scalar;for (var i = 0; i < 1; i++) {translate(width / 2, height / 2)rotate(angle)push()y1 = offset + sin(angle) * scalar;rotate(angle)line(0, 10 + angle / 9, 1000, y2);angle += speed;pop()}
}

添加声音与图片

通过P5.js官网的在线编辑器,很容易在项目中添加声音与图像资源,具体操作参考https://www.php.cn/js-tutorial-395952.html。但将项目下载并在网页打开就无法加载音频图片资源,还不知道怎么解决。添加好资源后加上鼠标交互就能达到很好打效果。


//点击右键加载不做人了的图片与音频
//点击右键加载咋瓦鲁多的图片与音频
function loading() {if (mouseIsPressed) {if (mouseButton === RIGHT) {mySound.setVolume(1);mySound.play();imageMode(CENTER);//绘制图片 image(img, 200, 200);tint(0, 153, 204, 126); //渲染}if (mouseButton === LEFT) {mySound.setVolume(1);mySound1.play();imageMode(CENTER);//绘制图片 image(img2, 200, 200);imageMode(CENTER);//绘制图片 image(img1, 200, 200);tint(0, 153, 204, 126); //渲染}}
}


时间停止效果

迪奥在动漫中喊出“the world !”会产生时停。所以想着在右上角添加一个时钟,点击左键会加载图片和音频并让始终停止。
下面是时钟代码,艺术字体参考网上:https://mlln.cn/2018/06/06/p5.js%E6%95%99%E7%A8%8B06-%E6%98%BE%E7%A4%BA%E6%96%87%E5%AD%97/

var showEllipse = false;
let value = 0;function preload() {let style = document.createElement('link')style.rel = "stylesheet"style.href = 'https://fonts.googleapis.com/css?family=Gaegu'document.getElementsByTagName('head')[0].appendChild(style)
}function setup() {createCanvas(800, 800);textFont("Gaegu");// 设置填充颜色fill(123, 0, 0)// 设置框线stroke(255)}function draw() {background(220);time();//if (mouseIsPressed) {//sleep(3000);//}}function mouseClicked() {if (mouseButton === CENTER) {showEllipse = !showEllipse;if (value === 0) {noLoop();value = 255;} else {loop();value = 0;}}
}function time() {let y = year();let m = month();let d = day();let h = hour();let mi = minute();let s = second();let millisecond = millis();// 设置字体大小textSize(26);text('current time: ' + y + '-' + m + '-' + d + '  ' + h + ':' + mi + ':' + s + ':' + millisecond, 25, 60);if (showEllipse) {ellipse(200, height / 2, 50, 50);//sleep(3000);//setTimeout("time()", 3000);}}function sleep(milliseconds) {setTimeout(function() {var start = new Date().getTime();while ((new Date().getTime() - start) < milliseconds) {// Do nothing}}, 0);
}

代码很简单,用了p5中写好的时间函数获取系统当前时间。问题是如何产生时停效果?试了很多方法,什么计时器setTimeout()函数或自定义的sleep()函数都不好使,最后发现p5中有一个noLoop()函数。

通过停止 p5.js 持续重复执行 draw() 内的代码达到时停效果。但又出现了一个问题:通过鼠标交互,左键一下,时间停止,假如停在了当前的15点25分12秒,如果是时停,那么再次点击鼠标时,时间应该从25分13秒开始,然而再次点击,时间只会继续跳到系统当前时间。所以这不是世界的时停,这是绯红之王的时删,感觉我参透了JOJO(捂脸笑哭)。而且我不知道怎么改,觉得最开始我应该画一个迪亚波罗。
还有一个问题就是显示的时间总是后一秒盖住前一秒,代码在其他跑就没这个问题,不知道怎么回事,有待改良。

最终代码

var img;
var img1;
var img2;
var sign;
let value = 0;
var angle = 0;
var offset = 30;
var offset2 = 20000;
var scalar = 90;
var speed = 8;function preload() {soundFormats('mp3', 'ogg');mySound1 = loadSound('theworld1.mp3');mySound = loadSound('buzuorenle.mp3');//加载图片文件 img = loadImage("buzuoren.png");img1 = loadImage("theworld1.png");img2 = loadImage("theworld2.png");//字体let style = document.createElement('link')style.rel = "stylesheet"style.href = 'https://fonts.googleapis.com/css?family=Gaegu'document.getElementsByTagName('head')[0].appendChild(style)}function setup() {createCanvas(900, 580);background(210);sign = 0;textFont("Gaegu");
}function draw() {time();loading();noFill();stroke(255, 170, 149); //粉线//stroke(0);strokeWeight(4);//手beginShape();fill(255, 230, 215);vertex(283, 405);bezierVertex(303, 381, 339, 385, 341, 402); //54bezierVertex(274, 426, 309, 474, 256, 503); //55bezierVertex(151, 528, 216, 355, 283, 405); //56//bezierVertex(523, 398, 391, 433, 391, 433);endShape();//补线noFill();bezier(283, 405, 301, 428, 275, 448, 250, 415); //57bezier(247, 414, 299, 438, 270, 469, 234, 438); //58bezier(234, 440, 281, 455, 257, 485, 224, 457); //59bezier(224, 456, 271, 475, 251, 501, 213, 480); //60stroke(255, 216, 68);//stroke(0);strokeWeight(4);//身子beginShape();fill(255, 238, 176);vertex(391, 433);bezierVertex(367, 437, 338, 460, 321, 478); //50bezierVertex(378, 506, 571, 498, 645, 450); //51bezierVertex(594, 424, 559, 405, 523, 398); //52bezierVertex(523, 398, 391, 433, 391, 433);endShape();//脖子beginShape();fill(255, 230, 215);vertex(402, 381);bezierVertex(408, 391, 408, 391, 411, 407); //49bezierVertex(317, 483, 611, 419, 492, 388); //53bezierVertex(492, 388, 481, 367, 481, 367);bezierVertex(481, 367, 402, 381, 402, 381);endShape();stroke(255, 170, 149); //粉线//stroke(0);strokeWeight(4);bezier(402, 381, 411, 400, 416, 413, 417, 423); //49.5bezier(482, 376, 488, 384, 492, 392, 499, 400); ////脸beginShape();fill(255, 230, 215);vertex(588, 285);bezierVertex(642, 178, 731, 342, 597, 320); //p2-p1   bezierVertex(539, 435, 284, 416, 324, 311); //34  bezierVertex(295, 357, 248, 274, 316, 268); //36bezierVertex(316, 268, 316, 160, 316, 160);bezierVertex(316, 160, 459, 100, 459, 100);bezierVertex(459, 100, 592, 153, 592, 153);bezierVertex(592, 153, 588, 285, 588, 285);endShape();stroke(255, 216, 68);//stroke(0);strokeWeight(4);//头发组1 11-16beginShape();fill(255, 238, 176);vertex(358, 207);bezierVertex(346, 196, 336, 214, 337, 251); //11bezierVertex(337, 251, 326, 237, 326, 237); //11.5  //bezier(341,152,324,186,303,211,337,251);//12//bezier(326,237,318,247,328,263,332,294);//13bezierVertex(318, 247, 328, 263, 332, 294); //13bezierVertex(321, 276, 308, 256, 307, 253); //14  bezierVertex(302, 236, 303, 277, 303, 277); //15.5-14bezierVertex(289, 264, 274, 267, 272, 250); //15.5bezierVertex(262, 231, 283, 210, 259, 189); //15bezierVertex(259, 189, 283, 203, 283, 203); //15-16 bezierVertex(268, 169, 278, 145, 310, 121); //16bezierVertex(310, 121, 309, 151, 309, 151); //16-17 //头发组2 17-22bezierVertex(307, 125, 355, 112, 363, 67); //17bezierVertex(363, 67, 379, 107, 379, 107); //17-18bezierVertex(385, 63, 455, 76, 478, 40); //18bezierVertex(478, 40, 466, 74, 466, 74); //18-19bezierVertex(497, 45, 563, 113, 618, 83); //19bezierVertex(618, 83, 591, 110, 591, 110); //19-20bezierVertex(617, 104, 639, 115, 663, 144); //20bezierVertex(663, 144, 624, 138, 624, 138); //20-21    bezierVertex(646, 134, 659, 178, 671, 221); //21bezierVertex(644, 204, 647, 218, 629, 209); //22   //头发组3 23-28bezierVertex(669, 214, 656, 279, 716, 292); //23bezierVertex(698, 308, 674, 308, 665, 308); //24bezierVertex(665, 308, 696, 327, 696, 327); //24-25bezierVertex(676, 334, 655, 330, 634, 324); //25bezierVertex(621, 339, 628, 347, 640, 362); //31bezierVertex(625, 362, 611, 356, 602, 351); //32bezierVertex(602, 351, 600, 382, 600, 382); //32-33bezierVertex(587, 375, 577, 367, 568, 355); //33  bezierVertex(582, 342, 590, 330, 597, 320); //33-p1bezierVertex(731, 342, 642, 178, 588, 285); //p1-p2bezierVertex(589, 258, 575, 237, 561, 230); //28   bezierVertex(553, 242, 546, 250, 538, 257); //28-p3    bezierVertex(548, 235, 544, 219, 529, 218); //30bezierVertex(525, 194, 503, 127, 449, 169); //30-p4bezierVertex(424, 124, 384, 167, 358, 207); //p4-11//bezierVertex(568, 355, 586, 286, 586, 286); //33-28//bezierVertex(577, 257, 587, 234, 560, 228); //28  //bezierVertex(560, 228, 449, 168, 449, 168); //28-3//bezierVertex(449, 168, 358, 207, 358, 207); //3-11 endShape();//补线noFill();bezier(671, 221, 647, 195, 626, 228, 606, 189); //22bezier(358, 207, 346, 196, 336, 214, 337, 251); //11bezier(341, 152, 324, 186, 303, 211, 337, 251); //12bezier(326, 237, 318, 247, 328, 263, 332, 294); //13bezier(544, 149, 591, 184, 565, 218, 540, 257); //29bezier(586, 286, 599, 259, 609, 233, 624, 234); //27bezier(302, 236, 308, 256, 321, 276, 332, 294); //14  stroke(0, 128, 64);//stroke(0);strokeWeight(4);//头戴7-8beginShape();fill(161, 190, 160);vertex(507, 193);bezierVertex(476, 206, 425, 203, 392, 192); //7bezierVertex(392, 192, 390, 225, 390, 225);bezierVertex(416, 230, 480, 237, 508, 221); //8bezierVertex(508, 221, 502, 193, 507, 193);endShape();//心9-10bezier(448, 245, 410, 223, 405, 180, 450, 196); //9bezier(448, 245, 494, 223, 488, 177, 450, 196); //10stroke(255, 216, 68);//stroke(0);strokeWeight(4);//刘海1-6beginShape();fill(255, 238, 176);vertex(398, 244);bezierVertex(308, 193, 392, 149, 429, 134); //1bezierVertex(442, 124, 440, 155, 449, 168); //3bezierVertex(467, 144, 472, 132, 485, 142); //4bezierVertex(514, 153, 568, 223, 489, 249); //5bezierVertex(527, 203, 489, 149, 449, 176); //6bezierVertex(424, 144, 377, 193, 398, 244); //2endShape();stroke(255, 170, 149);//stroke(0);strokeWeight(4);//嘴 34-40beginShape();fill(255);vertex(480, 337);bezierVertex(443, 386, 423, 401, 408, 344); //38bezierVertex(428, 348, 468, 343, 480, 337); //37endShape();//牙beginShape();fill(255, 255, 255);vertex(480, 337);bezierVertex(487, 342, 491, 353, 494, 361); //39bezierVertex(501, 347, 503, 334, 505, 330); //40bezierVertex(498, 331, 492, 336, 480, 337);endShape();//眼 41-42beginShape();fill(242, 43, 1);vertex(419, 283);bezierVertex(390, 313, 404, 327, 345, 262); //41bezierVertex(345, 262, 419, 283, 419, 283);endShape();beginShape();fill(242, 43, 1);vertex(573, 267);bezierVertex(492, 326, 521, 315, 478, 282); //42bezierVertex(478, 282, 573, 267, 573, 267);endShape();stroke(255, 216, 68);//stroke(0);strokeWeight(4);//左眉毛 43-48beginShape();fill(255, 238, 176);vertex(351, 237);bezierVertex(351, 237, 408, 272, 408, 272); //43bezierVertex(408, 272, 416, 259, 416, 259); //45bezierVertex(416, 259, 351, 237, 351, 237); //44endShape();//右眉毛beginShape();fill(255, 238, 176);vertex(540, 241);bezierVertex(540, 241, 477, 260, 477, 260); //46bezierVertex(477, 260, 480, 274, 480, 274); //48bezierVertex(480, 274, 540, 241, 540, 241); //47endShape();beijing();}function beijing() {stroke(0);strokeWeight(1);//背景  var y1 = offset + sin(angle) * scalar;var y2 = offset2 + sin(angle + 0.4) * scalar;for (var i = 0; i < 1; i++) {translate(width / 2, height / 2)rotate(angle)push()y1 = offset + sin(angle) * scalar;rotate(angle)line(0, 10 + angle / 9, 1000, y2);angle += speed;pop();}}//点击右键加载不做人了的图片与音频
//点击右键加载咋瓦鲁多的图片与音频
function loading() {if (mouseIsPressed) {if (mouseButton === RIGHT) {mySound.setVolume(1);mySound.play();imageMode(CENTER);//绘制图片 image(img, 200, 200);tint(0, 153, 204, 126); //渲染}if (mouseButton === LEFT) {mySound.setVolume(1);mySound1.play();imageMode(CENTER);//绘制图片 image(img2, 200, 200);imageMode(CENTER);//绘制图片 image(img1, 200, 200);tint(0, 153, 204, 126); //渲染}}
}function time() {//rect(550, 60, 55, 55, 20);fill(123, 0, 0)// 设置框线stroke(255)//let y = year();//let m = month();//let d = day();let h = hour();let mi = minute();let s = second();let millisecond = millis();// 设置字体大小textSize(35);text(h + ':' + mi + ':' + s, 650, 60);}function mouseClicked() {if (mouseButton === LEFT) {if (value === 0) {noLoop();value = 255;} else {loop();value = 0;}}}

P5.js创意自画像编程相关推荐

  1. P5.js创意编程之自我介绍

    P5.js创意编程之自我介绍 构思 作为一个树莓人,熬夜修仙就是条必走之路 那就画个修仙老头??? 先画草图吧 敲代码环节 就像图上那样,无非就算各种坐标 过程超级繁琐 就直接粘代码了 functio ...

  2. p5.js创意绘图(2)自画像

    利用p5.js画一幅自画像,效果如下: 1.按下键盘"M"(music)键,音乐停止播放:再次按下"M"键,音乐重新开始播放. 2.按下键盘"S&qu ...

  3. p5.js创意编程——Q版人像绘制

    目录 主要函数介绍 贝塞尔曲线 Shape frameRate 完整代码 实现效果 主要函数介绍 贝塞尔曲线 如图,是p5.js官方reference上关于贝塞尔曲线的说明,一次可以画出一条贝塞尔曲线 ...

  4. 基于p5.js的自画像,实现眨眼,暂停动态效果,改变背景

    前言 本次的自画像是临摹之前的一张照片--是和舍友一起玩的时候拍的.非常怀念那时的欢乐,现在大家都忙,很难再聚一块,以此怀念一下. 文章目录 前言 1. 效果展示 2. 代码解析 1. 人体的描绘 2 ...

  5. p5.js创意绘图(1)动态图形

    利用p5.js临摹一幅动态图形. 原图 分析 看起来像是两个葫芦在转圈,其实每个圆点并没有旋转,只是在以图形中心为原点的射线上来回移动.长瘦葫芦上的圆点移动的周期是短胖葫芦上的圆点移动的周期的两倍,且 ...

  6. p5.js动态自画像

    自画像展示 由于本人喜欢看国产动画片<大耳朵图图>,里面图图有一个特异功能就是可以动耳朵,所以本次自画像在本人形象的基础上加入交互元素--耳朵可以跟随鼠标光标的移动而移动. 以下为静态形象 ...

  7. 超炫酷|一堂课带你入门 p5.js 数字艺术新世界!

    一提起程序员,人们往往会脑补出一副双肩包.格子衫.脱发的画面,同时将程序员和「不修边幅.毫无美感」等糟糕的词汇联系了起来-- 但事实真的如此吗? 事实是: 我们不脱发 程序员的脱发比例是各行业中较低的 ...

  8. 使用p5.js画一幅创意自画像

    使用p5.js画一幅创意自画像 使用p5.js画一幅创意自画像 用编程方式创作一幅介绍自己的图片,因为我很喜欢五月天,所以我的自画像就是展示我去看演唱会的样子,穿着五月天Logo的stayrealT恤 ...

  9. p5.js 绘制创意自画像(互动媒体技术作业)

    p5.js 绘制创意自画像Little Prince(互动媒体技术作业) 作品展示 代码&创意点分析 1.设置工具类以获取坐标点:本次实验最有用的东西就是这个了 2.眼睛跟随鼠标运动: 3.披 ...

  10. Originality Self-portrait 创意自画像——p5.js

    Originality Self-portrait 创意自画像--p5.js 1.对自己的理解--以便自画. 个人性格比较像熊,平时吃饱喝足还是比较温顺的,但是烦心事比较暴躁,看什么东西都会不爽,所以 ...

最新文章

  1. html的input不可编辑状态,HTML中让表单input不可编辑的方法
  2. app.vue添加子组件
  3. django 创建超级用户时报错 1146
  4. micropython安装第三方库_【python操作】python安装第三方库的方法总结
  5. Java即时类| hashCode()方法与示例
  6. 2022年百度新能源汽车行业洞察
  7. 好看有个性的网站导航源码
  8. 逻辑回归与线性回归的区别
  9. python qt库,用于 Python 的高级 GUI 库(Qt 和 PyQt)(1)Unix系统 -电脑资料
  10. 世界上第一个手机是怎么诞生的?谁是第一个用手机的人?
  11. SSH如何通过公钥连接云服务器
  12. 【图像隐写】基于matlab GUI DWT+SVD数字水印 【含Matlab源码 939期】
  13. Goby内测版和AWVS14最新版联合教程详细说明
  14. android系统壁纸下载,提前用上Android 12系统 官方高清壁纸下载
  15. web前端 vue 面试题(一)
  16. 角色个人属性英文缩写
  17. html MP4视频浏览器播放黑屏
  18. 交换机、路由器和防火墙的原理和区别
  19. TestNG教程三:TestNG中的监听
  20. 打印程序在计算机上的应用程序,什么是“后台打印程序子系统应用程序”(spoolsv.exe),以及为什么它在我的电脑上运行?...

热门文章

  1. java键盘事件无反应_键盘事件,没反应
  2. 基于FPGA的ADS1256讲解
  3. spring + springmvc +mybatis 搭建 maven 项目的核心配置文件
  4. hiveSQL面试题16__时间序列--构造日期
  5. 加入飞桨特殊兴趣小组(PPSIG),点亮AI时代的梦想
  6. MacBook Pro的touchbar疯狂闪烁 通过写程序不断点亮touchbar,从而避免其闪烁
  7. 计算机cpu风扇不转怎么办,组装电脑cpu风扇不转怎么办 组装电脑cpu风扇不转解决方法【介绍】...
  8. 计算机白板培训报道,学习电子白板心得体会
  9. 如何根据移动端设计图设计rem比例
  10. 皮皮虾技术三面,我的面试经验与总结分享