jquery set mouse position inside a <div> graphic area - javascript

using http://www.flotcharts.org/ to realize a complex scatterplot graphic with zoom/pan functionalities, i would like to set mouse position at specific coordinates (by example: when doing a zoom in, I would like that cursor would positioned at the center of canvass).
It ssem this function doesn't work:
function setMousePosition(pos) {
var x = pos.x;
var y = pos.y;
var pointX = ( Math.floor(plot.offset().left + plot.p2c(pos).left) );
var pointY = ( Math.floor(plot.offset().top + plot.p2c(pos).top) );
$("#placeholder").mouseXPos( pointX ).`mouseYPos`( pointY );
About mouseXPos and mouseYPos, firebug say:
TypeError: placeholder.mouseXPos is not a function
So my question is: there is a way in javascript or jquery to set mouse coordinates inside a graphic area ?

The mouse position cannot be set/changed via JavaScript.

There is no any mechanism to place a cusror to specific position programmatically in Javascript

Related

PIXI JS - I want to change Width/height and Position of Rectangle with Mouse

var rectangle = new Graphics();
rectangle.beginFill(0, 0.001);
rectangle.lineStyle(1, 0xFF0000);
rectangle.drawRect(5, 5, 200, 100);
rectangle.interactive = true;
rectangle.buttonMode = true;
rectangle.on('pointerdown', onDragStart)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd)
.on('pointermove', onDragMove);
app.viewport.addChild(rectangle);
I'm using this code to create a rectangle and adding it to rectangle. This is the onDragMove Function
function onDragMove() {
if (this.dragging) {
const newPosition = this.data.getLocalPosition(this.parent);
this.width = newPosition.x;
this.height = newPosition.y;
}
}
This is basically changing its width and height, but I also want to Drag the Rectangle when clicked inside the rectangle and dragged on the screen. Any suggestions how can I achieve this?
Borders to change width/height
clicking inside rectangle to drag on the screen.
I created working example of dragging and resizing: https://www.pixiplayground.com/#/edit/SbpTjm7WKXbL51kmiG89W - please check.
when you click near bottom border of rectangle (+/- 20 px) then you will start resizing it.
when you click in any other place inside rectangle then you will drag it
Basing on this example i think you can implement resizing of other borders of rectangle etc :)
One note: please look at function drawRectangle :
function drawRectangle(rectangle)
{
rectangle.clear();
rectangle.beginFill(0, 0.001);
rectangle.lineStyle(1, 0xFF0000);
rectangle.drawRect(rectangle.myRectanglePosition[0], rectangle.myRectanglePosition[1], rectangle.myRectanglePosition[2], rectangle.myRectanglePosition[3]);
}
^ the rectangle.clear(); is called to redraw the PIXI.Graphics object. So on each frame we clear and draw it again on specific position with specific width & height.

Gravity Points not working properly with other elements

There's this awesome codepen called Gravity Points which I liked very much and wanted to use on my next project but it turns out it only works well if it is the only element on the page. Once you start adding content above and below it, it miscalculates the mouse position.
Take a look at my fork here, I've added the content above it. Notice if the canvas is aligned perfectly with the screen, the gravity points are created in the right spot but if you click on the canvas when you're half way scrolled up, the points are created a few pixels down.
I'm not great with javascript and jquery, although I'm able to understand which functions it's calling and which functions are being used to draw the points but I can't understand where the calculations are happening and how it's related to scroll position. This functions seems to be triggered when left clicked but where does the cursor coordinates come from?
function mouseDown(e) {
for (var i = gravities.length - 1; i >= 0; i--) {
if (gravities[i].isMouseOver) {
gravities[i].startDrag(mouse);
return;
}
}
gravities.push(new GravityPoint(e.clientX, e.clientY, G_POINT_RADIUS, {
particles: particles,
gravities: gravities
}));
}
So can someone take a look at it and give some insights?
<canvas> element has its own coordinate system, which differs from the document one (the one sent by mouseEvents).
What you need to do is to check canvas's bounding box and remove its offset to your mouseEvents coordinates :
canvas.onmousemove = function(mouseEvent){
var rect = canvas.getBoundingClientRect();
var x = mouseEvent.clientX - rect.left;
var y = mouseEvent.clientY - rect.top;
// doSomething with x and y
for (var i = gravities.length - 1; i >= 0; i--) {
if (gravities[i].isMouseOver) {
gravities[i].startDrag(mouse);
return;
}
}
gravities.push(new GravityPoint(x, y, G_POINT_RADIUS, {
particles: particles,
gravities: gravities
}));
}

