Eu2019
Eu2019

Reputation: 81

how to center the canvas created through javascript to the center of the screen

There's no div with the id of canvas, is all rendered through javascript. and with this method (this is reused code from other codePens) I'm not sure how to center the canvas created in view. It gets resized based on the browser size, but I need the image to be always in the center of the window based on the entire clientWidth. not sure how to do that within this code.

let img;
const detail = 1;
let particles = [];
let particleImage;
let ctx;
function preload() {
  img = loadImage('https://uploads-ssl.webflow.com/60e7fc673c4aab21388ab7a6/60f1ddf63d26403634b61e99_daniel3.jpg');
}

class Particle {
  constructor (x, y) {
    this.x = x || random(width);
    this.y = y || random(height);
    this.prevX = this.x;
    this.speed = 0;
    this.v = random(0, 0.7);
  }
  
  update (speed) {
    if (grid.length) {
      this.speed = grid[floor(this.y / detail)][floor(this.x / detail)] * 0.97;
    }
    this.x += (1 - this.speed) * 3 + this.v;
    
    if (this.x > width) {
      this.x = 0;
    }
  }
  
  draw () {
    image(particleImage, this.x, this.y);
  }
}

/* ====== STEP 6 ====== */
function goToStep6 () {
  ctx.globalAlpha = 1;
  loop();
  image(img, 0, 0, width, height);
  loadPixels();
  clear();
  noStroke();
  
  grid = [];
  for (let y = 0; y < height; y+=detail) {
    let row = [];
    for (let x = 0; x < width; x+=detail) {
      const r = pixels[(y * width + x) * 4];
      const g = pixels[(y * width + x) * 4 + 1];
      const b = pixels[(y * width + x) * 4 + 2];
      const _color = color(r, g, b);
      const _brightness = brightness(_color) / 100;
      row.push(_brightness);
    }
    grid.push(row);
  }
  
  particles = [];
  for (let i = 0; i < 3000; i++) {
    particles.push(new Particle(null, (i/3000) * height));
  }
}

function step6 () {
  ctx.globalAlpha = 0.05;
  fill(31,36,67);
  rect(0,0,width,height);
  ctx.globalAlpha = 0.2;
  particles.forEach(p => {
    p.update();
    ctx.globalAlpha = p.speed * 0.3;
    p.draw();
  });
}

function setup () {
  const canvas = createCanvas(100,100);
  ctx = canvas.drawingContext;
  
  pixelDensity(1);
  
  particleImage = createGraphics(8, 8);
  particleImage.fill(255);
  particleImage.noStroke();
  particleImage.circle(4, 4, 4);
  
  windowResized();
  if (window['goToStep' + 6]) {
    window['goToStep' + 6]();
  }
  draw();
}

function windowResized () {
  let imgWidthNew = img.clientWidth;
  const imgRatio = img.width/img.height;
  if (windowWidth/windowHeight > imgRatio) {
    resizeCanvas(floor(windowHeight * 4,5), floor(windowHeight));
    ctx.fillRect(100,100,canvas.width,canvas.height);
  } else {
    resizeCanvas(floor(windowHeight * 4,5), floor(windowHeight));
  }
  noiseSeed(random(100));
  if (window['goToStep' + 6]) {
    window['goToStep' + 6]();
  }
  draw();
}

function draw () {
  window['step' + 6]();
}
body {
  margin: 0;
  overflow: hidden;
  background:rgba(31,36,67,1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

And the access to the Codepen https://codepen.io/kubographics/pen/abWdeLo

Upvotes: 0

Views: 246

Answers (1)

Kaiido
Kaiido

Reputation: 136698

I I understand correctly, what you want is to draw this image using a "cover" object-fit value.
The can also have such an object-fit CSS property set on it, but that would mean you'd be drawing many pixels that won't be seen ever.

So instead, you may prefer to set the canvas size to the window's size, and manipulate the call to image() so that it fits correctly.
Ken Fyrstenberg, (a.k.a epistemex) which used to be an SO user already provided the code to do this object-fit "cover" in this Q/A, I am thus reusing it, after simply changing the variable names so they're more readable.

The other change in your code is obviously in the windowResized event handler, which now only calls resizeCanvas with the window's innerWidth and innerHeight.

let img;
const detail = 1;
let particles = [];
let particleImage;
let ctx;
function preload() {
  img = loadImage('https://uploads-ssl.webflow.com/60e7fc673c4aab21388ab7a6/60f1ddf63d26403634b61e99_daniel3.jpg');
}

class Particle {
  constructor (x, y) {
    this.x = x || random(width);
    this.y = y || random(height);
    this.prevX = this.x;
    this.speed = 0;
    this.v = random(0, 0.7);
  }
  
  update (speed) {
    if (grid.length) {
      this.speed = grid[floor(this.y / detail)][floor(this.x / detail)] * 0.97;
    }
    this.x += (1 - this.speed) * 3 + this.v;
    
    if (this.x > width) {
      this.x = 0;
    }
  }
  
  draw () {
    image(particleImage, this.x, this.y);
  }
}

/* ====== STEP 6 ====== */
function goToStep6 () {
  ctx.globalAlpha = 1;
  loop();

  const
    imgWidth = img.width,
    imgHeight = img.height,
    ratio = Math.min(width / imgWidth, height / imgHeight);
  let
    newWidth = imgWidth * ratio,   // new prop. width
    newHeight = imgHeight * ratio,   // new prop. height
    sourceX, sourceY, sourceWidth, sourceHeight,
    aspectRatio = 1;

  // decide which gap to fill    
  if (newWidth < width) {
    aspectRatio = width / newWidth;
  }
  if (Math.abs(aspectRatio - 1) < 1e-14 && newHeight < height) {
    aspectRatio = height / newHeight;
  }
  newWidth *= aspectRatio;
  newHeight *= aspectRatio;

  // calc source rectangle
  sourceWidth = imgWidth / (newWidth / width);
  sourceHeight = imgHeight / (newHeight / height);

  sourceX = (imgWidth - sourceWidth) / 2;
  sourceY = (imgHeight - sourceHeight) / 2;

  // make sure source rectangle is valid
  if (sourceX < 0) sourceX = 0;
  if (sourceY < 0) sourceY = 0;
  if (sourceWidth > imgWidth) sourceWidth = imgWidth;
  if (sourceHeight > imgHeight) sourceHeight = imgHeight;

  // of course P5.js inverted the parameters...
  image(img, 0, 0, width, height, sourceX, sourceY, sourceWidth, sourceHeight);

  loadPixels();
  clear();
  noStroke();
  
  grid = [];
  for (let y = 0; y < height; y+=detail) {
    let row = [];
    for (let x = 0; x < width; x+=detail) {
      const r = pixels[(y * width + x) * 4];
      const g = pixels[(y * width + x) * 4 + 1];
      const b = pixels[(y * width + x) * 4 + 2];
      const _color = color(r, g, b);
      const _brightness = brightness(_color) / 100;
      row.push(_brightness);
    }
    grid.push(row);
  }
  
  particles = [];
  for (let i = 0; i < 3000; i++) {
    particles.push(new Particle(null, (i/3000) * height));
  }
}

function step6 () {
  ctx.globalAlpha = 0.05;
  fill(31,36,67);
  rect(0,0,width,height);
  ctx.globalAlpha = 0.2;
  particles.forEach(p => {
    p.update();
    ctx.globalAlpha = p.speed * 0.3;
    p.draw();
  });
}

function setup () {
  const canvas = createCanvas(100,100);
  ctx = canvas.drawingContext;
  
  pixelDensity(1);
  
  particleImage = createGraphics(8, 8);
  particleImage.fill(255);
  particleImage.noStroke();
  particleImage.circle(4, 4, 4);
  
  windowResized();
  if (window['goToStep' + 6]) {
    window['goToStep' + 6]();
  }
  draw();
  goToStep6();
}

function windowResized () {
  resizeCanvas(window.innerWidth, window.innerHeight);
  noiseSeed(random(100));
  goToStep6();
  draw();
}

function draw () {
  step6();
}
body {
  margin: 0;
  overflow: hidden;
  background:rgba(31,36,67,1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

Upvotes: 1

Related Questions