Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
85 changes: 8 additions & 77 deletions dragdrop.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cyclogram.js prototype</title>
<title>Cyclogram.js</title>
<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script type="module" src="dragdrop.js"></script>
</head>

<style>
Expand All @@ -15,80 +15,11 @@
</style>

<body>
<div id="dragdrop">
<input id="input" type="file" accept=".jpg,.jpeg.,.gif,.png,.mov,.mp4" />
<p><strong>Select a video or image file</strong></p>
</div>
<div id="video"></div>
<div id="canvas"></div>
<script>

let frameRate = 30;
let rowNumber = 0;
let framesPerDay = 288/2; // remove nighttime hours, crudely
let colNumber = 0;
let myX = 100; // where you've clicked
let myY = 400;
let video;
let playVideo = false;
let i = 0;
let dotSize = 6;
let steps;
let density;

function setup() {
createCanvas(1000, 400).parent('canvas');

document.getElementById('input').addEventListener('change', function(event) {
var file = event.target.files[0];
var fileReader = new FileReader();
fileReader.onload = function() {
var blob = new Blob([fileReader.result], {type: file.type});
var url = URL.createObjectURL(blob);
video = createVideo(url).parent('video');

//video.elt.getVideoPlaybackQuality().totalVideoFrames // only how many frames have loaded so far
video.elt.controls = true;
video.elt.load();
noStroke();
steps = parseInt(frameRate * video.elt.duration) // in seconds
density = 1;//pixelDensity();

video.elt.onclick = function click(e) {
myX = parseInt(e.offsetX/video.elt.clientWidth * video.width);
myY = parseInt(e.offsetY/video.elt.clientHeight * video.height);
e.preventDefault();
}

}
fileReader.readAsArrayBuffer(file);
})
}

function draw() {
if (video) {
// video.elt.currentTime = i/frameRate;
video.loadPixels();
let color = [
video.pixels[(myY*video.width*4*density) + (myX*4*density)], // get red
video.pixels[(myY*video.width*4*density) + (myX*4*density + 1)], // get green
video.pixels[(myY*video.width*4*density) + (myX*4*density + 2)] // get blue
];

rect(i % framesPerDay * dotSize, rowNumber * dotSize, dotSize, dotSize);
fill(color);
colNumber += 1;
if (i % framesPerDay == 0) {
rowNumber += 1; // new row
colNumber = 0;
}
if (i == steps) i = 0;
else i++;
}
}

</script>


<div id="dragdrop">
<input id="input" type="file" accept=".jpg,.jpeg.,.gif,.png,.mov,.mp4" />
<p><strong>Select a video or image file</strong></p>
</div>
<div id="video"></div>
<div id="canvas"></div>
</body>
</html>
51 changes: 51 additions & 0 deletions dragdrop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createCyclogramCanvas, drawCyclogram } from "./modules/cyclogram.js";
import { processUploadedVideo } from "./modules/video.js";

let processedVideoResponse = {};
let framesPerDay = 288/2; // remove nighttime hours, crudely
let dotSize = 6;
let i = 0;
let rowNumber = 0;
let colNumber = 0;

new p5(function(p5) {
p5.setup = function() {
const canvasOptions = {
width: 1000,
height: 400,
element: 'canvas',
};
createCyclogramCanvas(p5, canvasOptions);

document.getElementById('input').addEventListener('change', async function(event) {
try {
processedVideoResponse = await processUploadedVideo(p5, event);
} catch (error) {
alert('Error loading file!');
}
})
}

p5.draw = function() {
const { video, frameRate, steps, density, x, y } = processedVideoResponse;
if (video) {
const drawOptions = {
video,
frameRate,
steps,
density,
myX: x || 100,
myY: y || 400,
framesPerDay,
dotSize,
i,
rowNumber,
colNumber,
};
const cyclogramResults = drawCyclogram(p5, drawOptions);
i = cyclogramResults.i;
rowNumber = cyclogramResults.rowNumber;
colNumber = cyclogramResults.colNumber;
}
}
});
36 changes: 36 additions & 0 deletions modules/cyclogram.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
function createCyclogramCanvas(p5Instance, canvasOptions) {
const { width, height, element } = canvasOptions;
const canvas = p5Instance.createCanvas(width, height);
canvas.parent(element);
return canvas;
}

function drawCyclogram(p5Instance, drawOptions) {
const { video, frameRate, steps, density, myX, myY, framesPerDay, dotSize } = drawOptions;
let { i, rowNumber, colNumber } = drawOptions;

// video.elt.currentTime = i/frameRate;
video.loadPixels();
let color = [
video.pixels[(myY * video.width * 4 * density) + (myX * 4 * density)], // get red
video.pixels[(myY * video.width * 4 * density) + (myX * 4 * density + 1)], // get green
video.pixels[(myY * video.width * 4 * density) + (myX * 4 * density + 2)] // get blue
];

p5Instance.rect(i % framesPerDay * dotSize, rowNumber * dotSize, dotSize, dotSize);
p5Instance.fill(color);
colNumber += 1;
if (i % framesPerDay == 0) {
rowNumber += 1; // new row
colNumber = 0;
}
if (i == steps) i = 0;
else i++;

return { i, rowNumber, colNumber };
}

