var colorArray = ["#C33B23","#E55130","#17081A","#077284","#00576B","#162B3D"]; var startWs = []; var endWs = []; var ladderWidth = 10; function setup() { createCanvas(900, 900); colorMode(RGB); smooth(); angleMode(DEGREES); strokeCap(SQUARE); ellipseMode(CENTER); noLoop(); } function mousePressed() { redraw(); } var c = 18; function draw() { rectMode(CENTER); let colorPalette = shuffle(colorArray); let bg = color(colorPalette[0]); background(bg); let margin = height / c; let w = width - margin * 2; let h = height - margin * 2; let step = 14; let unit = h / step; let l = random(5,10); let ma = random(1,5); push(); translate(margin, margin); // ---------- ドアの設置 ---------- noStroke(); fill(colorPalette[1]); for(let i = 1; i <= step; i++) { let y = i * unit; let doorH = unit * 0.5; if(random() < 0.2) { rectMode(CORNERS); let doorPos = random(10, w - 10); rect(doorPos - 6, y - doorH, doorPos + 6, y - 1); ellipse(doorPos, y - doorH, 12); } } // ---------- 階段の設置 ---------- let m = 5; strokeWeight(3); noFill(); stroke(colorPalette[2]); for(let i = 1; i <= step; i++) { let y = i * unit; let t = unit / m; // 掛ける場所を決める let ladderPos = random(0, w - ladderWidth); // 上の段に掛けられるか if (random() < 0.95) { if (startWs[i-1] < ladderPos && ladderPos + ladderWidth < endWs[i-1]) { line(ladderPos , y, ladderPos , y - unit); line(ladderPos + ladderWidth, y, ladderPos + ladderWidth, y - unit); for(let j = 1; j < m; j++) { line(ladderPos, y - t * j, ladderPos + ladderWidth, y - t * j); } } else { // かけられなかった場合は75%でリトライ if (random() < 0.75) { i--; } } } // 上の上の段に掛けられるか else { if (startWs[i-2] < ladderPos && ladderPos + ladderWidth < endWs[i-2]) { line(ladderPos , y, ladderPos , y - 2*unit); line(ladderPos + ladderWidth, y, ladderPos + ladderWidth, y - 2*unit); for(let k = 1; k < m * 2; k++) { line(ladderPos, y - t * k, ladderPos + ladderWidth, y - t * k); } } else { // かけられなかった場合は75%でリトライ if (random() < 0.75) { i--; } } } } // ---------- 人1の設置 ---------- noStroke(); fill(colorPalette[3]); for(let i = 1; i <= step; i++) { let y = i * unit; let personH = unit * 0.75; if(random() < 0.5) { let personPos = random(10, w - 10); triangle(personPos - 5, y-2, personPos + 5, y-2, personPos , y - personH*0.7); ellipse(personPos, y - personH*0.6, 12); } } // ---------- 木の設置 ---------- noStroke(); fill(colorPalette[3]); for(let i = 1; i <= step; i++) { let y = i * unit; let treeH = unit * 0.7; if(random() < 0.5) { let treePos = random(10, w - 10); for(let u = 0; u < treeH; u++) { let uu = map(u, 0,treeH, 0, 360); ellipse(treePos + 10* sin(uu)-2.5, y - u, 3,3); uu = map(u, 0,treeH*0.6, 0, 360); ellipse(treePos + 6* sin(uu)-15, y - u*0.6, 3,3); ellipse(treePos + 6* sin(uu)+15, y - u*0.6, 3,3); } } } // ---------- 階段の設置 ---------- strokeWeight(3); noFill(); stroke(colorPalette[5]); let dan = unit/4; for(let i = 1; i <= step; i++) { let y = i * unit; let stairH = unit; if(random() < 0.25) { let stairPos = random(20, w - 20); beginShape(); vertex(stairPos ,y); vertex(stairPos ,y-dan); vertex(stairPos+dan ,y-dan); vertex(stairPos+dan ,y-2*dan); vertex(stairPos+2*dan ,y-2*dan); vertex(stairPos+2*dan ,y-3*dan); vertex(stairPos+3*dan ,y-3*dan); vertex(stairPos+3*dan ,y-4*dan); endShape(); } } // ---------- 人2の設置 ---------- noStroke(); fill(colorPalette[4]); for(let i = 1; i <= step; i++) { let y = i * unit; let personH = unit * 0.75; if(random() < 0.5) { let personPos = random(10, w - 10); triangle(personPos - 5, y-2, personPos + 5, y-2, personPos , y - personH*0.7); ellipse(personPos, y - personH*0.6, 12); } } // ---------- 半円の設置 ---------- noFill(); strokeWeight(5); stroke(colorPalette[3]); for(let i = 1; i <= step; i++) { let y = i * unit; let circleR = unit * 0.75; if(random() < 0.6) { let circlePos = random(15, w - 15); arc(circlePos, y, circleR, circleR, 180, 360); } } // ---------- 机の設置 ---------- strokeWeight(3); fill(bg); stroke(colorPalette[5]); for(let i = 1; i <= step; i++) { let coff = 0.4; let y = i * unit; let deskH = unit * coff; if(random() < 0.2) { let deskPos = random(0 + 20, w - 20); line(deskPos , y - 1.25 , deskPos , y - deskH); line(deskPos + 20, y - 1.25 , deskPos + 20, y - deskH); line(deskPos - 5 , y - deskH , deskPos + 25, y - deskH); ellipse(deskPos + 10, y - deskH * 0.5, 8); } } // ---------- 箱の設置 ---------- strokeWeight(3); for(let i = 1; i <= step; i++) { let y = i * unit; let boxH = unit * 0.3; let b = 3; if(random() < 0.5) { let boxPos = random(30, w - 30); line(boxPos-boxH * 3/2, y-boxH-b ,boxPos-boxH/2 ,y-b); line(boxPos-boxH/2 , y-boxH-b ,boxPos+boxH/2 ,y-b); line(boxPos+boxH/2 , y-boxH-b ,boxPos+boxH * 3/2 ,y-b); line(boxPos-boxH * 3/2, y-b ,boxPos-boxH/2 ,y-boxH-b); line(boxPos-boxH/2 , y-b ,boxPos+boxH/2 ,y-boxH-b); line(boxPos+boxH/2 , y-b ,boxPos+boxH * 3/2 ,y-boxH-b); } } // ---------- フロア ---------- for(let i = 0; i <= step; i++) { let y = i * unit; strokeWeight(4); if(random()<0.5) { stroke(10, 10, 10, 75); } else { stroke(190, 190, 190, 125); } line(0, y, w, y); if (random() < 0.3) { startWs[i] = random(0, w * 0.5); endWs[i] = random(w * 0.5, w); } else { startWs[i] = 0; endWs[i] = w; } // set Color let p = int(random(1,6)); let cd = color(colorPalette[p]); if(random() < 0.6) { stroke(cd); strokeWeight(5); line(startWs[i], y, endWs[i], y); } } // ---------- frameの描画 ---------- let fc; if(random() < 0.5) { fc = color("#141414"); } else { fc = color("#d1d1d1"); } stroke(fc); strokeWeight(9); line(-4, 0, w+4, 0); line(-4, h, w+4, h); line(0, 0, 0, h); line(w, 0, w, h); pop(); push(); blendMode(DIFFERENCE); rectMode(CORNER); let p = int(random(1,6)); let cd = color(colorPalette[p]); let q = random(); fill(cd); if(q < 0.3) { translate(margin, height/2-1); noStroke(); rect(4, 2, width - 2*margin-8, height/2-margin-4); } else if (q < 0.5) { translate(margin, margin); beginShape(); vertex(4 , 4); vertex(4 , height-2*margin-4); vertex(width-2*margin-4 , height-2*margin-4); endShape(); } else if (q < 0.7) { translate(margin, margin); beginShape(); vertex(width-2*margin-4 , 4); vertex(4 , height-2*margin-4); vertex(width-2*margin-4 , height-2*margin-4); endShape(); } else { translate(margin, margin); rect(4, 4, (width - 2*margin-8)/2, (height/2-margin-4)*2); } pop(); }
メモ
- 今回やりたかったのは
blendMode
を使うこと。 - ココに一覧があるけど、今回は色々試してDIFFERENCEを使うことで色味の反転っぽいことができた。
- それ以外についてはソースコードは全く見てないけど随分前にTLでみた、我らがokazz先生の似たような作品(ココの三品目で紹介されているやつ)っぽいものを漠然と作れればなと思ってこんな絵の構成になっている。まあ、再帰でもないんだけどね。
- 多少コード読める人ならすぐわかるけどこのコードはすごく手続き的というか非効率です。でも、先週ツイートしたように、こういう製作者の過程が見えるコーディングのほうが後から作品を真似てみようと思った人の立場になったときに面白いかなって。そういう意図です。
- 最後飽きてしまったのでNEORTで見るとすごい横長です。ご了承ください。
(TouchDesignerのCompositeTOPのOperationみたいなもんですね。)
以下、雑談。 最近、訳合って意識的にたくさんのMVを見ている生活を送っているんだけど、kiki vivi lilyとSUKISHAが組んで演っている「Blue in Green」のMVがとても良くて、その流れでたまたま昨日読んだSUKISHAのインタビュー記事に載っていた言葉が非常に芯を食っているというか、共感できるものだった。
作る人になりたいのに「なかなか仕事が忙しくて…」とか「SNSとか見てるとすごい人が多くて…」とか自分からバリアを張ってしまう人は孤独が足りないんだと思う。"共感"できる楽しみに囲まれてしまうと"生産"の楽しみにBETする勇気いるもんね。かといって共感し会える友達の存在も貴重だからなんとも言えんけど。
みんな好きにしたらいいと思うけど、
ひとまず僕はこの習慣をもうしばらく続けようと思います。