skia2/experimental/webtry/res/imp/zoom.html
commit-bot@chromium.org 015c08e5ca Move zooming into its own component, imported via HTML Imports.
Also, start building our own polyfill library (polyfill.js) using Grunt and Bower.

Finally, refactor all the web pages so that the common header and footer material comes from templates.

BUG=skia:
R=mtklein@google.com

Author: jcgregorio@google.com

Review URL: https://codereview.chromium.org/292433002

git-svn-id: http://skia.googlecode.com/svn/trunk@14783 2bbb7eff-a529-9590-31e7-b0007b416f81
2014-05-19 16:40:08 +00:00

170 lines
6.0 KiB
HTML

<script type="text/javascript" charset="utf-8">
/**
* A reusable HTML Import to enable zooming on images.
*
* To use, simply include this HTML Import and add the class 'zoom' to any
* images you want zoomable.
*
* <link rel='import' type='text/html' href='/res/imp/zoom.html'>
*
* <img src="http://..." class="zoom"/>
*
* Any number of images on a page can be zoomable.
*
* If you want to display the rgb colors of the pixel at the center of the
* zoom then add an id of 'zoomHex' to any element that supports
* textContent, such as a div, p, span, etc.
*
* <p id=zoomHex></p>
*
* Note that HTML Imports need to be polyfilled in the near term.
*/
(function () {
function onLoad() {
var PIXELS = 20; // The number of pixels in width and height in a zoom.
var clientX = 0;
var clientY = 0;
var lastClientX = 0;
var lastClientY = 0;
var ctx = null; // The 2D canvas context of the zoom.
var currentImage = null; // The img node we are zooming for, otherwise null.
var hex = document.getElementById('zoomHex');
var canvasCopy = null;
function zoomMove(e) {
clientX = e.clientX;
clientY = e.clientY;
}
function zoomMouseDown(e) {
e.preventDefault();
// Only do zooming on the primary mouse button.
if (e.button != 0) {
return
}
currentImage = e.target;
clientX = e.clientX;
clientY = e.clientY;
lastClientX = clientX-1;
lastClientY = clientY-1;
document.body.style.cursor = 'crosshair';
canvas = document.createElement('canvas');
canvas.width = 1024;
canvas.height = 1024;
canvas.classList.add('zoomCanvas');
ctx = canvas.getContext('2d');
ctx.imageSmoothingEnabled = false;
this.parentNode.insertBefore(canvas, this);
// Copy the image over to a canvas so we can read RGBA values for each point.
if (hex) {
canvasCopy = document.createElement('canvas');
canvasCopy.width = currentImage.width;
canvasCopy.height = currentImage.height;
canvasCopy.id = 'zoomCopy';
canvasCopy.getContext('2d').drawImage(currentImage, 0, 0, currentImage.width, currentImage.height);
this.parentNode.insertBefore(canvasCopy, this);
}
document.body.addEventListener('pointermove', zoomMove, true);
document.body.addEventListener('pointerup', zoomFinished);
document.body.addEventListener('pointerleave', zoomFinished);
// Kick off the drawing.
setTimeout(drawZoom, 1);
}
function hexify(i) {
var s = i.toString(16).toUpperCase();
// Pad out to two hex digits if necessary.
if (s.length < 2) {
s = '0' + s;
}
return s;
}
function drawZoom() {
if (currentImage) {
// Only draw if the mouse has moved from the last time we drew.
if (lastClientX != clientX || lastClientY != clientY) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var x = clientX - currentImage.x;
var y = clientY - currentImage.y;
var dx = Math.floor(ctx.canvas.width/PIXELS);
var dy = Math.floor(ctx.canvas.height/PIXELS);
ctx.lineWidth = 1;
ctx.strokeStyle = '#000';
// Draw out each pixel as a rect on the target canvas, as this works around
// FireFox doing a blur as it copies from one canvas to another.
var colors = canvasCopy.getContext('2d').getImageData(x, y, PIXELS, PIXELS).data;
for (var i=0; i<PIXELS; i++) {
for (var j=0; j<PIXELS; j++) {
var offset = (j*PIXELS+i)*4; // Offset into the colors array.
ctx.fillStyle = 'rgba(' + colors[offset] + ', ' + colors[offset+1] + ', ' + colors[offset+2] + ', ' + colors[offset+3]/255.0 + ')';
ctx.fillRect(i*dx, j*dy, dx-1, dy-1);
// Box and label one selected pixel with its rgba values.
if (hex && i==PIXELS/2 && j == PIXELS/2) {
ctx.strokeRect(i*dx, j*dy, dx-1, dy-1);
hex.textContent = 'rgba('
+ colors[offset] + ', '
+ colors[offset+1] + ', '
+ colors[offset+2] + ', '
+ colors[offset+3] + ') '
+ hexify(colors[offset])
+ hexify(colors[offset+1])
+ hexify(colors[offset+2])
+ hexify(colors[offset+3]);
}
}
}
lastClientX = clientX;
lastClientY = clientY;
}
setTimeout(drawZoom, 1000/30);
}
}
function zoomFinished() {
currentImage = null;
if (hex) {
hex.textContent = '';
}
document.body.style.cursor = 'default';
ctx.canvas.parentNode.removeChild(ctx.canvas);
canvasCopy.parentNode.removeChild(canvasCopy);
document.body.removeEventListener('pointermove', zoomMove, true);
document.body.removeEventListener('pointerup', zoomFinished);
document.body.removeEventListener('pointerleave', zoomFinished);
}
var zoomables = document.body.querySelectorAll('.zoom');
for (var i=0; i<zoomables.length; i++) {
zoomables[i].addEventListener('pointerdown', zoomMouseDown);
}
}
// If loaded via HTML Imports then DOMContentLoaded will be long done.
if (document.readyState != "loading") {
onLoad();
} else {
this.addEventListener('DOMContentLoaded', onLoad);
}
})();
</script>
<style type="text/css" media="screen">
.zoom {
cursor: crosshair;
}
.zoomCanvas {
position: absolute;
width: vmin;
height: vmin;
top: 3em;
right: 1em;
z-index: -1;
}
#zoomCopy {
display: none;
}
#zoomHex {
text-shadow: 1px 1px #eee;
}
</style>