SVG: Scale one element of group from specified anchor point

OK, so I have a group of four elements rotating 90 degrees as I want them to, around an origin point in the middle of the four elements.
I would like to scale the top left block before and after spinning as well, outward from said origin point, but I'm having much difficulty doing so.
Here is a fiddle for my sample (read: overly simplified) progress so far:
http://jsfiddle.net/Vac2Q/2843/
The fiddle's javascript:
/* create an svg drawing */
var draw = SVG('drawing')
/* draw rectangle */
var dial = draw.circle(60)
.move(125,125)
.fill('#0099ff')
var rect_yellow = draw.rect(50,50)
.move(100,100)
.fill('gold')
var rect_blue = draw.rect(50,50)
.move(160,100)
.fill('navy')
var rect_black = draw.rect(50,50)
.move(160,160)
.fill('black')
var rect_green = draw.rect(50,50)
.move(100,160)
.fill('green')
var blades = draw.group()
.add(rect_yellow)
.add(rect_blue)
.add(rect_black)
.add(rect_green)
.back()
var angle = 0
var rotation = 90
var spin = document.getElementById('spin')
var spun = 0
/* make rectangle jump and change color on mouse over */
spin.addEventListener('click', function() {
/* calculate new ending orientation for blades */
angle += rotation
var new_rotate = angle
/* rotate the blade group */
blades.animate(1000, '>')
.rotate(new_rotate, 155, 155)
++spun
})
And here is a slightly more glamorous example of what I'm trying to do re: scaling:
The first issue is being able to determine which blade is in the top left position after a given rotation. The second issue is scaling itself; I've gotten the blade to scale, but then it goes crazy and moves off the screen at the same time. I'm not sure how to get it to scale properly from the specified origin point (the middle of the center circle).
You can use the .after() function to chain animations.
I'm not sure if I am using svg.js correctly, but here's what I did:
var rects = [rect_yellow, rect_green, rect_black, rect_blue];
// define the animations
var enlarge_blade = function() {
rects[spun % 4].animate(250, '<')
.scale(1.25, 1.25)
.translate(-38,-38);
};
function spin_anim() {
rects[spun % 4].animate(250, '>')
.scale(1, 1)
.translate(0,0)
.after(rotate_blades);
};
var rotate_blades = function() {
blades.animate(1000, '>')
.rotate(angle, 155, 155)
.after(function() {
++spun;
enlarge_blade();
title.text('spun ' + spun + ' times');
});
};
// Pre-enlarge the first (yellow) rect
enlarge_blade();
/* make rectangle jump and change color on mouse over */
spin.addEventListener('click', function() {
angle += rotation
spin_anim();
})
Demo here
I see you're using svg.js. I don't know how it treats transforms internally. But in any case. To scale an element, you typically use its center point as a reference. Therefore you should find the center point of each rect and scale it using that point. (I assume svg.js performs the required translation internally).

mouseOver in Highcharts

I have a chart. There is no mouseOver event in chart options, but I need to get mouse coordinates when I move cursor. For example, I want to show coordinates on xAxis and yAxis. Is it possible?
You can catch mousevent on the div which contain highcharts.
http://jsfiddle.net/5KHaj/2/
$('#highcharts-0').mouseover(function(e){
$('#report').html(e.clientX + ' ' + e.clientY);
});
Get the normal mouse coordinates then calculate the relative position.
document.body.onmousemove = function (event) {
var x = event.target.x - <your_chart_element>.getBoundingClientRect().left
var y = event.target.y - <your_chart_element>.getBoundingClientRect().top
}

Interspersing KineticJS and jQuery events

