Processingでモーショングラフィックスを作るまで その3
3回目です!
前回の記事はこちら
tofgame.hatenablog.com
今回作るもののイメージ
(1)文字が回転しながら中心に寄る
(2)全部の文字が中心に寄ったら文字が消える
(3)文字が消えた部分から丸が広がり文字が現れる
文字が回転しながら中心に寄る
文字用クラス「RotateText」を作成します。
中心点を基準に三角関数で位置を決めるイメージです。
半径と角度を変数定義しておき、それを変更することで回転、中心に寄るといった動作を実装します。
全部の文字が中心に寄ったら文字が消える
半径が0になったタイミングでArrayListのRemoveを使って消します。
文字が消えた部分から丸が広がり文字が現れる
circle関数を使って丸を書きます。
背景色を白、丸の色を黒にするので、文字色を背景色と同じにしてあたかも文字が自然に現れたような表現をします。
完成したもの
ソースコード
PFont font; ArrayList<RotateText> movingTexts=new ArrayList<RotateText>(); GrowingCircle growingCircle; Blur blur; String displayText="MOTIONTHREE"; int scene; void setup() { size(600, 600); textAlign(CENTER, CENTER); colorMode(HSB, 360, 100, 100, 100); font=createFont("Voynich_MonoSpace.ttf", 60); textFont(font, 60); for (int i=0; i<displayText.length(); i++) { movingTexts.add(new RotateText(String.valueOf(displayText.charAt(i)), width*1.1, i/(float)displayText.length()*360, new PVector(width/2, height/2))); } growingCircle=new GrowingCircle(new PVector(width/2, height/2), 0, 100); blur=new Blur(); } void draw() { background(0, 0, 100); switch(scene) { case 0: if (keyPressed) { scene=1; } break; case 1: for (int i=movingTexts.size()-1; i>=0; i--) { movingTexts.get(i).run(); if (movingTexts.get(i).removeFlag) { movingTexts.remove(i); } if (movingTexts.size()<=0) { scene=2; } } break; case 2: growingCircle.run(); fill(0, 0, 100); text(displayText, width/2, height/2); blur.run(); break; } } class RotateText { String str; //文字 float radius; //半径 float angle; //角度 PVector midPos; //中心位置 PVector pos; //位置 boolean removeFlag; RotateText(String str, float radius, float angle, PVector midPos) { this.str=str; this.radius=radius; this.angle=angle; this.midPos=midPos; } void run() { rogic(); display(); } void rogic() { angle+=6; radius-=3; if (radius<=0) removeFlag=true; pos=RoundPos(midPos, radius, angle); } void display() { fill(0, 0, 0); text(str, pos.x, pos.y); } PVector RoundPos(PVector midPos, float radius, float angle) { return new PVector(midPos.x+sin(radians(angle+180))*radius, midPos.y+cos(radians(angle+180))*radius); } } class GrowingCircle { PVector pos; float size; float spd; GrowingCircle(PVector pos, float size, float spd) { this.pos=pos; this.size=size; this.spd=spd; } void run() { rogic(); display(); } void rogic() { size+=spd; } void display() { noStroke(); fill(0, 0, 0); circle(pos.x, pos.y, size); } } class Blur { float angle; float time; void run() { time+=1; if (time>=60) { angle+=random(1, 10); filter(BLUR, abs(sin(radians(angle)))*4); } } }
次回
近いうちに!