KineticJS - update text layer with new mouse position - mouseevent

I am using the following to get the mouse position:
var coordinate = 0;
............
canvas1.addEventListener('mousemove', function (evt) {
var mousePos = getMousePos(canvas1, evt);
var nY = Math.round(mousePos.y);
var nX = Math.round(mousePos.x);
coordinate = "x=" + nX + ", y=" + nY;
$('#pValue').val(coordinate);
}, false);
It works great if I display the value in a text field; however I could not update a text layer:
dlayerA1Text = new Kinetic.Layer();
var simpleTextRight = new Kinetic.Text({
x: lOffset + (lOffset * 0.25),
y: 15,
text: coordinate,
fontSize: 12,
fontFamily: 'Calibri',
fill: 'white',
align: 'left'
});

[Edited – again! Sorry about my incomplete answer last night – I was sleepy!]
To get a Kinetic Text to display coordinates of mouse movements on the stage…
The stage itself does not emit mouse events, but we can use stage.getContent to get the stage’s DIV so we can listen for mouse events on that div:
$(stage.getContent()).on('mousemove', function(event){ onMousemove(event)});
Then in the onMousemove handler, we can get the coordinate of the mouse on the stage:
var pos=stage.getMousePosition();
var mouseX=parseInt(pos.x);
var mouseY=parseInt(pos.y);
And finally we update the kinetic text to show that coordinate:
simpleTextRight.setText("Mouse: x="+mouseX+", y="+mouseY);
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/KamDV/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.3-beta.js"></script>
<style>
#container{ border:solid 1px #ccc; margin-top: 10px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
// create a stage and a layer
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);
// a kinetic text object to display coordinates
var mouseToText=new Kinetic.Text({
x:20,
y:30,
fontFamily:"Arial",
fontSize:18,
fill:"blue",
stroke:null,
text:"Mouse position"
});
layer.add(mouseToText);
// Start listening to mousemove events
// The stage does not emit mouse events
// So stage.getContent() will get a reference to the stage <div>
// This will let us get mouseevents even on areas not filled with kinetic nodes
$(stage.getContent()).on('mousemove', function(event){ onMousemove(event)});
// on mousemove...
// Find the current mouse position
// Update the kinetic text for the new coordinate
// And redraw the layer
function onMousemove(event) {
// Find the position of the mouse relative to the stage
var pos=stage.getMousePosition();
mouseX=pos.x;
mouseY=pos.y;
// update the kinetic text with the current coordinate
mouseToText.setText("Mouse: x="+mouseX+", y="+mouseY);
// draw the layer with the new text
layer.drawScene();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>

This was very helpful.
However, the latest version of kinetic.js no longer has 'getMousePosition', they are using the 'getPointerPosition'.
Which is nice, because I could not get hand.js to work with kinetic.js. Appears they already thought of that.

Related

symfony 3.3 saving latitude and longutude google maps API

I'm using google maps API and I need to save the position of each user after they select it by dragging the marker, knowing that they will be changing it from their profile and not an update page.
So basically I need to save the lat and lng of the user in the table right after they move marker, I haven't found a proper solution since we usually have regular forms with submit buttons to update. So here's the google maps div from the twig
<div id="map-canvas" style="width: 500px; height: 380px"></div>
<script src="https://maps.googleapis.com/maps/api/js?key="
type="text/javascript"></script>
<script>
var map = new google.maps.Map(document.getElementById('map-canvas'),{
center:{
lat: 45,
lng: 45
},
zoom:15
});
var marker = new google.maps.Marker({
position:{
lat: 45,
lng: 45
},
map: map,
draggable: true
});
google.maps.event.addListener(marker,'dragend',function () {
var lat = marker.getPosition().lat();
var lng = marker.getPosition().lng();
$('#lat').val(lat);
$('#lng').val(lng);
})
</script>
and here's the controller for the profil page
public function showEtabbAction(){
$em = $this->getDoctrine()->getManager();
$etab = $this->getUser()->getEtablissement();
$userNom = $this->getUser()->getNom();
return $this->render('#AllforkidsUser/Etablissement/etab.html.twig',array("etablissement"=>$etab,"nom"=>$userNom));
}
and thanks
Put two hidden fields in your form and then on dragend map event, set the value of this hidden fields from the marker position. Then you can handle the request as a regular form.

Greensock Animation Platform - is it possible to reverse nested timelines?

Is it possible to reverse a master timeline within GSAP? I know you can reverse a timeline that is not nested.
Here's the code:
// hide copy content divs
const hideCopyContentDivsTl = new TimelineMax()
hideCopyContentDivsTl.to(copyContentDivs, 1, {
height: 0,
width: 0,
autoAlpha: 0
})
// shrink copy wrapper div
const shrinkCopyWrapperTL = new TimelineMax()
shrinkCopyWrapperTL.to(copyWrapperDiv, 1, {
width: '2%',
height: '4%'
})
// fade remove bg and change to white
const fadeLargeBgImgTl = new TimelineMax()
fadeLargeBgImgTl.to(largeImage, 1, {
backgroundColor: "#fff"
})
// the master timeline to manage the parts
const masterTimeline = new TimelineMax({paused: true})
masterTimeline.add(hideCopyContentDivsTl)
.add(shrinkCopyWrapperTL)
.add(fadeLargeBgImgTl)
// assume that there is a mechanism to change the state of playVideo between true and false
if (this.state.playVideo === false) {
console.log("should play: ", masterTimeline)
masterTimeline.play()
} else {
console.log("should reverse: ", masterTimeline)
masterTimeline.reverse()
}
I can get it to play forwards, just not in reverse. Do I need to tell the browser where to start in the timeline so that it can play in reverse?
The problem is with my code and not with GSAP. I have new timelines created on every click. How will it reverse something that it doesn't have a previous reference to? The solution would be to create the timelines outside of the click event and then based on the state, play forward or reverse the animation.

Animate DIV to another DIV position

I can't figure out how to animate my DIV so that it goes to the #slot1 position (and later any slot I choose).
Here is my javascript code and the fiddle
$(function (){
$('#deck').click(function (){
var slotPos = $('#slot1').position();
$(this).animate({left: slotPos.left}, 400);
});
});
http://jsbin.com/ejeweb/4/
Thanks in advance!
$(#slot1 ).position()
function giving the relative position w.r.t to
<div id='head'>
container. So you can try below code. And use accordingly it:
$(function (){
$('#deck').click(function (){
var slotPos = $('#slot1').position(),
hand=$("#hand").position();
$("#deck").animate({
left: 10+hand.left+slotPos.left,
top:10 + hand.top},
400);
})
}
);
Let me know if this works for you!

Cropping PhantomJS screen capture sized to content

PhantomJS is doing a great job of capturing web pages into image files for me. I am using a script based on rasterize.js.
However, for certain web elements of a fixed size, I need the resulting image to match the size of the web element.
e.g. I have a page like this:
<html>
<body>
<div id="wrapper" style="width:600px; height:400px;">
Content goes here...
</div>
</body>
</html>
In this example, I need it to produce an image sized at 600x400. Is thre a way to get the viewport size dynamically based on a web element in the page I am rasterizing.
I know this one is not a easy one... Ideas?
Thanks
Wow. Not that hard after all. Just set the viewport really big and use the cropRect function. What a great tool!
Mods to rasterize.js:
page.open(address, function (status) {
if (status !== 'success') {
console.log('Unable to load the address!');
} else {
var height = page.evaluate(function(){
return document.getElementById('wrapper').offsetHeight;
});
var width = page.evaluate(function(){
return document.getElementById('wrapper').offsetWidth;
});
console.log('Crop to: '+width+"x"+height);
page.clipRect = { top: 0, left: 0, width: width, height: height };
window.setTimeout(function () {
page.render(output);
phantom.exit();
}, 200);
}
});

Mootools - detecting an instance of a css class

I have a website that I have added some basic Mootools animation to. Here is the page of the website i have a question on:
http://www.humsdrums.com/portfolio/webdesign.html
You will notice that when you mouse over the large images, they fade and a magnifying glass tweens down. Here is the Mootools class called "Magnify" I made for this:
var Magnify = new Class({
Implements : [Options, Events],
options : {
},
initialize : function (item, image, options)
{
this.setOptions(options);
this.div = document.id(item);
this.img = $$(image);
this.tweenBackground = new Fx.Tween(this.div,{
duration:'250',
property:'background-position'
});
this.div.addEvent('mouseenter', this.reveal.bind(this));
this.div.addEvent('mouseleave', this.hide.bind(this));
},
reveal : function()
{
this.tweenBackground.cancel();
this.tweenBackground.start('175px -78px', '175px 90px');
this.img.tween('opacity', .15);
console.log('mouse over');
},
hide :function ()
{
this.tweenBackground.cancel();
this.tweenBackground.start('175px 90px', '175px -78px');
this.img.tween('opacity', 1);
}
});
I then need to initialize an instance of the class for each element i want to do this by grabbing the css id.
window.addEvent('domready', function()
{
var magnify1 = new Magnify('p1', '#p1 img');
var magnify2 = new Magnify('p2', '#p2 img');
var magnify3 = new Magnify('p3', '#p3 img');
var magnify4 = new Magnify('p4', '#p4 img');
});
What I want to be able to do is simple give each element I want to have this functionality a CSS class of "magnify so I don't have to use individual ID's and add another instance of the Mootools class every time.
If I the element a CSS class and put it into my Mootools class, it breaks. Even if it didn't break, it seems like Mootools would simply make all elements with that CSS class animate at the same time when only one is moused over.
How would I detect which instance of the "magnify CSS class is being moused over? My only thoughts were to find a way to grab all the elements with the "magnify" CSS class, put them into an array and then check to see if the item being hovered over equals one of the items in the array. I don't know how to do that or if that is the best way.
Any help or suggestions would be great! Let me know if you want to see more code or if I can explain something better.
you need to code to patterns more. first of all - you have a relationship of 2 elements - a containing div and an image.
your event is actually on the parent el but you also need to reference and animate the inner element (the image).
your selector is simply div.item-port > img if you want to grab all images. div.item-port > img ! div.item-port will grab the parent divs instead of those that have an image as direct child only. etc.
then you need to decide what element to attach the event to. you have many choices in your markup.
before you even get there, you have a a href which wraps BOTH your elements. that allows you to use a cross-browser :hover pseudo.
you can very easily do in pure css:
div.port-item {
/* defaults you already have and then ... */
background-position: 175px -78px;
-webkit-transition: all 0.2s ease-out 0s;
-moz-transition: all 0.2s ease-out 0s;
-ms-transition: all 0.2s ease-out 0s;
-o-transition: all 0.2s ease-out 0s;
transition: all 0.2s ease-out 0s;
}
.portfolio-item a:hover div.port-item {
background-position: 175px 90px;
}
.portfolio-item a:hover img {
opacity: .15; // etc for cross-browser
}
only if you want to recover when the browser does not support transitions, you should instantiate your js class. http://jsfiddle.net/wMnzb/4/
var Magnify = new Class({
Implements: [Options],
options: {
parent: 'div'
},
initialize: function (images, options) {
this.setOptions(options);
this.elements = document.getElements(images);
this.attachEvents();
},
attachEvents: function () {
var selector = this.options.parent;
this.elements.each(function (el) {
var parent = el.getParent(selector);
parent.set('tween', {
duration: '250',
link: 'cancel'
});
parent.addEvents({
mouseenter: function () {
this.tween('background-position', '175px 90px');
el.fade(0.15);
},
mouseleave: function () {
this.tween('background-position', '175px -78px');
el.fade(1);
}
});
});
}
});
new Magnify('div.port-item > img');
simplified as much as is feasible, but you get the idea - completely ambiguous from ids and any such repetitive specificity.