Another no SVG piece that extends the earlier example. In this case, the zoomed image has a border so that users aren't confused about the transparent parts of a PNG image not responding to a mouseout event. It also includes a select element populated by the same data array that was used to build the gallery and which lets you zoom to the row containing the image you select.
Last active
August 29, 2015 14:00
-
-
Save emeeks/11336107 to your computer and use it in GitHub Desktop.
Dynamic Image Gallery with Zoom To Select Element
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title>D3 in Action Gallery Example 2</title> | |
<meta charset="utf-8" /> | |
</head> | |
<script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script> | |
<script src="http://d3js.org/colorbrewer.v1.min.js"></script> | |
<style> | |
div.gallery { | |
position: relative; | |
} | |
img.infinite { | |
position: absolute; | |
background: rgba(255,255,255,0); | |
border-width: 1px; | |
border-style: solid; | |
border-color: rgba(0,0,0,0); | |
} | |
</style> | |
<body onload="galleryExample2()"> | |
<div id="controls"> | |
</div> | |
</body> | |
<footer> | |
<script> | |
function galleryExample2() { | |
imageArray = []; | |
d3.select("#controls").append("canvas").attr("height", 500).attr("width", 500); | |
var context = d3.select("canvas").node().getContext("2d"); | |
context.textAlign = "center"; | |
context.font="200px Georgia"; | |
colorScale = d3.scale.quantize().domain([0,1]).range(colorbrewer.Reds[7]); | |
lineScale = d3.scale.quantize().domain([0,1]).range([10,40]); | |
for (var x=0;x<100;x++) { | |
context.clearRect(0,0,500,500); | |
context.strokeStyle = colorScale(Math.random()); | |
context.lineWidth = lineScale(Math.random()); | |
context.fillStyle = colorScale(Math.random()); | |
context.beginPath(); | |
context.arc(250,250,200,0,2*Math.PI); | |
context.fill(); | |
context.stroke(); | |
context.fillStyle = "black"; | |
context.fillText(x,250,280); | |
var dataURL = d3.select("canvas").node().toDataURL(); | |
imageArray.push({x: x, data: dataURL}); | |
} | |
d3.select("canvas").remove(); | |
d3.select("#controls") | |
.append("div").attr("class", "gallery") | |
.selectAll("img").data(imageArray).enter().append("img") | |
.attr("class", "infinite") | |
.attr("src", function(d) {return d.data}) | |
.on("mouseover", highlightImage) | |
.on("mouseout", dehighlightImage) | |
redrawGallery(); | |
function highlightImage(d) { | |
var newWidth = parseFloat(d3.select("div.gallery").node().clientWidth); | |
var imageSize = newWidth / 8; | |
d3.select(this).transition().duration(500).style("width", imageSize * 2) | |
.style("background", "rgba(255,255,255,1)") | |
.style("border-color", "rgba(0,0,0,1)"); | |
this.parentNode.appendChild(this) | |
} | |
function dehighlightImage(d) { | |
var newWidth = parseFloat(d3.select("div.gallery").node().clientWidth); | |
var imageSize = newWidth / 8; | |
d3.select(this).transition().duration(500).style("width", imageSize) | |
.style("background", "rgba(255,255,255,0)") | |
.style("border-color", "rgba(0,0,0,0)") | |
} | |
function redrawGallery() { | |
var newHeight = parseFloat(d3.select("div.gallery").node().clientHeight); | |
var newWidth = parseFloat(d3.select("div.gallery").node().clientWidth); | |
var imageSize = newWidth / 8; | |
d3.selectAll("img") | |
.style("width", newWidth / 8) | |
.style("top", function(d) {return Math.floor(d.x / 8) * imageSize}) | |
.style("left", function(d) {return d.x%8 * imageSize}) | |
} | |
window.onresize = function(event) { | |
redrawGallery(); | |
} | |
d3.select("div.gallery").style("height", "50%").style("overflow","scroll").style("border", "2px black solid") | |
d3.select("#controls").append("select") | |
//.attr("onchange", function (d) {return "zoomTo("+d.x+")"}) | |
.on("change", zoomTo) | |
.selectAll("option").data(d3.selectAll("img").data()).enter().append("option").attr("value", function(d) {return d.x}).html(function(d) {return "Image #" +d.x}) | |
function zoomTo() { | |
var selectValue = d3.select("select").node().value; | |
var newWidth = parseFloat(d3.select("div.gallery").node().clientWidth); | |
var imageSize = newWidth / 8; | |
var scrollTarget = Math.floor(selectValue / 8) * imageSize; | |
d3.selectAll("img").filter(function(d) {return d.x == selectValue}) | |
.transition().duration(2000).style("width", imageSize * 2) | |
.style("background", "rgba(255,255,255,1)") | |
.style("border-color", "rgba(0,0,0,1)"); | |
var selectedNode = d3.selectAll("img").filter(function(d) {return d.x == selectValue}).node(); | |
selectedNode.parentNode.appendChild(selectedNode); | |
d3.select("div.gallery").transition().duration(2000) | |
.tween("scrollTween", scrollTopTween(scrollTarget)); | |
function scrollTopTween(scrollTop) { | |
return function() { | |
var i = d3.interpolateNumber(this.scrollTop, scrollTop); | |
return function(t) { this.scrollTop = i(t); }; | |
}; | |
} | |
} | |
} | |
</script> | |
</footer> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment