伴随 P5.js 入坑创意编程

论坛 期权论坛 期权     
牛衣古柳   2019-6-29 21:29   3004   0
上一篇文章:填坑!完结娱乐圈明星关系图谱 发布后,古柳印象里过往留下的坑貌似只剩下 图像检索(一):因缘际会与前瞻 的后续实践代码(原文里给了参考代码链接)和在豆瓣Top250电影海报上的尝试效果了。


一想到所有坑都被填了(如果还有啥是我不记得的,请千万不要提醒我),就觉得真是业界良心,倍感轻松。
于是古柳某日点开 图像检索(一):因缘际会与前瞻 一文,回顾“佳作”之余,也找了下里面清华美院向帆老师的作品集网站 zeelab Projects
PS:如果你没看过这个演讲,推荐一看,古柳至今难忘:【一席】向帆:如果把每年的春晚都像蚊香一样卷起来的话,它就是这样的

[iframe]https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_874687679080857600[/iframe]

而在这些作品中,古柳更中意且也想实现下类似网页展示效果的是:AwardPuzzel - zeelab 。下面援引下“官方”介绍,建议去网页体验一下:
AwardPuzzel 是一个全国美展油画类获奖画作的数据视觉化作品,收录了美展第六届至第十二届的2276幅获奖作品,通过动态交互的方式呈现了中国油画30年间的艺术历程、形态、色彩、尺寸和地区之间的变化和关系以及中国油画大师们的艺术思路。
本作品可以被当作研究工具为研究者和评论家使用,亦可作艺术作品欣赏。
我们希望通过这个平台分享我们的视角,也希望使用者通过自己的浏览和观察得到自己的结论。
全国美展是中国美术界最重要事件,每五年举办一次,第六届是1984年举办,第十二届为2014年举办。

虽然古柳不怎么会前端,但自从接触爬虫以来,右键“审查元素”,查看网页源代码的习惯还是有的。
于是不看不知道,一看又引出了后续的诸多故事,借用书上的一句话:“那日也是合该有事”,且听古柳慢慢道来……


点开网页源代码后,找到数据展示和交互的区域对应的代码自然是不难的。这里为了展示方便,特地丢到Carbon 里,重点突出下这段代码。
可以看到
  1. HTML
复制代码
里主要用了
  1. canvas
复制代码
标签,这也没什么,古柳反正不懂
  1. canvas
复制代码
,睁眼瞎罢了,也看不出什么名堂。但是却发现标签里的
  1. data-processing-soucres
复制代码
属性对应的
  1. .pde
复制代码
文件,特别与众不同,“闻所未闻,见所未见”,并且想起当初也曾各种搜罗,希冀能复现向帆老师的春晚或美展油画项目,虽不了了之,但对
  1. processing
复制代码
这一能实现各种艺术创意的编程语言有了印象。


于是谷歌了下
  1. “HTML+Canvas+Processing”
复制代码
等关键词,意外地发现:基于
  1. Java
复制代码
  1. Processing
复制代码
语言的家谱中,还有对应
  1. JavaScript
复制代码
  1. Python
复制代码
版本,前者即:
  1. P5.js
复制代码
,而这不禁使古柳看到了能在网页中复现上述效果的希望。


说起来,之前古柳压根一丁点都没听说过
  1. P5.js
复制代码
,搜了下对应的中文资料也不算多,更偏爱看视频学习的我,看到万能的B站上有人搬运了油管上
  1. Daniel Shiffman
