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
22 changes: 22 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
The MIT License

Copyright (c) 2010-2018 Google, Inc. http://angularjs.org

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pixelate.js
===

**pixelate.js** is a simple library and jQuery plugin to pixelate any set of images and optionally reveal them on hover.
**pixelate.js** is a simple standalone library in pure Javascript and jQuery plugin to pixelate any set of images and optionally reveal them on hover.

[Demo here](http://43081j.github.io/pixelate/)

Expand All @@ -19,14 +19,14 @@ document.querySelector('img').pixelate();
Or via HTML data attributes:

```html
<img src="test.jpg" width="200" height="200" data-pixelate>
<img src="test.jpg" alt="" data-pixelate>
```

Options
===

* `value` The percentage of pixelation to perform, a value between `0` and `1`
* `reveal` Reveal the image on hover and remain revealed if clicked
* `value` The percentage of pixelation to perform, a value between `0` and `1`, with `1` being no pixelation and `0` being maximum pixelation.
* `reveal` Reveal the image on hover and remain revealed if clicked.
* `revealonclick` Reveal the image on click. When combined with `reveal`, it will remain revealed after being clicked.

These options may be specified by data tags, like so:
Expand Down
100 changes: 67 additions & 33 deletions dist/pixelate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,115 @@
* pixelate.js
* 43081j
* Pixelate images with ease
* v0.5
* License: MIT
*/
(function(window, $) {
var pixelate = function() {
var pixelate = function(args) {
// Parameters
var defaults = {
value: 0.05,
reveal: true,
revealonclick: false
value: 0.05, // pixelation "density" (1 = no pixelation, 0 = all pixelated into 1 pixel)
reveal: true, // reveal on hover
revealonclick: false // reveal on click
};
var options = arguments[1] || {};
// Get the current object (img)
var element = this, //arguments[0],
elementParent = element.parentNode;
if(typeof options !== 'object') {
options = { value: parseInt(arguments[1]) };
// Input arguments
var input_options = args || {};
if(typeof input_options !== 'object') {
input_options = { value: parseInt(arguments[1]) };
}
// Function/object that will merge and store all options (priority to html attributes, then to user-specified arguments, then to defaults
options = (function() {
var opts = {};
for(var k in defaults) {
// HTML attribute
if(element.hasAttribute('data-' + k)) {
opts[k] = element.getAttribute('data-' + k);
continue;
}
if(k in options) {
opts[k] = options[k];
continue;
}
opts[k] = defaults[k];
// User-specified argument
} else if (k in input_options) {
opts[k] = input_options[k];
// Defaults (fallback if there is nothing else)
} else {
opts[k] = defaults[k];
}
}
return opts;
})();
// Get image size
var display = element.style.display,
imgWidth = element.width,
imgHeight = element.height,
revealed = false;
var canv = document.createElement('canvas');
canv.width = imgWidth;
canv.height = imgHeight;
var ctx = canv.getContext('2d');
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
// Create two canvas (one temporary to downscale, and one final to upscale)
var canvtmp = document.createElement('canvas'); // temporary downscaling canvas
canvtmp.width = imgWidth;
canvtmp.height = imgHeight;
var canvpix = document.createElement('canvas'); // final upscaling canvas
canvpix.width = imgWidth;
canvpix.height = imgHeight;
var contexttmp = canvtmp.getContext('2d');
contexttmp.mozImageSmoothingEnabled = false;
contexttmp.webkitImageSmoothingEnabled = false;
contexttmp.imageSmoothingEnabled = false;
var contextpix = canvpix.getContext('2d');
contextpix.mozImageSmoothingEnabled = false;
contextpix.webkitImageSmoothingEnabled = false;
contextpix.imageSmoothingEnabled = false;
// Compute the downsampling width and height
var width = imgWidth * options.value,
height = imgHeight * options.value;
ctx.drawImage(element, 0, 0, width, height);
ctx.drawImage(canv, 0, 0, width, height, 0, 0, canv.width, canv.height);
// Downsampling (reduce image size, to create the pixels)
contextpix.clearRect(0, 0, canvpix.width, canvpix.height); // clear temporary canvas to avoid overlapping multiple times the same downsampled image, blurrying the contours
contexttmp.drawImage(element, 0, 0, width, height);
// Upsample back to original size (using another canvas to avoid issues with transparent images, which will leave the temporary canvas as a small icon in the upper left corner)
contextpix.clearRect(0, 0, canvpix.width, canvpix.height); // clear the canvas to avoid overlapping multiple times same image (particularly when using reveal option)
contextpix.drawImage(canvtmp, 0, 0, width, height, 0, 0, canvpix.width, canvpix.height);
// Reinsert image back in place (we hide the old and place a new one instead)
element.style.display = 'none';
elementParent.insertBefore(canv, element);
elementParent.insertBefore(canvpix, element);
// Manage user interaction: reveal on hover or on click
if(options.revealonclick !== false && options.revealonclick !== 'false') {
/*
* Reveal on click
*/
canv.addEventListener('click', function(e) {
canvpix.addEventListener('click', function(e) {
revealed = !revealed;
if(revealed) {
ctx.drawImage(element, 0, 0, imgWidth, imgHeight);
// On reveal, show the original image
contextpix.clearRect(0, 0, canvpix.width, canvpix.height); // clear
contextpix.drawImage(element, 0, 0, imgWidth, imgHeight);
} else {
ctx.drawImage(element, 0, 0, width, height);
ctx.drawImage(canv, 0, 0, width, height, 0, 0, canv.width, canv.height);
// On unreveal, recompute the pixelation
contexttmp.clearRect(0, 0, canvpix.width, canvpix.height); // clear
contexttmp.drawImage(element, 0, 0, width, height); // downsample using temporary canvas
contextpix.clearRect(0, 0, canvpix.width, canvpix.height); // clear
contextpix.drawImage(canvtmp, 0, 0, width, height, 0, 0, canvpix.width, canvpix.height); // upsample
}
});
}
if(options.reveal !== false && options.reveal !== 'false') {
/*
* Reveal on hover
*/
canv.addEventListener('mouseenter', function(e) {
canvpix.addEventListener('mouseenter', function(e) {
if(revealed) return;
ctx.drawImage(element, 0, 0, imgWidth, imgHeight);
// On reveal, show the original image
contextpix.clearRect(0, 0, canvpix.width, canvpix.height); // clear
contextpix.drawImage(element, 0, 0, imgWidth, imgHeight);
});
canv.addEventListener('mouseleave', function(e) {
canvpix.addEventListener('mouseleave', function(e) {
if(revealed) return;
ctx.drawImage(element, 0, 0, width, height);
ctx.drawImage(canv, 0, 0, width, height, 0, 0, canv.width, canv.height);
// On unreveal, recompute the pixelation
contexttmp.clearRect(0, 0, canvpix.width, canvpix.height); // clear
contexttmp.drawImage(element, 0, 0, width, height); // downsample using temporary canvas
contextpix.clearRect(0, 0, canvpix.width, canvpix.height); // clear
contextpix.drawImage(canvtmp, 0, 0, width, height, 0, 0, canvpix.width, canvpix.height); // upsample
});
}
};
// Add prototype function to all objects (so that we can call img.pixelate())
window.HTMLImageElement.prototype.pixelate = pixelate;
if(typeof $ === 'function') {
$.fn.extend({
Expand All @@ -88,6 +121,7 @@
}
});
}
// Add HTML attribute callback
document.addEventListener('DOMContentLoaded', function(e) {
var img = document.querySelectorAll('img[data-pixelate]');
for(var i = 0; i < img.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion pixelate.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.