Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get coordinates where mouse is/click #215

Open
JosephIsaacTurner opened this issue Feb 24, 2023 · 2 comments
Open

Get coordinates where mouse is/click #215

JosephIsaacTurner opened this issue Feb 24, 2023 · 2 comments

Comments

@JosephIsaacTurner
Copy link

Hi guys,

I am using Papaya to make a webpage where users can search based on coordinates.
A good example of something similar is neurosynth (https://neurosynth.org/locations/).
I want users to be able to search based on where they click on the papaya viewer. Just like the neurosynth viewer, which allows one to search based on the selected coordinate.

This is all straightforward.

I just want to know how to return the xyz coordinates where the user's mouse is hovering and/or where was last clicked.

It seems like it should be simple, because the papaya viewer always knows the coordinates of the mouse when you hover over the viewer (you can see at the bottom); I just don't know how to actually get those values and use them lol.

Thanks

@cynde
Copy link

cynde commented Mar 6, 2023

@JosephIsaacTurner is this what you're looking for? #166

@JosephIsaacTurner
Copy link
Author

I actually figured out a solution to my problem. I couldn't figure it out anywhere else, even on the page mentioned by @cynde.

There's a method called papaya.viewer.Viewer.prototype.getCurrentValueAt
This method calculates the coordinates in anatomical space, which is what I am trying to get.
The method itself is called by a few other methods. Importantly, whenever the screen is clicked, the
papaya.viewer.Viewer.prototype.drawViewer calls the papaya.viewer.Viewer.prototype.getCurrentValueAt method and displays the anatomical coordinates.

So, what I did was added a boolean parameter to the papaya.viewer.Viewer.prototype.getCurrentValueAt method, and whenever the papaya.viewer.Viewer.prototype.drawViewer calls the method, this parameter is set as true; whenever true, I change the value of an HTML attribute in my page to show the coordinates created by the papaya.viewer.Viewer.prototype.getCurrentValueAt method.

It might be easier to understand looking at my code for these methods:
I added the click parameter to this method, and put the coordinates myX, myY, and myZ into an HTML element called "selectedCorodinate". The click parameter is only true when it is called by the papaya.viewer.Viewer.prototype.drawViewer method, which only happens when users click on a coordinate. If you want to constantly update the coordinate position as users hover over coordinates (rather than just click) you would get rid of the click parameter.

This is what it looks like:

papaya.viewer.Viewer.prototype.getCurrentValueAt = function(x, y, z, click) {

// Check if viewer is in world space
if (this.worldSpace) {
    if(click){
    let myX = (x - this.volume.header.origin.x) * this.volume.header.voxelDimensions.xSize;
    let myY = (this.volume.header.origin.y - y) * this.volume.header.voxelDimensions.ySize;
    let myZ = (this.volume.header.origin.z - z) * this.volume.header.voxelDimensions.zSize;
    document.getElementById("selectedCoordinate").innerHTML = "<b>What's Here? Click to search:</b> <a href='" + `LesionProject.php?x=${myX}&y=${myY}&z=${myZ}` + "'>" + String(myX) + " " + String(myY) + " " + String(myZ) +"</a>";
    // console.log(
        //     (x - this.volume.header.origin.x) * this.volume.header.voxelDimensions.xSize,
        //     (this.volume.header.origin.y - y) * this.volume.header.voxelDimensions.ySize,
        //     (this.volume.header.origin.z - z) * this.volume.header.voxelDimensions.zSize,
        // );
    }
   
  // If in world space, get the voxel value at the given world coordinate in the current screen volume at the current timepoint
  return this.currentScreenVolume.volume.getVoxelAtCoordinate(
    (x - this.volume.header.origin.x) * this.volume.header.voxelDimensions.xSize,
    (this.volume.header.origin.y - y) * this.volume.header.voxelDimensions.ySize,
    (this.volume.header.origin.z - z) * this.volume.header.voxelDimensions.zSize,
    this.currentScreenVolume.currentTimepoint,
    false
  );
} else {
    if(click){
      let myX =  x * this.volume.header.voxelDimensions.xSize;
      let myY = y * this.volume.header.voxelDimensions.ySize;
      let myZ = z * this.volume.header.voxelDimensions.zSize;
      document.getElementById("selectedCoordinate").innerHTML = "<b>What's Here? Click to search:</b> <a href='" + `LesionProject.php?x=${myX}&y=${myY}&z=${myZ}` + "'>" + String(myX) + " " + String(myY) + " " + String(myZ) +"</a>";
      // console.log(
        //     x * this.volume.header.voxelDimensions.xSize,
        //     y * this.volume.header.voxelDimensions.ySize,
        //     z * this.volume.header.voxelDimensions.zSize
        // );
    }
    
  // If not in world space, get the voxel value at the given millimeter coordinate in the current screen volume at the current timepoint
  return this.currentScreenVolume.volume.getVoxelAtMM(
    x * this.volume.header.voxelDimensions.xSize,
    y * this.volume.header.voxelDimensions.ySize,
    z * this.volume.header.voxelDimensions.zSize,
    this.currentScreenVolume.currentTimepoint,
    false
  );
}

};

You can copy this snippet and replace the method in your version of papaya.js.

You will also want to change the method that calls it; The method is really big, and I made a minute change near the very end (see bold text):

papaya.viewer.Viewer.prototype.drawViewer=function(c,b){
var d="Yes"===this.container.preferences.radiological,
e="Yes"===this.container.preferences.showOrientation;
this.initialized?(this.context.save(),b?(this.axialSlice.repaint(this.currentCoord.z,c,this.worldSpace),
this.coronalSlice.repaint(this.currentCoord.y,c,this.worldSpace),
this.sagittalSlice.repaint(this.currentCoord.x,c,this.worldSpace)):
((c||this.draggingSliceDir!==papaya.viewer.ScreenSlice.DIRECTION_AXIAL)
&&this.axialSlice.updateSlice(this.currentCoord.z,c,this.worldSpace),
(c||this.draggingSliceDir!==papaya.viewer.ScreenSlice.DIRECTION_CORONAL)
&&this.coronalSlice.updateSlice(this.currentCoord.y,c,this.worldSpace),
(c||this.draggingSliceDir!==papaya.viewer.ScreenSlice.DIRECTION_SAGITTAL)
&&this.sagittalSlice.updateSlice(this.currentCoord.x,c,this.worldSpace)),
this.context.fillStyle=papaya.viewer.Viewer.BACKGROUND_COLOR,
"No"===this.container.preferences.smoothDisplay?(this.context.imageSmoothingEnabled=!1,
this.context.webkitImageSmoothingEnabled=!1,this.context.mozImageSmoothingEnabled=!1,this.context.msImageSmoothingEnabled=!1):
(this.context.imageSmoothingEnabled=!0,
this.context.webkitImageSmoothingEnabled=!0,
this.context.mozImageSmoothingEnabled=!0,
this.context.msImageSmoothingEnabled=!0),
this.context.setTransform(1,0,0,1,0,0),
this.context.fillRect(this.mainImage.screenOffsetX,this.mainImage.screenOffsetY,this.mainImage.screenDim,this.mainImage.screenDim),
this.context.save(),this.context.beginPath(),
this.context.rect(this.mainImage.screenOffsetX,this.mainImage.screenOffsetY,this.mainImage.screenDim,this.mainImage.screenDim),
this.context.clip(),
this.context.setTransform(this.mainImage.finalTransform[0][0],0,0,this.mainImage.finalTransform[1][1],this.mainImage.finalTransform[0][2],this.mainImage.finalTransform[1][2]),
this.context.drawImage(this.mainImage.canvasMain,0,0),
this.context.restore(),
this.mainImage.canvasDTILines
&&this.context.drawImage(this.mainImage.canvasDTILines,0,0),
this.container.orthogonal
&&(this.context.setTransform(1,0,0,1,0,0),
this.context.fillRect(this.lowerImageBot.screenOffsetX, this.lowerImageBot.screenOffsetY,this.lowerImageBot.screenDim,this.lowerImageBot.screenDim),
this.context.save(),
this.context.beginPath(),
this.context.rect(this.lowerImageBot.screenOffsetX,this.lowerImageBot.screenOffsetY,this.lowerImageBot.screenDim,this.lowerImageBot.screenDim),
this.context.clip(),
this.context.setTransform(this.lowerImageBot.finalTransform[0][0],0,0,this.lowerImageBot.finalTransform[1][1],this.lowerImageBot.finalTransform[0][2],this.lowerImageBot.finalTransform[1][2]),
this.context.drawImage(this.lowerImageBot.canvasMain, 0,0),
this.context.restore(),
this.lowerImageBot.canvasDTILines
&&this.context.drawImage(this.lowerImageBot.canvasDTILines,this.lowerImageBot.screenOffsetX,this.lowerImageBot.screenOffsetY),
this.context.setTransform(1,0,0,1,0,0),
this.context.fillRect(this.lowerImageTop.screenOffsetX,this.lowerImageTop.screenOffsetY,this.lowerImageTop.screenDim,this.lowerImageTop.screenDim),
this.context.save(),
this.context.beginPath(),
this.context.rect(this.lowerImageTop.screenOffsetX,this.lowerImageTop.screenOffsetY,this.lowerImageTop.screenDim,this.lowerImageTop.screenDim),
this.context.clip(),
this.context.setTransform(this.lowerImageTop.finalTransform[0][0],0,0,this.lowerImageTop.finalTransform[1][1],this.lowerImageTop.finalTransform[0][2],this.lowerImageTop.finalTransform[1][2]),
this.context.drawImage(this.lowerImageTop.canvasMain,0,0),
this.context.restore(),
this.lowerImageTop.canvasDTILines
&&this.context.drawImage(this.lowerImageTop.canvasDTILines,this.lowerImageTop.screenOffsetX,this.lowerImageTop.screenOffsetY)),
(e||d)&&this.drawOrientation(),
"None"!==this.container.preferences.showCrosshairs&&this.drawCrosshairs(),
"Yes"===this.container.preferences.showRuler&&this.drawRuler(),
this.container.display
&&this.container.display.drawDisplay(this.currentCoord.x,this.currentCoord.y,this.currentCoord.z,
this.getCurrentValueAt(this.currentCoord.x,this.currentCoord.y,this.currentCoord.z, true))):
this.drawEmptyViewer()
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants