伴隨 P5.js 入坑創意編程

上一篇文章:填坑!完結娛樂圈明星關係圖譜 發佈後,古柳印象裏過往留下的坑貌似只剩下 圖像檢索(一):因緣際會與前瞻 的後續實踐代碼(原文裏給了參考代碼連接)和在豆瓣Top250電影海報上的嘗試效果了。
javascript

一想到全部坑都被填了(若是還有啥是我不記得的,請千萬不要提醒我),就以爲真是業界良心,倍感輕鬆。html

因而古柳某日點開 圖像檢索(一):因緣際會與前瞻一文,回顧「佳做」之餘,也找了下里面清華美院向帆老師的做品集網站 zeelab Projects前端

PS:若是你沒看過這個演講,推薦一看,古柳至今難忘:【一席】向帆:若是把每一年的春晚都像蚊香同樣捲起來的話,它就是這樣的
java

而在這些做品中,古柳更中意且也想實現下相似網頁展現效果的是:AwardPuzzel - zeelab 。下面援引下「官方」介紹,建議去網頁體驗一下:編程

AwardPuzzel 是一個全國美展油畫類獲獎畫做的數據視覺化做品,收錄了美展第六屆至第十二屆的2276幅獲獎做品,經過動態交互的方式呈現了中國油畫30年間的藝術歷程、形態、色彩、尺寸和地區之間的變化和關係以及中國油畫大師們的藝術思路。
本做品能夠被看成研究工具爲研究者和評論家使用,亦可做藝術做品欣賞。
咱們但願經過這個平臺分享咱們的視角,也但願使用者經過本身的瀏覽和觀察獲得本身的結論。
全國美展是中國美術界最重要事件,每五年舉辦一次,第六屆是1984年舉辦,第十二屆爲2014年舉辦。canvas

雖然古柳不怎麼會前端,但自從接觸爬蟲以來,右鍵「審查元素」,查看網頁源代碼的習慣仍是有的。微信

因而不看不知道,一看又引出了後續的諸多故事,借用書上的一句話:「那日也是合該有事」,且聽古柳慢慢道來……
dom

點開網頁源代碼後,找到數據展現和交互的區域對應的代碼天然是不難的。這裏爲了展現方便,特意丟到 Carbon 裏,重點突出下這段代碼。編程語言

能夠看到 HTML 裏主要用了 canvas 標籤,這也沒什麼,古柳反正不懂 canvas,睜眼瞎罷了,也看不出什麼名堂。可是卻發現標籤裏的 data-processing-soucres 屬性對應的 .pde 文件,特別不同凡響,「聞所未聞,見所未見」,而且想起當初也曾各類蒐羅,希冀能復現向帆老師的春晚或美展油畫項目,雖不了了之,但對 processing 這一能實現各類藝術創意的編程語言有了印象。
ide

因而谷歌了下 「HTML+Canvas+Processing」 等關鍵詞,意外地發現:基於 JavaProcessing 語言的家譜中,還有對應 JavaScriptPython 版本,前者即:P5.js,而這不由使古柳看到了能在網頁中復現上述效果的但願。

