How to create block at a given mouse position

1,284 views
Skip to first unread message

Sergey Batalov

unread,
Mar 27, 2016, 3:40:01 AM3/27/16
to Blockly
Hi!

I'd like to create a block as a result of a 'drop' mouse event (the drag begins outside of blockly) and struggling with a couple of problems.

First, when I'm creating a block with workspace.newBlock() or Blockly.Xml.domToBlock() and then programmatically select it using block.select(), the block is created just fine and is highlighted visually, but pressing Del (or Backspace etc) does not work. I have to click on the block with mouse to be able to delete it.

More importantly, I can not figure out how to convert coordinates of the 'drop' mouse event to SVG coordinates so that block can be positioned near mouse pointer. I tried Blockly.mouseToSvg(event, workspace.getParentSvg()), fiddled with matrixTransform etc to no avail. Ideally, if the block happen to be near other block where it can be plugged in, it should be plugged automatically. It seems that what I described is already implemented somewhere in Blockly. Are there some Blockly helper methods to achieve this?

Thank you.

Brian Pratt

unread,
Jul 7, 2017, 4:57:22 PM7/7/17
to Blockly
Did you figure this out?  I'm stuck at the exact same place.

Thanks,
Brian

Rachel Fenichel

unread,
Jul 7, 2017, 9:54:11 PM7/7/17
to Blockly
Hi Brian,

This pull request on Scratch Blocks may help you get unstuck: https://github.com/LLK/scratch-blocks/pull/1001

I think about coordinate problems in terms of the following:
1. Screen coordinates--I usually think of them in client coordinates.  Specifically, the offset to the top left of the injection div.  These are in pixels.
2. Workspace coordinates.  Where blocks are on the workspace.  You can call block.getRelativeToSurfaceXY() to get the position of a block in workspace coordinates.
  - Workspace units may be different from pixels if the workspace is scaled
  - The workspace coordinate system has an origin that is originally at the top left corner of the workspace.  This origin moves relative to the injection div as you scale and scroll the workspace.
3. Workspace offset.  The offset from the origin of the workspace to the top left corner of the injection div in pixels.
  - Here's a helper function to get that offset.  I'm adding it to Blockly as well, but it isn't in yet.
4. MouseEvent coordinates.  I usually use clientX and clientY, which are in pixels.

Hope that helps,
Rachel

Sergey Batalov

unread,
Jul 7, 2017, 11:02:36 PM7/7/17
to Blockly
Thanks, Rachel.

Brian Pratt

unread,
Jul 10, 2017, 9:20:16 AM7/10/17
to Blockly
Thanks, that helped!  Using your helper functions, I just store the last place clicked on.  Then in the .paste method, use those coordinates instead of what was in the clipboard xml.  

Here is what I did:
Blockly.WorkspaceSvg.prototype.onMouseDown_ = function(e) {
// ... removed code
 
// Save off the mouse coordinates for other people to use
 
var point = Blockly.mouseToSvg(e, this.getParentSvg(),  this.getInverseScreenCTM());
 
var rel = this.getOriginOffsetInPixels();
 
this.mouseX = (point.x - rel.x) / this.scale;
 
this.mouseY = (point.y - rel.y) / this.scale;
// ... rest of function

Reply all
Reply to author
Forward
0 new messages