前橋工科大学 – デザイン演習 II 2022
第2課題演習 – The Last Clockをp5.jsで作ってみる

「時間を表現する」という第2課題の練習として、The Last Clockをp5.jsで実現してみましょう!
カメラ入力基本
画面中央にカメラ映像(640 x 480)を表示するサンプル
let capture;
function setup() {
createCanvas(windowWidth, windowHeight);
//Webcamキャプチャー設定
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
}
function draw() {
background(0);
//キャプチャーした映像を画面中央に描画
imageMode(CENTER);
image(capture, width / 2, height / 2, 640, 480);
}
スリット画像抽出
中心の縦1ピクセル分だけ抽出する (スリット)
let capture;
let slitX = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
//Webcamキャプチャー設定
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
background(0);
}
function draw() {
imageMode(CENTER);
//カメラ映像の左右の中心1pixelを抽出
let scan = capture.get(capture.width/2, 0, 1, 480);
//抽出した画像を描画
image(scan, width/2, height/2);
}
スリットスキャン
スリットで抽出した画像を横に並べていく(スリットスキャン)
let capture;
let slitX = 0; //スキャンするスリットの位置
function setup() {
createCanvas(windowWidth, windowHeight);
//Webカムからキャプチャー (640x480)
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
background(0);
}
function draw() {
//イメージを中央揃えで
imageMode(CENTER);
//カメラの左右の中心の1ピクセル幅の帯をキャプチャー
let scan = capture.get(capture.width / 2, 0, 1, capture.height);
//左から右に移動しながらキャプチャーした画像を描画
image(scan, slitX, height / 2, 1, capture.height);
//描画位置を1ピクセル右へ
slitX = slitX + 1;
//もし画面の右端まできたら左からくりかえし
if(slitX > width) {
slitX = 0;
}
}
スキャンした画像を回転 (1分で1周)
let capture;
let slitX = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
//Webcamキャプチャー設定
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
background(0);
}
function draw() {
imageMode(CENTER);
//カメラ映像の左右の中心1pixelを抽出
let scan = capture.get(capture.width / 2, 0, 1, 480);
//ミリ秒を換算した秒を計算
let ms = millis() / 1000.0;
let s = second();
s = (s / 1000.0) + ms;
//円形にスキャンした画像の軌跡を描く
translate(width / 2, height / 2);
push();
rotate(radians(s * 6.0));
image(scan, 0, -height / 3, 4, height / 6);
pop();
}
The Last Clockへ!
分針と時針を追加して、The Last Clockのカバーへ!
let capture;
let slitX = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
//Webcamキャプチャー設定
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
background(0);
}
function draw() {
imageMode(CENTER);
//カメラ映像の左右の中心1pixelを抽出
let scan = capture.get(capture.width / 2, 0, 1, 480);
//ミリ秒を換算した秒を計算
let ms = millis() / 1000.0;
let s = second();
s = (s / 1000.0) + ms;
let m = minute() + (second() / 60.0);
let h = hour() + (minute() / 60.0);
//円形にスキャンした画像の軌跡を描く
translate(width / 2, height / 2);
//秒針
push();
rotate(radians(s * 6.0));
image(scan, 0, -height / 12 * 5, 2, height / 6);
pop();
//分針
push();
rotate(radians(m * 6.0));
image(scan, 0, -height / 12 * 3, 1, height / 6);
pop();
//時針
push();
rotate(radians(h * 30.0));
image(scan, 0, -height / 12, 1, height / 6);
pop();
//枠線
noFill();
stroke(127);
strokeWeight(0.5);
circle(0, 0, height);
circle(0, 0, height/3*2);
circle(0, 0, height/3);
}
応用: スリットを自由に動かしてみる!
リサジュー図形 + 回転

let capture;
let slitX = 0;
let slitY = 0;
let scanRot = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
background(0);
}
function draw() {
//画面の中心を減点に
translate(width / 2, height / 2);
imageMode(CENTER);
//1ピクセルのスリットをキャプチャー
let scan = capture.get(capture.width / 2, 0, 1, capture.height);
//三角関数でリサジュー図形に
slitX = cos(frameCount / 200.0) * width / 4;
slitY = sin(frameCount / 230.0) * width / 4;
scanRot = scanRot + 0.3;
//指定した場所に画像を描く
push();
translate(slitX, slitY);
rotate(radians(scanRot));
image(scan, 0, 0, 10, capture.height);
pop();
}
グニャグニャビデオ
The Fourth Dimension (1988) – Zbigniew Rybczynski 風エフェクト
let capture;
let div = 128.0;
let imageBuffer = [];
function setup() {
createCanvas(windowWidth, windowHeight);
capture = createCapture(VIDEO);
capture.size(640, 480);
capture.hide();
background(0);
}
function draw() {
translate(width / 2 - capture.width / 2, height / 2 - capture.height / 2);
let snap = capture.get(0, 0, capture.width, capture.height);
imageBuffer.push(snap);
if (imageBuffer.length > div) {
imageBuffer.shift();
}
for (let i = 0; i < imageBuffer.length; i++) {
let ypos = capture.height / div * i;
let img = imageBuffer[i].get(0, ypos, capture.width, capture.height / div + 1);
image(img, 0, capture.height / div * i);
}
}
次回までの課題
- 作品にタイトルをつける
- 本日のエスキースを踏まえて、より精緻なスケッチを作成する
- 展示の際の方法などもざっくりと考えてくること