kineticjs stage.getAbsoluteMousePosition()? - label

I am playing with kineticjs with a draggable and zoomable stage and I'd like to know if there is a way to get the stage.getAbsoluteMousePosition() as we can have the absolutePosition of a Node.
Here is the jsfiddle showing a use case, note the position of the tooltip when you zoom in/out.
The interesting part is here:
circle.on('mouseover mousemove',function(){
var mousePos = stage.getMousePosition();
tooltip.setPosition(mousePos.x-stage.getAbsolutePosition().x,mousePos.y-stage.getAbsolutePosition().y);
tooltip.setVisible(true);
tooltip.moveToTop();
layer.draw();
});
I am having trouble to make it work and I believe with the getAbsoluteMousePosition would fix it.
Best,
Edit: This question is outdated.

Outdated Answer
Ok, fixed it myself even thought I don't use the absoluteposition I wanted to.
Here is the jsfiddle, the proper way of doing it was like this:
circle.on('mouseover mousemove', function () {
var mousePos = stage.getMousePosition();
tooltip.setPosition(mousePos.x/ui.scale-stage.getAbsolutePosition().x/ui.scale+stage.getOffset().x,
mousePos.y/ui.scale-stage.getAbsolutePosition().y/ui.scale+stage.getOffset().y);
tooltip.setVisible(true);
tooltip.moveToTop();
layer.draw();
});

If I understand correctly, if you want to get the absolute position of your mouse pointer to the screen this is how you could do it:
circle.on('mouseover mousemove', function (e) {
var mousePos = stage.getMousePosition();
var absoluteX = e.screenX;
var absoluteY = e.screenY;
tooltip.setPosition(mousePos.x - absoluteX, mousePos.y - absoluteY);
tooltip.setVisible(true);
tooltip.moveToTop();
layer.draw();
});
This doesn't solve your answer though as the (x,y) coordinate of the mouse should be relative to the canvas, not your screen. I'm not exactly sure why tooltip.setPosition(mousePos.x, mousePos.y); wouldn't work, the zoom must be messing up the mousePos coordinates relatively somehow.
Anyways, if you only need the tooltip to hover above the correct node, and not follow the mouse position, than this should work for you:
tooltip.setPosition(this.getX(), this.getY());
And if you need, you could offset it by a certain amount for example half the height (radius).
tooltip.setPosition(this.getX(), this.getY()-this.getHeight()/2);
http://jsfiddle.net/projeqht/nDpYr/

Related

d3.brush does not work in Firefox or Edge when embedded

I'm using the Swiper API. When there's any d3 Chart embedded, the brush receives senseless mouse coordinates, in any case not relative to the container where the click occurs. (That's in fact at least the surrounded svg.)
I'm trying to find a solution but I don't know how I can force d3.brushX to use mouse coordinates which are really relative.
I don't know whether this is a bug or not, it has probably not really to do with the brush itself, rather how the browser pass mouse clicks top-down the DIV's until the SVG will be reached.
Here's the Fiddle.
(just for the annoying code rule:)
// Add brushing
var brush = d3.brushX()
The second slide contains an embedded d3 line chart example, taken from here.
The fiddle works only in Chrome 75+.
Not in Firefox 68+ nor in Edge 44+.
Running the chart example standalone, it works in all available browsers. So I designate this post for Swiper and D3 hopefully to get a hint for an solution.
According to the problem here I found out, that I can change the behavior in the point.js routines an an workaround.
If a D3 chart makes use of an brush **and ** the SVG of the chart element is embedded by a surrounding DIV with an explicite width, mouse clicks will not be interpreted correctly in Firefox or Edge. In Chrome it works perfectly.
I changed the code like this to achieve that it works in FF and Edge, but lose functionality with Chrome:
function reverseTraversal(node,targetTagName) {
var p = node;
while(p.tagName != targetTagName) p = p.parentNode;
return p;
}
function point(node, event) {
var svg = node.ownerSVGElement || node;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
var p = reverseTraversal(node,"DIV");
var rect = p.getBoundingClientRect();
point.x = event.clientX + rect.width, point.y = event.clientY;
point = point.matrixTransform(node.getScreenCTM().inverse());
return [point.x, point.y];
}
var rect = node.getBoundingClientRect();
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
}
As you can see, I have to traverse backwards until the closest DIV will be reached, get the bounding and add its width to the clientX coordinate.
Without adding the fixed width, the brush is unusable in the particular case.
To get working with all the browsers, maybe a switch is necessary.
It's not a perfect solution, just a workaround for d3.brushX behavior.

Selecting part of circle

Before, there is image:
I am totally new in Titanim(Appcelerator). There is task: I must draw or import and select the definite regions of circle. When clicked, it must change colour. Your help will be appreciated.
With regards
Plz Keep two images one with new background and one with original background.Just change the image path and you would be good to go.Something like this
Ti.UI.backgroundColor = 'white';
var win = Ti.UI.createWindow();
var image = Ti.UI.createImageView({
image:'/images/myimage.png'
});
image.addEventListener('click',function(e){
image.image="images/newimage";
});
win.add(image);
win.open();

Focus/Context Brushing + Pan/Zoom graph - How to limit panning

