よつばと15巻の発売記念にダンボーを描く
p5.jsでダンボーを描く
よつばと15巻が発売です。 とても嬉しく、喜ばしいことですね。
この喜びを表すためにp5.jsでダンボーを描きました。
画像を貼り付けておきます。
ダンボーの描写
関数function danbo(x, y, size, tex)
でダンボーを描いています。
ダンボーは顔の四角形、目の円、口の三角形で構成されるので、シンプルに描画できます。
顔の模様はテクスチャを作成して、四角形に貼り付けています。
模様テクスチャは
- 縦縞
- 横縞
- ランダム円
- ランダム四角形
- パーリンノイズ
を作りました。 それぞれ、2色の色をランダムに選んで模様にしています。
Openproccessing
Openproccessingの方にもアップしておきました。 ランダムでダンボーを描きます。
ソースコード
let vs = ` precision highp float; precision highp int; attribute vec3 aPosition; attribute vec2 aTexCoord; varying vec2 vTexCoord; uniform mat4 uProjectionMatrix; uniform mat4 uModelViewMatrix; void main() { vec4 positionVec4 = vec4(aPosition, 1.0); gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; vTexCoord = aTexCoord; } `; let fs = ` precision highp float; precision highp int; varying vec2 vTexCoord; uniform sampler2D u_tex; uniform float u_time; float pi = 3.14159265358979; float rand(vec2 co) { float a = fract(dot(co, vec2(2.067390879775102, 12.451168662908249))) - 0.5; float s = a * (6.182785114200511 + a * a * (-38.026512460676566 + a * a * 53.392573080032137)); float t = fract(s * 43758.5453); return t; } void main() { vec2 uv = vTexCoord; float radius = 0.0035; uv.x = uv.x + rand(uv + u_time*0.02)*radius ; uv.y = uv.y + rand(uv + u_time*0.01)*radius; vec4 tex = texture2D(u_tex, uv); gl_FragColor = tex; } `; const w = 720; const N = 5; const span = w/N; let theShader ; let pg ; let obj = new Array(N); function setup() { setAttributes("alpha", false); setAttributes("premultipliedAlpha", true); setAttributes("antialias", true); setAttributes("depth", true); setAttributes("powerPreference", "high-performance"); createCanvas(w, w, WEBGL); //noStroke(); drawingContext.enable(drawingContext.BLEND); theShader = createShader(vs, fs); pg = createGraphics(w*1.25, w*1.25); rectMode(CENTER); colorMode(HSB); noLoop(); for(let i=0;i<N;i+=1){ obj[i] = new Array(N); for(let j=0;j<N;j+=1){ obj[i][j] = new danbo_obj(span*(i+0.5), span*(j+0.5), span*0.95); } } } function draw(){ background(random(360), random(30,50), random(90,100)); push(); translate(-w/2, -w/2) for(let i=0;i<N;i+=1){ for(let j=0;j<N;j+=1){ obj[i][j].draw(); } } pop(); let tex = get(); shader(theShader); theShader.setUniform(`u_tex`, tex); theShader.setUniform(`u_time`, frameCount/200); clear(); fill(0, 0, 0, 0); rect(0, 0, w); } function danbo(x, y, size, tex){ const w = size; const h = size * 0.65; const eye_span = size * 0.42; const eye_d = size * 0.125; const eye_y = y - h*0.5*0.15; const mouth_y = y + h*0.5*0.5; const mouth_d = eye_d*0.85; const mouth_y0 = mouth_y - mouth_d*0.5; const mouth_y1 = mouth_y + mouth_d*0.5; const mouth_x0 = x+mouth_d*0.8; const mouth_x1 = x-mouth_d*0.8; push(); strokeWeight(size/32); stroke("#202020"); texture(tex); rect(x, y, w, h); pop(); push(); strokeWeight(0); fill("#202020"); ellipse(x + eye_span*0.5, eye_y, eye_d, eye_d); ellipse(x - eye_span*0.5, eye_y, eye_d, eye_d); triangle(x, mouth_y0, mouth_x0, mouth_y1, mouth_x1, mouth_y1); pop(); } function rand_color(){ return color(random(360), random(20, 100), random(50, 100)); } class danbo_obj{ constructor(x, y, size){ this.x = x; this.y = y; this.size = size; this.tex = this.gen_tex(); } draw(){ danbo(this.x, this.y, this.size, this.tex); } gen_tex(){ let pg = createGraphics(this.size, this.size*0.65); const p = random(0.6); if(p<0.1){ this.line_v_tex(pg); } else if(p<0.2){ this.line_h_tex(pg); } else if(p<0.3){ this.dot_tex(pg); } else if(p<0.4){ this.rect_tex(pg); } else if(p<0.5){ this.noise_tex(pg); } else{ this.normal_tex(pg); } return pg; } normal_tex(pg){ pg.colorMode(HSB); pg.background(rand_color()); } line_v_tex(pg){ pg.colorMode(HSB); pg.noStroke(); pg.background(rand_color()); pg.fill(rand_color()); const line_num = int(random(5,16)); for(let i=0;i<line_num;i+=2){ pg.rect(pg.width/line_num*i, 0, pg.width/line_num, pg.height); } } line_h_tex(pg){ pg.colorMode(HSB); pg.noStroke(); pg.background(rand_color()); pg.fill(rand_color()); const line_num = int(random(5,16)); for(let i=0;i<line_num;i+=2){ pg.rect(0, pg.height/line_num*i, pg.width, pg.height/line_num); } } dot_tex(pg){ pg.colorMode(HSB); pg.noStroke(); pg.background(rand_color()); pg.fill(rand_color()); const dot_num = int(random(10,70)); for(let i=0;i<dot_num;i+=2){ let x = random(pg.width); let y = random(pg.height); pg.ellipse(x, y, random(random(pg.width/2))); } } rect_tex(pg){ pg.colorMode(HSB); pg.rectMode(CENTER); pg.noFill(); pg.background(rand_color()); pg.stroke(rand_color()); pg.strokeWeight(random(0.5, 4)); const dot_num = int(random(3,30)); for(let i=0;i<dot_num;i+=2){ let x = random(pg.width); let y = random(pg.height); pg.rect(x, y, random(random(pg.width/2))); } } noise_tex(pg){ pg.colorMode(HSB); pg.noStroke(); pg.background(rand_color()); const noiseVal = random(1,50); const cellSize = int(random(2,5)); const seed = random(1); let col = rand_color(); for (let y=0; y*cellSize < pg.height; y++) { for (let x=0; x*cellSize < pg.width; x++) { let alpha = noise(x/noiseVal, y/noiseVal, seed) *1.5; col.setAlpha(alpha); pg.fill(col); pg.rect(x*cellSize, y*cellSize, cellSize, cellSize); } } } } //save PNG function mousePressed() { save("img_" + month() + day() + hour() + minute() + second() + ".png"); }