I am looking to build a simple photo collage using KineticJS and Canvas. In the canvas container, I have pre-defined image areas. I also have (in the DOM and outside of the canvas container), a strip of images which I want to drag and drop to the image wells on the canvas. I am able to drag an image and snap it to a (hard-coded) image well but while the image is moving on canvas I'm unable to get the x and y co-ordinates. I've tried using jQuery's drag/drag event but then it is blind to the canvas and I've tried to use use the KineticJS's dragover function but then I can't get the DOM image's x and y. The idea is that knowing the x,y of the image being dragged I can write some logic to figure out which image location it should get snapped to - as opposed to hard coding it's target.
Is it even possible to do this with KineticJS+jQuery - drag images from a DOM onto a canvas and have them snap into pre-defined image areas? Or, is there a simpler way?
as far as I understand your problem, I tried to reproduce it, but not seeing any difficulties
<div width="600" height="500" style="background-color:green;padding-left:60px" id="wrap">
<canvas id="a" width="300" height="225" style="background-color:yellow"></canvas>
</div>
<img id="dragMe" src="http://www.linuxmint.com/img/logo.png"/>
<div id="log">
<span class="a"></span>
<span class="b"></span>
<span class="c"></span>
<span class="d"></span>
</div>
$("#wrap").mousemove(function(e){
var pageCoords = "( " + e.pageX + ", " + e.pageY + " )";
var clientCoords = "( " + e.clientX + ", " + e.clientY + " )";
$("#log > span.a").text("( e.pageX, e.pageY ) : " + pageCoords);
$("#log > span.b").text("( e.clientX, e.clientY ) : " + clientCoords);
});
var p = $('#a').position();
$("#dragMe").draggable({
drag: function(event, ui) {
$("#log > span.c").text( ui.offset.left+':' +ui.offset.top);
$("#log > span.d").text( ( ui.offset.top-p.top)+':' +(ui.offset.left - p.left));
}
});
http://jsfiddle.net/agj3N/1/
When I asked you if you had a reason you had the strip of images outside of the KineticJS stage, you answered:
Only because when I toJSON it (for saving and calling up for a future edit), I just want the images on my photo collage and not the photos on the strip.
My answer to this is:
You don't have to use toJSON on the entire stage.
If you separate the Photo Strip (previously outside of the canvas) into a different layer from the Collage (previously inside the canvas, then you can have two layers and use toJSON on only one of those layers!
The result will be that toJSON will only serialize the objects from that given layer, which sounds like what you need.
jsfiddle - here is an example to illustrate what I mean, excuse my poor logic for snapping the image to the group. I have 2 layers: photoStripLayer and collageLayer
Click on the Collage toJSON button. Notice the console.log output does not include any of the images. This is because collageLayer only has a group inside it that has a child rectangle.
Drag the first yoda (top left, the rest don't work this is just an example) into the red box. Sorry you'll have to play around with this to get it to snap properly (I'm assuming you have your "snap" code already)
On dragend if the Yoda node is inside the red box, it will use KineticJS' moveTo function to move the yoda from the photoStripLayer --> collageLayer. You'll know it worked when the Yoda snaps to position (0,0) relative to the new group.
Now Click on the Collage toJSON button. Notice that the yoda image is now a part of the toJSON console.log output. The yoda was moved to the new group, which is a child of collageLayer. Now part of the collageLayer, Yoda is.
Here's the dragend code:
node.on('dragend', function () {
var pos = stage.getMousePosition();
var X = pos.x;
var Y = pos.y;
var minX = snap.getX();
var maxX = snap.getX() + snap.getWidth();
var minY = snap.getY();
var maxY = snap.getY() + snap.getHeight();
if (node.getX() < minX) {
node.moveTo(snap);
node.setX(0);
node.setY(0);
}
if (node.getX() > maxX) {
node.moveTo(snap);
node.setX(0);
node.setY(0);
}
if (node.getY() < minY) {
node.moveTo(snap);
node.setX(0);
node.setY(0);
}
if (node.getY() > maxY) {
node.moveTo(snap);
node.setX(0);
node.setY(0);
}
photoStripLayer.draw();
collageLayer.draw();
});
And the button click code to illustrate using toJSON:
function collageToJSON() {
var cjson = collageLayer.toJSON();
console.log(cjson);
/* To illustrate, you can also call toDataURL here. But in JSFiddle I think it throws a Security Error.
collageLayer.toDataURL({
callback: function(dataUrl) {
window.open(dataUrl);
}
});
*/
}
document.getElementById('CtoJSON').addEventListener('click', function () {
collageToJSON();
});
And there you have it! The issue is solved by letting KineticJS handle the entire process.

Categories