I've managed to make a d3.js line+area graph sync with focus/context brushing and pan/zoom, with a small example here:
http://jsfiddle.net/MtXvx/8/
I'm having trouble limiting the panning to stop at the original domain boundaries, while also working nicely with the brush. This is to prevent users from losing the graph in their view.
While I have tried manually detecting when panning has exceeded boundaries and then setting zoom.translate([0,0]), such as in these examples:
d3.js scatter plot - zoom/drag boundaries, zoom buttons, reset zoom, calculate median
Limiting domain when zooming or panning in D3.js
d3.js scatter plot - zoom/drag boundaries, zoom buttons, reset zoom, calculate median
...as I do here at line 183:
//If exceed original domain, limit panning by resetting translate
if (x.domain()[0] < x0.domain()[0]) {
zoom.translate([0, 0]);
}
The problem occurs when:
1) Create a brush region in the small context graph
2) Pan the big focus graph all the way towards the earliest date
3) Graph jumps when panning is almost at the boundary
Would appreciate any help to prevent the jumping from happening, or if there is any other way to limit the panning (and eventually the zooming out too) to the original domain boundaries.
Regarding limiting the zoom-out, setting:
var zoom = d3.behavior.zoom().x(x).scaleExtent([1,10]).on("zoom", zoomed);
...does not work nicely because the zoom-out would be limited to the brush region instead of the full extent of the graph data.
Much thanks!
I had similar problems combining D3 Brushing and Zoom & Pan, but figured it out eventually. I found the key to limit the panning is to reset the translate of the zoom behavior object. Specifically, here is my zoom callback function:
function zoomed() {
var t = d3.event.translate;
var s = d3.event.scale;
var size = width*s;
t[0] = Math.min(t[0], 0);
t[0] = Math.max(t[0], width-size);
zoom.translate(t);
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
var brushExtent = [x.invert(0), x.invert(width)];
context.select(".brush").call(brush.extent(brushExtent));
}
While not part of your question, also an important part to make the whole demo work right is to update the zoom translate and scale when brushing is done, so here is my brushed callback:
function brushed() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
var s = x.domain();
var s_orig = x2.domain();
var newS = (s_orig[1]-s_orig[0])/(s[1]-s[0]);
var t = (s[0]-s_orig[0])/(s_orig[1]-s_orig[0]);
var trans = width*newS*t;
zoom.scale(newS);
zoom.translate([-trans,0]);
}
Here is a complete example based one of D3 examples: http://bl.ocks.org/sbreslav/be9af0d809b49864b7d8
to limit the extent of the panning on the graph you could use clamp, although I couldn't see where or if you were using a scale in that fiddle (actually it didn't appear to be working). Here's a simple example in a fiddle

HTML Canvas clip area - Context restore?

Am trying to set a "dirty zone" on my canvas to prevent the repainting of unmoved items (background image, static items, etc.)
i.e. only the background painted behind a moving player needs to be redrawn
EDIT: As suggested, here's the jsfiddle of it
http://jsfiddle.net/7kbzj/3/
The "update" method doesn't work out there, so it's moveSprite() you can get run by clicking the "move sprite" link... Basically, the clipping zone shouldmove by 10px to the right each time you click. Clipping mask stays at initial position, only the re-paint occurs. Weird o_O
So as I init my canvas, once the background is painted, set I use the ctx.save() method:
function init() {
canvas = document.getElementById('kCanvas');
ctx = canvas.getContext('2d');
ctx.fillStyle = "rgb(0,128,0)";
ctx.fillRect (0,0,320,240);
ctx.save();
setInterval(function () { update(); }, tpf);
}
In order to see the clipping works, I draw a different color background (blue one) in the area that I wanted clipped... the result is bad, only the first clipped area is painted blue :(
function update() {
setDirtyArea(x,y,w+1,h)
ctx.fillStyle = "rgb(0,0,128)";
ctx.fillRect (0,0,320,240);
x++;
// paint image
ctx.clearRect(x,y,w,h);
ctx.drawImage(imageObj, x, y);
}
function setDirtyArea(x,y,w,h) {
ctx.restore();
// define new dirty zone
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.clip();
}
I'd love to se the blue zone propagate itself towards the right of the screen... please help, I don't understand what's wrong!
Thanks,
J.
You need to wrap the actual drawing and clipping of the box with the save and restore methods. and include the closePath method. I have modified your fiddle to work the way I believe you are trying to make it.
http://jsfiddle.net/jaredwilli/7kbzj/7/
ctx.save(); // save the context
// define new dirty zone
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.clip();
ctx.restore(); // restore the context
I also have learned that using save and restore can get really complex, and confusing to know which context your in. It came up with a pretty huge canvas app im working on, and i found that indenting your canvas code helps immensely. Especially the save/restores. I have even decided it should be considered a best practice, so the more people who know and do it the better.
Hope this helps.

Raphael JS : mouseover/mouseout - problem with text-labels

I use Raphael JS to create an SVG-map with area's and textlabels. I want the area to highlight when you move the mouse over it.
I have this working now, but when I move the mouse over the label (in the center of the area) the mouseout-event for that area is triggered, so the area is unhighlighted again.
Is there any way to prevent this from happening, or a workaround ?
Create a rect with opacity set to 0 over the text and attach the event handlers on that rect. You can calculate the dimensions of the rect using getBBox() of the text.
Creating a set via Paper#set was the approach that worked for me. e.g.:
var st = paper.set();
st.push.apply(st, vectors); // `vectors`: my array of "hoverable" vectors
st.push(text); // `text`: my text vector for `vectors`
st.hover(function () {
text.show();
}, function () {
text.hide();
});

Resources