提及來,以前古柳壓根一丁點都沒據說過 P5.js,搜了下對應的中文資料也不算多,更偏心看視頻學習的我,看到萬能的B站上有人搬運了油管上Daniel Shiffman 的教學視頻(1-12節),因而立馬刷了下,p5.js 基礎教程 1-7,並所有跟着敲了遍代碼,雖然無字幕,但還蠻好啃的,有不少針對初學編程的知識講解。(原始連接:Code! Programming with p5.js - YouTube

習得新技能後,立馬用明星關係圖譜的圖片簡單粗暴的拼了下照片牆,雖然離美展油畫的效果差了十萬八千里,但也算是賣出了第一步。


其實之前就沒少拼照片牆,想來你們也都見過爬取微信好友而後拼圖的文章,但古柳仍是安利下這篇舊文,裏面的圖片絕對值得一看(若是你看完以爲也不咋地,那……也就隨它去吧):Python PIL庫實現的照片牆成果圖分享

再就是幾天前,看到 @愛可可-愛生活 老師的這則微博:Processing 創做的生成藝術 via:おかず​,配圖漂亮就不說了,重點是帶着 Processing 關鍵詞,因而就埋下了想用 P5.js 實現一波的念頭。

幸運地找到了做品的出處:Generative Art #146 via:おかず,欣喜地發現附有 Processing 實現代碼,並且該系列有更多不錯的做品,遂萌發了想將其全部做品用 P5.js 實現一波並開源的想法。

固然由於目前 P5.js 不夠熟練,JavaScript / ES6 之類也只是入門,不免有所擔憂和顧慮。但在復現這個做品時發現 ProcessingP5.js 真的很像,不少函數接口官方設計成統一的,極大下降了門檻。

上圖就是古柳用 P5.js 復現的效果,雖然還有些小問題,代碼也不必定最規範,但先行分享,後續再優化哈!可在此網址體驗做品生成效果:editor.p5js.org/DesertsX/sk…

歡迎關注,「牛衣古柳」哈!

let particles;
const n = 120;

function setup() {
  createCanvas(900, 900);
  // pixelDensity(2);
  colorMode(HSB, 360, 100, 100, 100);
  rectMode(CENTER);
  newParticles();
}

function draw() {
  for (let i in particles) {
    let p = particles[i];
    p.run();
    if (p.isDead()) {
      particles.splice(i, 1);
    }
  }
}

function forms() {
  for (let j = 0; j < n; j++) {
    let x = random(width), y = random(height);
    let s = random(20, 100);
    let hs = s / 2;
    let c = getCol();
    noStroke();
    fill(c);
    if (random(1) > 0.5) {
      for (let i = -s / 2; i < s / 2; i++) {
        particles.push(new Particle(x + i, y - hs, c));
        particles.push(new Particle(x + i, y + hs, c));
        particles.push(new Particle(x - hs, y + i, c));
        particles.push(new Particle(x + hs, y + i, c));
      }
      square(x, y, s);
    } else {
      for (let a = 0; a < TAU; a += TAU / 360) {
        particles.push(new Particle(x + hs * cos(a), y + hs * sin(a), c));
      }
      circle(x, y, s);
    }
  }
}
function newParticles() {
  // particles = new ArrayList<Particle>();
  particles = new Array();
  background("#FCFCF0");
  forms();
  noiseSeed(parseInt(random(100000)));
}
// function mousePressed() {
// newParticles();
// }
function keyPressed() {
  // 還沒生效
  if (keyCode === 's') {
    saveFrame("123.png");
  }
}
function getCol() {
  let colors = ["#e4572e", "#29335c", "#f3a712", "#a8c686", "#669bbc", "#efc2f0"];
  //let colors = ["#880D1E", "#DD2D4A", "#F26A8D", "#F49CBB", "#CBEEF3"];
  let idx = parseInt(random(colors.length));
  // console.log(idx + colors[idx]);
  return colors[idx];
}
class Particle {
  constructor(x, y, col) {
    this.pos = createVector(x, y);
    this.step = 1;
    this.angle = random(10);
    this.lifeSpan = 100;
    this.noiseScale = 800;
    this.noiseStrength = 90;
    this.col = col;
  }
  show() {
    noStroke();
    // fill(this.col, this.lifeSpan);
    fill(this.col);
    circle(this.pos.x, this.pos.y, 0.5);
  }
  move() {
    this.angle = noise(this.pos.x / this.noiseScale, this.pos.y / this.noiseScale) * this.noiseStrength;
    this.pos.x += cos(this.angle) * this.step;
    this.pos.y += sin(this.angle) * this.step;
    this.lifeSpan -= 0.1;
  }

  isDead() {
    return (this.lifeSpan < 0.0)
  }
  run() {
    this.show();
    this.move();
  }
}複製代碼
相關文章
相關標籤/搜索