复制代码
的教学视频(1-12节),于是立马刷了下,p5.js 基础教程 1-7,并全部跟着敲了遍代码,虽然无字幕,但还蛮好啃的,有很多针对初学编程的知识讲解。(原始链接:Code! Programming with p5.js - YouTube


习得新技能后,立马用明星关系图谱的图片简单粗暴的拼了下照片墙,虽然离美展油画的效果差了十万八千里,但也算是卖出了第一步。





其实以前就没少拼照片墙,想来大家也都见过爬取微信好友然后拼图的文章,但古柳还是安利下这篇旧文,里面的图片绝对值得一看(如果你看完觉得也不咋地,那……也就随它去吧):用python的PIL库实现照片墙的成果分享


再就是几天前,看到
  1. @爱可可-爱生活
复制代码
老师的这则微博:Processing 创作的生成艺术 via:おかず,配图漂亮就不说了,重点是带着
  1. Processing
复制代码
关键词,于是就埋下了想用
  1. P5.js
复制代码
实现一波的念头。

幸运地找到了作品的出处:Generative Art #146 via:おかず,欣喜地发现附有
  1. Processing
复制代码
实现代码,而且该系列有更多不错的作品,遂萌发了想将其所有作品用
  1. P5.js
复制代码
实现一波并开源的想法。


当然因为目前
  1. P5.js
复制代码
不够熟练,
  1. JavaScript
复制代码
/
  1. ES6
复制代码
之类也只是入门,难免有所担心和顾虑。但在复现这个作品时发现
  1. Processing
复制代码
  1. P5.js
复制代码
真的很像,很多函数接口官方设计成统一的,极大降低了门槛。


上图就是古柳用
  1. P5.js
复制代码
复现的效果,虽然还有些小问题,代码也不一定最规范,但先行分享,后续再优化哈!可在此网址体验作品生成效果:https://editor.p5js.org/DesertsX/sketches/GxYHsZg9n
  1. let particles;
  2. const n = 120;
  3. function setup() {
  4.   createCanvas(900, 900);
  5.   // pixelDensity(2);
  6.   colorMode(HSB, 360, 100, 100, 100);
  7.   rectMode(CENTER);
  8.   newParticles();
  9. }
  10. function draw() {
  11.   for (let i in particles) {
  12.     let p = particles[i];
  13.     p.run();
  14.     if (p.isDead()) {
  15.       particles.splice(i, 1);
  16.     }
  17.   }
  18. }
  19. function forms() {
  20.   for (let j = 0; j < n; j++) {
  21.     let x = random(width), y = random(height);
  22.     let s = random(20, 100);
  23.     let hs = s / 2;
  24.     let c = getCol();
  25.     noStroke();
  26.     fill(c);
  27.     if (random(1) > 0.5) {
  28.       for (let i = -s / 2; i < s / 2; i++) {
  29.         particles.push(new Particle(x + i, y - hs, c));
  30.         particles.push(new Particle(x + i, y + hs, c));
  31.         particles.push(new Particle(x - hs, y + i, c));
  32.         particles.push(new Particle(x + hs, y + i, c));
  33.       }
  34.       square(x, y, s);
  35.     } else {
  36.       for (let a = 0; a < TAU; a += TAU / 360) {
  37.         particles.push(new Particle(x + hs * cos(a), y + hs * sin(a), c));
  38.       }
  39.       circle(x, y, s);
  40.     }
  41.   }
  42. }
  43. function newParticles() {
  44.   // particles = new ArrayList();
  45.   particles = new Array();
  46.   background("#FCFCF0");
  47.   forms();
  48.   noiseSeed(parseInt(random(100000)));
  49. }
  50. // function mousePressed() {
  51. //   newParticles();
  52. // }
  53. function keyPressed() {
  54.   // 还没生效
  55.   if (keyCode === 's') {
  56.     saveFrame("123.png");
  57.   }
  58. }
  59. function getCol() {
  60.   let colors = ["#e4572e", "#29335c", "#f3a712", "#a8c686", "#669bbc", "#efc2f0"];
  61.   //let colors = ["#880D1E", "#DD2D4A", "#F26A8D", "#F49CBB", "#CBEEF3"];
  62.   let idx = parseInt(random(colors.length));
  63.   // console.log(idx + colors[idx]);
  64.   return colors[idx];
  65. }
  66. class Particle {
  67.   constructor(x, y, col) {
  68.     this.pos = createVector(x, y);
  69.     this.step = 1;
  70.     this.angle = random(10);
  71.     this.lifeSpan = 100;
  72.     this.noiseScale = 800;
  73.     this.noiseStrength = 90;
  74.     this.col = col;
  75.   }
  76.   show() {
  77.     noStroke();
  78.     // fill(this.col, this.lifeSpan);
  79.     fill(this.col);
  80.     circle(this.pos.x, this.pos.y, 0.5);
  81.   }
  82.   move() {
  83.     this.angle = noise(this.pos.x / this.noiseScale, this.pos.y / this.noiseScale) * this.noiseStrength;
  84.     this.pos.x += cos(this.angle) * this.step;
  85.     this.pos.y += sin(this.angle) * this.step;
  86.     this.lifeSpan -= 0.1;
  87.   }
  88.   isDead() {
  89.     return (this.lifeSpan < 0.0)
  90.   }
  91.   run() {
  92.     this.show();
  93.     this.move();
  94.   }
  95. }
复制代码
欢迎关注,“牛衣古柳”哈!




分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP