Skip to content

Commit

Permalink
More bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
anvaka committed Jan 13, 2018
1 parent 9cbca97 commit 451a74f
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 35 deletions.
4 changes: 2 additions & 2 deletions config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ module.exports = {
*/

// https://webpack.js.org/configuration/devtool/#development
devtool: '#source-map',
devtool: 'source-map',

// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
Expand All @@ -51,7 +51,7 @@ module.exports = {

productionSourceMap: true,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
devtool: 'source-map',

// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
Expand Down
10 changes: 7 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</form>
<div class='file-picker'>
or
<input ref='localFile' type="file" id="local-files-button" class="nodisplay" name="files[]" multiple="" accept="image/*" @change='onFilePickerChanged'>
<input type='file' id='local-files-button' class='nodisplay' name="files[]" multiple="" accept="image/*" @change='onFilePickerChanged'>
<label class='browse-btn' for="local-files-button">select a local file</label>
</div>
</div>
Expand Down Expand Up @@ -49,15 +49,19 @@ export default {
},
methods: {
onSubmit() {
this.$refs.localFile.files = null;
sceneState.setImages([this.scene.image]);
},
onInputFocused(e) {
e.target.select();
this.inputSelected = true;
},
onFilePickerChanged(e) {
sceneState.setImages(e.target.files);
var files = e.target.files;
sceneState.setImages(files);
// Try to reset the type
e.target.type = 'input';
e.target.type = 'file';
//setTimeout(() => e.target.files = null, 10);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/About.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
<div class='content'>
<h3>Pixel Chart <a class='close bold' href='#' @click.prevent='close'>close</a></h3>
<p>
This website allows you to take any picture and split it thousands particles.
This website allows you to take any picture and split it into thousands particles.
The particles are arranged according to color intensities into a histogram.
</p>
<p>
The website was created in response to popular demand in <a href='https://www.reddit.com/r/dataisbeautiful/comments/7ol3gy/gaussian_distribution_oc/'>this reddit post.</a>
The website was created in response to <a href='https://www.reddit.com/r/dataisbeautiful/comments/7ol3gy/gaussian_distribution_oc/'>this reddit post.</a>
Thank you for the inspiration!
</p>
<ul>
Expand Down
12 changes: 9 additions & 3 deletions src/pixchart/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,13 @@ function pixChart(imageLink, options) {

gl.useProgram(screenProgram.program);

// gl.enable(gl.BLEND);
// gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
glUtils.bindAttribute(gl, particleInfoBuffer, screenProgram.a_particle, 4);

glUtils.bindTexture(gl, imgInfo.texture, 2);
gl.uniform1f(screenProgram.u_frame, currentFrameNumber);
gl.uniform1f(screenProgram.u_max_y_value, imgInfo.stats.maxYValue);
gl.uniform1f(screenProgram.u_alpha, 0.0);
gl.uniform4f(screenProgram.u_sizes, width, height, window.innerWidth, window.innerHeight);

gl.uniform1i(screenProgram.u_screen, 2);
Expand Down Expand Up @@ -166,8 +167,12 @@ function pixChart(imageLink, options) {

function startExpandCollapseCycle() {
if (disposed) return;
if (nextAnimationFrame) return; // already scheduled.
nextAnimationFrame = setTimeout(() => requestAnimationFrame(animate), 1000);
if (nextAnimationFrame || pendingTimeout) return; // already scheduled.

pendingTimeout = setTimeout(() => {
pendingTimeout = 0;
nextAnimationFrame = requestAnimationFrame(animate)
}, 1000);
}

function animate() {
Expand Down Expand Up @@ -216,6 +221,7 @@ function pixChart(imageLink, options) {
} else {
// drive it back to original state
pendingTimeout = setTimeout(() => {
pendingTimeout = 0;
nextAnimationFrame = requestAnimationFrame(animate);
}, 1000);
}
Expand Down
36 changes: 21 additions & 15 deletions src/pixchart/lib/createShaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ var vertexShader = `
uniform vec2 texture_resolution;
uniform float u_frame;
uniform float u_max_y_value;
uniform vec2 mouse_pos;
uniform vec4 u_sizes;
uniform float u_max_y_value;
// [0] is x coordinate of a particle
// [1] is y
Expand All @@ -32,44 +33,49 @@ var vertexShader = `
float ease(float t) {
return t < 0.5 ? 2. * t * t : -1. + (4. - 2. * t) * t;
}
const vec3 rand_constants = vec3(12.9898, 78.233, 4375.85453);
float rand(const vec2 co) {
float t = dot(rand_constants.xy, co);
return fract(sin(t) * (rand_constants.z + t));
}
void main() {
gl_PointSize = float(${pointSize});
vec2 texture_pos = vec2(
mod(a_particle[3], texture_resolution.x)/texture_resolution.x,
floor(a_particle[3] / texture_resolution.x)/(texture_resolution.y)
);
v_color = texture2D(u_screen, texture_pos);
vec2 source = vec2(
2. * texture_pos.x - 1.,
1. - 2.* texture_pos.y
);
float factor = min(1.0, min(u_sizes[3]/u_sizes[1], u_sizes[2]/u_sizes[0]));
source.x *= factor * u_sizes[0] / u_sizes[2];
source.y *= factor * u_sizes[1] / u_sizes[3];
// we don't want to make small images larger. That's why we pick minimum of 1.
// float factor = min(1.0, min(u_sizes[3]/u_sizes[1], u_sizes[2]/u_sizes[0]));
float factor = min(u_sizes[3]/u_sizes[1], u_sizes[2]/u_sizes[0]);
source *= factor * u_sizes.xy/u_sizes.zw;
vec2 target = vec2(
(2. * a_particle.x - 1.) * 0.9, // * factor * u_sizes[0]/u_sizes[2],
(1.75 * a_particle.y/u_max_y_value - .8) * 0.9
);
if (a_particle.x < 0.) {
// these particles are filtered out.
target.x = cos(atan(source.y, source.x)) * 2.;
target.y = sin(atan(source.y, source.x)) * 2.;
}
(2. * a_particle.x - 1.) * 0.9,
(2. * a_particle.y/(u_max_y_value) - 1.) * 0.9
) * factor * u_sizes.xy/u_sizes.zw;
float timeSpan = a_particle.z;
float t;
if (u_frame <= timeSpan) t = ease(u_frame/timeSpan);
else t = 1.;
if (a_particle.x < 0.) {
// these particles are filtered out.
target.x = source.x; //cos(atan(source.y, source.x)) * 2.;
target.y = source.y; //sin(atan(source.y, source.x)) * 2.;
v_color.a = 0.; //mix(0.1, 0., t);
//v_color = vec4(1.0, 0., 0., 1.);
}
gl_PointSize = max(1., ceil(factor)); float(${pointSize});
float tmin = 1. - t;
vec2 dest = tmin * source + t * target;
// vec2 dest = tmin * tmin * source + 2. * tmin * vec2(0.) * t + t * t * target;
Expand Down
13 changes: 13 additions & 0 deletions src/pixchart/lib/loadImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,25 @@ function loadImage(imageObject, scaleImage) {
// todo: remove dependency on window?
var sx = window.innerWidth/image.width;
var sy = window.innerHeight/image.height;
if (window.innerWidth < 400 || window.innerHeight < 400 && window.devicePixelRatio > 1) {
sx *= window.devicePixelRatio;
sy *= window.devicePixelRatio;
}
if (sx < sy) {
image.width *= Math.min(sx, 2);
image.height *= Math.min(sx, 2);
} else {
image.width *= Math.min(sy, 2);
image.height *= Math.min(sy, 2);
}

var maxPixels = 500000;
var ar = image.width/image.height;
var h0 = Math.sqrt(maxPixels * ar);
var w0 = maxPixels / h0;
if (h0 < image.height || w0 < image.width) {
image.width = h0;
image.height = w0;
}
}
}
21 changes: 12 additions & 9 deletions src/pixchart/lib/loadParticles.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ function loadParticles(image, options) {
function processPixels() {
var start = performance.now();
var currentYValue;
while (idx < 4*n) {
var r = pixels[idx + 0], g = pixels[idx + 1], b = pixels[idx + 2];
var pixelsCount = 4 * n;
while (idx < pixelsCount) {
var invIndex = pixelsCount - idx - 4;
var r = pixels[invIndex + 0], g = pixels[invIndex + 1], b = pixels[invIndex + 2];
var v = getValue(r, g, b);
// v ranges from 0 to 1.
var bucketNumber = Math.round(v * bucketsCount);
Expand All @@ -73,19 +75,20 @@ function loadParticles(image, options) {

currentYValue = bucketColors[bucketNumber] += 1;
// assign this pixel to this height in the bucket
var pixelIndex = idx/4;
var rnd = Math.random();// * Math.abs(0.5 -v);
particleInfo[idx + 0] = v;
particleInfo[idx + 1] = currentYValue - 1;
particleInfo[idx + 2] = framesCount - rnd * framesCount*0.75;
particleInfo[idx + 3] = pixelIndex;
particleInfo[idx + 3] = invIndex/4;

// if (v > 0.95) {
// // TODO: Proper ignore logic here.
// particleInfo[idx] = -1;
// } else
if (currentYValue > maxYValue) maxYValue = currentYValue;

idx += 4;
if (v === 0.) {
// TODO: Proper ignore logic here.
particleInfo[idx] = -1;
} else if (currentYValue > maxYValue) maxYValue = currentYValue;
if (performance.now() - start > 42) {
if (performance.now() - start > 12) {
scheduleWork();
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function initScene(canvas) {
cleanErrorClass = true;
progressElement.innerHTML = 'Could not load image :(. <br /> Try uploading it to <a href="https://imgur.com" target="_blank">imgur.com</a>?'
if (queue.length > 1) {
setTimeout(processNextInQueue, 500);
pendingTimeout = setTimeout(processNextInQueue, 500);
}
}

Expand All @@ -59,6 +59,7 @@ function initScene(canvas) {
currentPixChart.restartCycle()
return;
}

if (currentPixChart) {
currentPixChart.dispose();
}
Expand Down

0 comments on commit 451a74f

Please sign in to comment.