svg.js
svg.js copied to clipboard
Documentation: Basic Events should include example with mouseEvent and coordinate transform
This is the example given in the doc. It is way too spartanic and even omits all parameters passed to the click handler.
element.click(function() {
this.fill({ color: '#f06' })
})
Also the documentation does not give an example of how to transform the coordinates of the MouseEvent to the SVG-view-box coordinates, which is probably the standard case for using click events. So I have prepared an example for a standard use-case (after searching for the point() function for hours). It is a little bit elaborate, but that does not hurt, as it is almost a copy-paste solution. I hope this is a useful contribution.
Full Object-Oriented Example with coordinate transform:
class AddPointOnClickModelViewController {
constructor()
{
this.svg = SVG("#svgElement"); // this is our HTML svg drawing area (View of our MVC).
// We retrieve it by ID (for a Singleton)
// now we register the click handler to this instance
let me = this;
this.svg.click(function(mouseEvent) {
// mouseEvent is type MouseEvent with coordinates offsetX, offsetY relative to the top left of the svg dom element
// this is type SVG and is the clicked element
me.onClickSvg(this, mouseEvent); // forward to MC instance
});
}
onClickSvg(svg, mouseEvent)
{
// The global variable "event" declared at this point is the same as mouseEvent
let id = svg.attr().id; // svg and this.svg are the same
console.log("SVG element clicked has id:", id)
console.log("offsetX offsetY modifierKeys:", mouseEvent.offsetX, mouseEvent.offsetY, mouseEvent.shiftKey, mouseEvent.altKey, mouseEvent.metaKey);
// transform click location to viewbox coordinates
let { x, y } = svg.point(mouseEvent.pageX, mouseEvent.pageY);
console.log("Coordinates transformed:", x, y);
// add a circle at the clicked coordinates to the SVG-View
let newPoint = svg.ellipse([5,5]).cx(x).cy(y).fill("red").stroke({width:1, color: '#000'});
// at this point we could register a click-to-remove function on the circle/ellipse
// now you may want to store the new point in your data-model ...
}
In my opinion the function "point()" is misnamed. One expects a shape like line() not a transform. SVG.transformPageCoordinates() or transformMouseEventCoordinates() would be a great alias. Trading saved keystrokes for code understandability never appealed to me, otherwise nice library!
https://svgjs.dev/docs/3.1/events/#basic-events
Well :smiley:
element.click(function() {
this.fill({ color: '#f06' })
})
does seem a bit thin, compared to
class AddPointOnClickModelViewController {
constructor() {
this.svg = SVG("#svgElement"); // this is our HTML svg drawing area (View of our MVC).
// We retrieve it by ID (for a Singleton)
// now we register the click handler to this instance
let me = this;
this.svg.click(function (mouseEvent) {
// mouseEvent is type MouseEvent with coordinates offsetX, offsetY relative to the top left of the svg dom element
// this is type SVG and is the clicked element
me.onClickSvg(this, mouseEvent); // forward to MC instance
});
}
onClickSvg(svg, mouseEvent) {
// The global variable "event" declared at this point is the same as mouseEvent
let id = svg.attr().id; // svg and this.svg are the same
console.log("SVG element clicked has id:", id)
console.log("offsetX offsetY modifierKeys:", mouseEvent.offsetX, mouseEvent.offsetY, mouseEvent.shiftKey, mouseEvent.altKey, mouseEvent.metaKey);
// transform click location to viewbox coordinates
let { x, y } = svg.point(mouseEvent.pageX, mouseEvent.pageY);
console.log("Coordinates transformed:", x, y);
// add a circle at the clicked coordinates to the SVG-View
let newPoint = svg.ellipse([5, 5]).cx(x).cy(y).fill("red").stroke({ width: 1, color: '#000' });
// at this point we could register a click-to-remove function on the circle/ellipse
// now you may want to store the new point in your data-model ...
}
...