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();
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With