|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
<html xmlns="http://www.w3.org/1999/xhtml"> |
|
<head> |
|
<meta http-equiv="X-UA-Compatible" content="chrome=1" /> |
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
|
<title>d3 x3dom event test</title> |
|
<script type="text/javascript" src="http://x3dom.org/x3dom/dist/x3dom.js"></script> |
|
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> |
|
<link rel="stylesheet" type="text/css" href="http://www.x3dom.org/download/dev/x3dom.css"></link> |
|
</head> |
|
|
|
<body> |
|
<div id="divX3d"> |
|
<X3D xmlns="http://www.web3d.org/specifications/x3d-namespace" id="x3d" x="0px" y="0px" width="500px" height="500px"> |
|
<Scene> |
|
<Viewpoint centerOfRotation="0 0 0" position="0 0 15" orientation="0 1 0 0" /> |
|
<Background skyColor='.95 .95 .95' /> |
|
<Group> |
|
<Transform translation='-3 0 0'> |
|
<Shape> |
|
<Appearance> |
|
<Material diffuseColor="1 0 0" specularColor=".5 .5 .5" /> |
|
</Appearance> |
|
<Box id="Red cube"/> |
|
</Shape> |
|
</Transform> |
|
<Transform translation="0 0 0"> |
|
<Shape> |
|
<Appearance> |
|
<Material diffuseColor="0 0 1" specularColor=".5 .5 .5" /> |
|
</Appearance> |
|
<Sphere id="Blue sphere"/> |
|
</Shape> |
|
</Transform> |
|
<Transform translation="3 0 0"> |
|
<Shape> |
|
<Appearance> |
|
<Material diffuseColor="0 1 0" specularColor=".5 .5 .5" /> |
|
</Appearance> |
|
<Cone id="Green cone"/> |
|
</Shape> |
|
</Transform> |
|
<Transform translation="5 0 0"> |
|
<Billboard axisOfRotation="0 0 0"> |
|
<Shape> |
|
<Text solid="true" string="Click Me"> |
|
</Text> |
|
</Shape> |
|
</Billboard> |
|
</Transform> |
|
</Group> |
|
</Scene> |
|
</X3D> |
|
</div> |
|
|
|
<script type="text/javascript"> |
|
|
|
document.onload = function() |
|
{ |
|
// This will not work by itself because the x3d canvas captures onclick methods |
|
d3.select('Box').on('click', showAlertWithEventCoordinate) |
|
|
|
// This works. Note however that in the javascript string assigned to 'onclick', the function |
|
// forwardClick must be globally, not locally scoped. |
|
d3.select('Sphere').on('click', showAlertWithEventCoordinate) |
|
d3.select('Sphere').attr('onclick', "forwardClick(event)") |
|
|
|
// This works too. |
|
d3.select('Cone').node().addEventListener('click', showAlertWithEventCoordinate) |
|
d3.select('Text').node().addEventListener('click', showAlertWithEventCoordinate) |
|
|
|
function showAlertWithEventCoordinate(event) { |
|
var pagePt = invertMousePosition(event); |
|
alert(d3.select(event.target).attr('id') + ' picked at:\n' |
|
+ 'world coordinate (' + event.hitPnt + '),\n' |
|
+ 'canvas coordinate (' + event.layerX + ', ' + event.layerY + '),\n' |
|
+ 'page coordinate (' + pagePt.x + ', ' + pagePt.y + ')' ) |
|
} |
|
} |
|
|
|
// Call the 'click' handler with event. Note that event member variables differ from |
|
// what d3 expects. In particular d3.mouse() will not work. |
|
// |
|
function forwardClick(event) { |
|
d3.select(event.target).on('click')(event); |
|
|
|
// Is possible to instead construct a new event with members that d3 requires? e.g., |
|
//var e=document.createEvent('mouseEvent'); |
|
//var screenX = 0, screenY = 0; // TODO: compute |
|
//e.initMouseEvent('click', event.bubbles, event.cancelable, window, event.detail, |
|
// screenX, screenY, event.layerX, event.layerY, |
|
// event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.button, null); |
|
//d3.select(event.target).node().dispatchEvent(e); |
|
} |
|
|
|
// inverse of coordinate transform defined by function mousePosition(evt) in x3dom.js |
|
// |
|
function invertMousePosition(evt) |
|
{ |
|
var convertPoint = window.webkitConvertPointFromPageToNode; |
|
var pageX = -1, pageY = -1; |
|
if ( "getBoundingClientRect" in document.documentElement ) { |
|
var elem = d3.select('#divX3d').node(); |
|
console.log('elem:', elem) |
|
var box = elem.getBoundingClientRect(); |
|
var scrolleft = window.pageXOffset || document.body.scrollLeft; |
|
var scrolltop = window.pageYOffset || document.body.scrollTop; |
|
var paddingLeft = parseFloat(document.defaultView.getComputedStyle(elem, null).getPropertyValue('padding-left')); |
|
var borderLeftWidth = parseFloat(document.defaultView.getComputedStyle(elem, null).getPropertyValue('border-left-width')); |
|
var paddingTop = parseFloat(document.defaultView.getComputedStyle(elem, null).getPropertyValue('padding-top')); |
|
var borderTopWidth = parseFloat(document.defaultView.getComputedStyle(elem, null).getPropertyValue('border-top-width')); |
|
pageX = Math.round(evt.layerX + (box.left + paddingLeft + borderLeftWidth + scrolleft)); |
|
pageY = Math.round(evt.layerY + (box.top + paddingTop + borderTopWidth + scrolltop)); |
|
} else if (convertPoint) { |
|
var pagePoint = convertPoint(evt.target, new WebKitPoint(0, 0)); |
|
x = Math.round(point.x); |
|
y = Math.round(point.y); |
|
} else { |
|
x3dom.debug.logError('NO getBoundingClientRect, NO webkitConvertPointFromPageToNode'); |
|
} |
|
return { x: pageX, y: pageY }; |
|
} |
|
|
|
</script> |
|
</body> |
|
</html> |
Can you show how to add event listeners to a d3,selectAll() that returns shapes. Thanks!