Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pixelated resize using canvas with transparent PNG

I want to accomplish a pixelated effect using the canvas option imageSmoothingEnabled=false; so the image "unblurs" on scroll.

Everything works fine until using transparent images namely PNGs. The scaled image is projected, which stays in the background.

Also the image does not get loaded until the user has scrolled a few pixels.

I've found out that the canvas.drawImage() function owns parameters to set the offset. However I haven't found a solution to this.

Demo https://jsfiddle.net/aLjfemru/

var ctx = canvas.getContext('2d'),
  img = new Image(),
  play = false;

/// turn off image smoothing - this will give the pixelated effect
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;


/// wait until image is actually available
img.onload = function(){
                image1.src="nf.png";

                context.drawImage(image1, 50, 50, 10, 10);
                };

img.src = 'https://upload.wikimedia.org/wikipedia/commons/b/bb/Gorgosaurus_BW_transparent.png';

/// MAIN function
function pixelate(v) {
  document.getElementById("v").innerHTML = "(v): " + v;

  /// if in play mode use that value, else use slider value
  var size = v * 0.01;

  var w = canvas.width * size;
  var h = canvas.height * size;

  /// draw original image to the scaled size
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(img, 0, 0, w, h);
  ctx.drawImage(canvas, 0, 0, w, h, 0, 0, canvas.width, canvas.height);
}

function onScroll() {
  $(window).on('scroll', function() {
    var y = window.pageYOffset;
    if (y > 10) {
      y = Math.pow(y, 0.8);
      if (y >= 60) {
        y = 100;
      }
      pixelate(y);
    }
  });
}
onScroll();
like image 378
form.follows.function Avatar asked Oct 21 '25 09:10

form.follows.function


1 Answers

Some quick changes to get it happening

Use a second canvas to do the pixelation

Wait for the images to load before doing the rendering.

The onscroll will not fire until you scroll, so when image has loaded call the rendering function to display the image.

canvas.width = innerWidth-20;
ctx = canvas.getContext("2d");
var ctxImage;
const img = new Image;
img.src = 'https://upload.wikimedia.org/wikipedia/commons/b/bb/Gorgosaurus_BW_transparent.png';
/// wait until image is actually available
img.onload = function(){
     // I dont knwo what this is for so removed the following two lines
    //image1.src="nf.png"; 
    //context.drawImage(image1, 50, 50, 10, 10);
    // Create a canvas to match the image
    var c = document.createElement("canvas");
    canvas.width = Math.min(canvas.width,(c.width = this.naturalWidth));
    canvas.height = c.height = this.naturalHeight;
    ctxImage = c.getContext("2d");
    // changing canvas size resets the state so need to set this again.
    ctx.imageSmoothingEnabled = false;
    onScroll();
    pixelate(100); // call first time
};

ctx.font = "32px arial";
ctx.textAlign = "center";
ctx.fillText("Loading please wait.",ctx.canvas.width /2, ctx.canvas.height / 4);
/// MAIN function
function pixelate(v) {
  document.getElementById("v").innerHTML = "(v): " + v;

  /// if in play mode use that value, else use slider value
  var size = Number(v) * 0.01;

  var w = img.width * size;
  var h = img.height * size;

 
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctxImage.clearRect(0, 0, ctxImage.canvas.width, ctxImage.canvas.height);
  ctxImage.drawImage(img, 0, 0, w, h);
  ctx.drawImage(ctxImage.canvas, 0, 0, w, h, 0, 0, canvas.width, canvas.height);
}

function onScroll() {
  addEventListener("scroll", function() {

    var y = window.pageYOffset;
    if (y > 10) {
      y = Math.pow(y, 0.65);
      if (y >= 100) {
        y = 100;
      }
      pixelate(y);
    }
  });
      
}
#fix {
      position: fixed;
    }

    html {
      height: 2000px;
    }
<div id="fix">
<p id="v" value="Animate">1</p><br />

<canvas id="canvas"></canvas>
</div>
like image 148
Blindman67 Avatar answered Oct 23 '25 23:10

Blindman67



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!