export {
createCyclogramCanvas,
drawCyclogram,
}
54 changes: 54 additions & 0 deletions modules/video.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
function getCoordinatesOfVideoClick(video, clickEvent) {
const x = parseInt(clickEvent.offsetX/video.elt.clientWidth * video.width);
const y = parseInt(clickEvent.offsetY/video.elt.clientHeight * video.height);
clickEvent.preventDefault();
return { x, y };
}

function loadVideo(p5Instance, loadOptions) {
const { url, element } = loadOptions;
const video = p5Instance.createVideo(url);
video.parent(element);

// video.elt.getVideoPlaybackQuality().totalVideoFrames // only how many frames have loaded so far
video.elt.controls = true;
video.elt.load();
p5Instance.noStroke();
const frameRate = 30;
const steps = parseInt(frameRate * video.elt.duration) // in seconds
const density = 1; // pixelDensity();

let coordinates = {};
video.elt.onclick = function click(event) {
coordinates = getCoordinatesOfVideoClick(video, event);
};

return { video, frameRate, steps, density, ...coordinates };
}

async function processUploadedVideo(p5Instance, event) {
const file = event.target.files[0];
const fileReader = new FileReader();

return new Promise((resolve, reject) => {
fileReader.onerror = () => {
fileReader.abort();
reject(new DOMException('Problem parsing input file'));
};

fileReader.onload = () => {
const blob = new Blob([fileReader.result], { type: file.type });
const url = URL.createObjectURL(blob);
const loadOptions = { url, element: 'video' };
const response = loadVideo(p5Instance, loadOptions);
resolve(response);
};
fileReader.readAsArrayBuffer(file);
});
}

export {
loadVideo,
getCoordinatesOfVideoClick,
processUploadedVideo,
};
63 changes: 3 additions & 60 deletions prototype.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Cyclogram.js prototype</title>
<script src="https://cdn.jsdelivr.net/npm/p5@1.5.0/lib/p5.js"></script>
<script type="module" src="prototype.js"></script>
</head>

<style>
Expand All @@ -15,64 +15,7 @@
</style>

<body>
<div id="video"></div>
<div id="canvas"></div>
<script>

let frameRate = 30;
let rowNumber = 0;
let framesPerDay = 288/2; // remove nighttime hours, crudely
let colNumber = 0;
let myX = 100; // where you've clicked
let myY = 400;
let video;
let playVideo = false;
let i = 0;
let dotSize = 6;
let steps;
let density;

function setup() {
createCanvas(1000, 400).parent('canvas');

video = createVideo('river.mp4').parent('video');
//video = createVideo('https://archive.org/download/cyclogram-timelapse-test/9-month-river-timelapse-autumn-winter-sprin.mp4')
//video.elt.getVideoPlaybackQuality().totalVideoFrames // only how many frames have loaded so far
video.elt.controls = true;
video.elt.load();
noStroke();
steps = parseInt(frameRate * video.elt.duration) // in seconds
density = 1;//pixelDensity();

video.elt.onclick = function click(e) {
myX = parseInt(e.offsetX/video.elt.clientWidth * video.width);
myY = parseInt(e.offsetY/video.elt.clientHeight * video.height);
e.preventDefault();
}
}

function draw() {
// video.elt.currentTime = i/frameRate;
video.loadPixels();
let color = [
video.pixels[(myY*video.width*4*density) + (myX*4*density)], // get red
video.pixels[(myY*video.width*4*density) + (myX*4*density + 1)], // get green
video.pixels[(myY*video.width*4*density) + (myX*4*density + 2)] // get blue
];

rect(i % framesPerDay * dotSize, rowNumber * dotSize, dotSize, dotSize);
fill(color);
colNumber += 1;
if (i % framesPerDay == 0) {
rowNumber += 1; // new row
colNumber = 0;
}
if (i == steps) i = 0;
else i++;
}

</script>


<div id="video"></div>
<div id="canvas"></div>
</body>
</html>
47 changes: 47 additions & 0 deletions prototype.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { createCyclogramCanvas, drawCyclogram } from "./modules/cyclogram.js";
import { loadVideo } from "./modules/video.js";

let processedVideoResponse = {};
let framesPerDay = 288/2; // remove nighttime hours, crudely
let dotSize = 6;
let i = 0;
let rowNumber = 0;
let colNumber = 0;

new p5(function(p5) {
p5.setup = function() {
const canvasOptions = {
width: 1000,
height: 400,
element: 'canvas',
};
createCyclogramCanvas(p5, canvasOptions);

const url = '../assets/river.mp4';
const loadOptions = { url, element: 'video' };
processedVideoResponse = loadVideo(p5, loadOptions);
}

p5.draw = function() {
const { video, frameRate, steps, density, x, y } = processedVideoResponse;
if (video) {
const drawOptions = {
video,
frameRate,
steps,
density,
myX: x || 100,
myY: y || 400,
framesPerDay,
dotSize,
i,
rowNumber,
colNumber,
};
const cyclogramResults = drawCyclogram(p5, drawOptions);
i = cyclogramResults.i;
rowNumber = cyclogramResults.rowNumber;
colNumber = cyclogramResults.colNumber;
}
}
});