Implementing infinite animation in famousJS with StateModifier - scale

I want a circle to act like a heart does, a pulsing animation. So the circle first scales to 75%, then to 100%. I want to make this an infinite loop.
Code:
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Easing = require('famous/transitions/Easing');
var mainContext = Engine.createContext();
var surface = new Surface({
size: [180, 180],
properties: {
backgroundColor: 'grey',
borderRadius: '50%'
}
});
var stateModifier = new StateModifier();
stateModifier.setTransform(
Transform.scale(0.7, 0.7, 1),
{ duration : 1050 }
);
stateModifier.setTransform(
Transform.scale(1, 1, 1),
{ duration : 450 }
);
mainContext.add(stateModifier).add(surface);
Anyone knows how to implement this?

Use the callback and wrap the setTransform in a function to have each callback call each other when they finish.
Example running snippet
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Easing = require('famous/transitions/Easing');
var mainContext = Engine.createContext();
var surface = new Surface({
size: [180, 180],
properties: {
backgroundColor: 'grey',
borderRadius: '50%'
}
});
var stateModifier = new StateModifier();
function min() {
stateModifier.setTransform(
Transform.scale(0.7, 0.7, 1), {
duration: 1050
},
max
);
}
function max() {
stateModifier.setTransform(
Transform.scale(1, 1, 1), {
duration: 450
},
min
);
}
mainContext.add(stateModifier).add(surface);
surface.on('deploy', function() {
min();
});
});
require(['main']);
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

Related

Unable to draw a Curved Polyline using Here Maps JS Api

Unable to Draw a curved polyline using Here Maps JS API.
Trying to add the logic based on my previous findings.
It throws an error "Uncaught TypeError: arc.GreatCircle is not a constructor"
Any Suggestions on how to fix this ?
My Earlier Querstion
Here is my working JSFiddle which is trying to draw a curve to multiple spots.
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Europe
var map = new H.Map(document.getElementById('map'),
defaultLayers.vector.normal.map,{
center: {lat:52, lng:5},
zoom: 5,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
window.addEventListener('resize', function() { map.getViewPort().resize(); });
var npoints = 100,
offset = 20;
// Now use the map as required...
//addPolylineToMap(map);
// Berlin -> Chicago0
add([52.51607,13.37699],[41.88425,-87.63245], { style: { strokeColor : "#00FF00", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Tokyo -> san Francisco
add([35.68019,139.81194],[37.77712,-122.41964], {style: { strokeColor: "rgba(0,0,255,0.7)", lineWidth: 15, lineDash: [1], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Melbourne
add([52.51607,13.37699],[-37.81753,144.96715], { style: { strokeColor : "rgba(255,0,255,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Paris -> Paris -> London
add([52.51607,13.37699],[48.85721, 2.34144], { style: { strokeColor : "rgba(0,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
add([48.85721, 2.34144],[51.50643,-0.12721], { style: { strokeColor : "rgba(255,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
function add(s,e,options) {
var arc = {};
arc.Coord = Coord;
arc.Arc = Arc;
arc.GreatCircle = GreatCircle;
var start_ll = new H.geo.Point(s[0],s[1]),
end_ll = new H.geo.Point(e[0],e[1]),
start_coord = {x: start_ll.lng, y:start_ll.lat},
end_coord = {x:end_ll.lng, y:end_ll.lat};
description = ''+s[0]+','+s[1]+'=>'+e[0]+','+e[1]+'',
gc0 = new arc.GreatCircle(start_coord,end_coord, {'name': 'line', 'color':'#ff7200','description':description}),
line0 = gc0.Arc(npoints,{offset:offset}),
strip = line0.strip();
map.addObject(new H.map.Polyline(strip, options));
}
var D2R = Math.PI / 180;
var R2D = 180 / Math.PI;
var Coord = function(lon, lat) {
this.lon = lon;
this.lat = lat;
this.x = D2R * lon;
this.y = D2R * lat;
};
Coord.prototype.view = function() {
return String(this.lon).slice(0, 4) + ',' + String(this.lat).slice(0, 4);
};
Coord.prototype.antipode = function() {
var anti_lat = -1 * this.lat;
var anti_lon = (this.lon < 0) ? 180 + this.lon : (180 - this.lon) * -1;
return new Coord(anti_lon, anti_lat);
};
var LineString = function() {
this.coords = [];
this.length = 0;
};
LineString.prototype.move_to = function(coord) {
this.length++;
this.coords.push(coord);
};
var Arc = function(properties) {
this.properties = properties || {};
this.geometries = [];
};
Arc.prototype.json = function() {
if (this.geometries.length <= 0) {
return { 'geometry': { 'type': 'LineString', 'coordinates': null }, 'type': 'Feature', 'properties': this.properties };
} else if (this.geometries.length == 1) {
return { 'geometry': { 'type': 'LineString', 'coordinates': this.geometries[0].coords }, 'type': 'Feature', 'properties': this.properties };
} else {
var multiline = [];
for (var i = 0; i < this.geometries.length; i++) {
multiline.push(this.geometries[i].coords);
}
return { 'geometry': { 'type': 'MultiLineString', 'coordinates': multiline }, 'type': 'Feature', 'properties': this.properties };
}
};
Arc.prototype.strip = function() {
var s = H.geo.Strip ? new H.geo.Strip() : new H.geo.LineString();
for (var i = 0; i < this.geometries.length; i++) {
if (this.geometries[i].coords.lenght !== 0) {
var coords = this.geometries[i].coords;
for (var j = 0; j < coords.length; j++) {
var p = new H.geo.Point(coords[j][1], coords[j][0]);
s.pushPoint(p);
}
}
}
return s;
}
var GreatCircle = function(start, end, properties) {
if (!start || start.x === undefined || start.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
if (!end || end.x === undefined || end.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
this.start = new Coord(start.x, start.y);
this.end = new Coord(end.x, end.y);
this.properties = properties || {};
var w = this.start.x - this.end.x;
var h = this.start.y - this.end.y;
var z = Math.pow(Math.sin(h / 2.0), 2) + Math.cos(this.start.y) * Math.cos(this.end.y) * Math.pow(Math.sin(w / 2.0), 2);
this.g = 2.0 * Math.asin(Math.sqrt(z));
if (this.g == Math.PI) {
throw new Error('it appears ' + start.view() + ' and ' + end.view() + " are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite");
} else if (isNaN(this.g)) {
throw new Error('could not calculate great circle between ' + start + ' and ' + end);
}
};
#map {
width: 95%;
height: 450px;
background: grey;
}
<script src="https://heremaps.github.io/maps-api-for-javascript-examples/test-credentials.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Polyline on the Map</title>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<link rel="stylesheet" type="text/css" href="demo.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="../template.css" />
<script type="text/javascript" src='../test-credentials.js'></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
</head>
<body id="markers-on-the-map">
<div id="map"></div>
<script type="text/javascript" src='demo.js'></script>
</body>
</html>
this is simple: the var GreatCircle is not defined yet but program code invoke GreatCircle
We moved some parts of code through each together
but any way there is error GreatCircle doesn't have 'arc' property defined.
there is this module https://demo.support.here.com/javascripts/examples/v31/geodesic-polyline.js
but you needs Bézier curve: https://en.wikipedia.org/wiki/B%C3%A9zier_curve
I found some implementation on this https://habr.com/ru/post/163073/ - (but in russian) - there a curve consists from lines based on 100 points (step 0.01)
flow = getBezierCurve(new Array(arr[0], arr[1], arr[2], arr[3]), 0.01);
drawLines(ctx, flow, 10);
In JS API wasn't implemented functionality of like Bézier curve
but search in google on "bezier curve javascript example code" - if you get points of curve you can use in JS API map.screenToGeo every point and plot it on the map

Get position of famous `Draggable` after `on end` and until `Transition` ends

Using famous with meteor and famous-views but at it's core this is really a famous question —
How can I get the position of a Draggable modifier after the on end event and until it stops moving?
Eg. while it's bouncing into a given position what is it's position vector? How can I put this into a session var etc. or pipe it somewhere else?
Pure Famo.us Solution: Use the update and end events on a Draggable.
draggable.on('update', function (e) {
var pos = e.position;
// Use the updating position here
});
draggable.on('end', function (e) {
var pos = e.position;
// Use the final position here
});
As you can see from the snippet below, these two events will allow you to track the drag position. As you drag the surface, the other surface is transitioned to follow using the position of the Draggable.
Updated: returns to origin transform on drag end
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require('famous/modifiers/Draggable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
var mainContext = Engine.createContext();
var transTransform = new TransitionableTransform();
transTransform.set(Transform.translate(100, 0, 0));
var surface = new Surface({
size: [300, 100],
properties: {
backgroundColor: 'rgba(255,0,0,0.1)',
cursor: 'pointer'
}
});
var dragSurface = new Surface({
content: 'Drag Me',
size: [100, 100],
properties: {
backgroundColor: 'rgba(0,0,0,0.1)',
cursor: 'pointer'
}
});
var modifier = new Modifier({
origin: [0, 0],
align: [0, 0],
transform: transTransform
});
var draggable = new Draggable();
draggable.subscribe(dragSurface);
var content = 'Not Draggable';
surface.setContent(content);
mainContext.add(modifier).add(surface);
mainContext.add(draggable).add(dragSurface);
draggable.on('update', function (e) {
var pos = e.position;
surface.setContent('Draggable Position is '+pos);
transTransform.set(Transform.translate(pos[0]+100, pos[1], 0));
});
draggable.on('end', function (e) {
var pos = e.position;
surface.setContent('Draggable End Position is '+pos);
transTransform.setTranslate([100, 0, 0],{duration: 300});
this.setPosition([0,0],{duration: 300});
});
});
// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
Updated: A more loosely coupled example.
Emit an event object to an EventHandler to be able to listen for the custom event and use the object to apply your outside transition.
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require('famous/modifiers/Draggable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
var mainContext = Engine.createContext();
var transTransform = new TransitionableTransform();
transTransform.set(Transform.translate(100, 0, 0));
var surface = new Surface({
size: [300, 100],
properties: {
backgroundColor: 'rgba(255,0,0,0.1)',
cursor: 'pointer'
}
});
var dragSurface = new Surface({
content: 'Drag Me',
size: [100, 100],
properties: {
backgroundColor: 'rgba(0,0,0,0.1)',
cursor: 'pointer'
}
});
var modifier = new Modifier({
origin: [0, 0],
align: [0, 0],
transform: transTransform
});
var draggable = new Draggable();
draggable.subscribe(dragSurface);
//draggable.pipe(surface._eventOutput);
surface._eventOutput.subscribe(draggable);
surface.setContent('Not Draggable');
surface.on('updated', function(e) {
var pos = e.position;
this.setContent('Draggable Position is ' + pos);
transTransform.set(Transform.translate(pos[0] + 100, pos[1], 0));
});
surface.on('ended', function(e) {
var pos = e.position;
this.setContent('Draggable End Position is ' + e.ending);
transTransform.setTranslate([pos[0] + 100, pos[1], 0], {
duration: e.duration
});
});
mainContext.add(modifier).add(surface);
mainContext.add(draggable).add(dragSurface);
draggable.on('update', function(e) {
this.eventOutput.emit('updated', {
position: e.position
});
});
draggable.on('end', function(e) {
var finalPos = [0, 0];
var duration = 300
this.eventOutput.emit('ended', { position: finalPos, ending: e.position, duration: duration });
this.setPosition(finalPos, { duration: duration });
});
});
// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
New: Using the Draggable as a transform reference
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require('famous/modifiers/Draggable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
var mainContext = Engine.createContext();
var transTransform = new TransitionableTransform();
transTransform.set(Transform.translate(100, 0, 0));
var surface = new Surface({
size: [300, 100],
properties: {
backgroundColor: 'rgba(255,0,0,0.1)',
cursor: 'pointer'
}
});
var dragSurface = new Surface({
content: 'Drag Me',
size: [100, 100],
properties: {
backgroundColor: 'rgba(0,0,0,0.1)',
cursor: 'pointer'
}
});
var draggable = new Draggable();
var modifier = new Modifier({
origin: [0, 0],
align: [0, 0],
transform: getTransform
});
function getTransform() {
var pos = draggable.getPosition();
surface.setContent('Draggable Position is ' + pos); //needs performance enhancement
transTransform.setTranslate([pos[0]+100,pos[1],0]);
return transTransform.get();
}
draggable.subscribe(dragSurface);
surface.setContent('Not Draggable');
mainContext.add(modifier).add(surface);
mainContext.add(draggable).add(dragSurface);
draggable.on('update', function(e) {
});
draggable.on('end', function(e) {
var finalPos = [0, 0];
var duration = 300
this.setPosition(finalPos, {
duration: duration
});
});
});
// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
New: Using the Draggable as a transform reference with events
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var Draggable = require('famous/modifiers/Draggable');
var TransitionableTransform = require('famous/transitions/TransitionableTransform');
var mainContext = Engine.createContext();
var transTransform = new TransitionableTransform();
transTransform.set(Transform.translate(100, 0, 0));
var surface = new Surface({
size: [300, 100],
properties: {
backgroundColor: 'rgba(255,0,0,0.1)',
cursor: 'pointer'
}
});
var dragSurface = new Surface({
content: 'Drag Me',
size: [100, 100],
properties: {
backgroundColor: 'rgba(0,0,0,0.1)',
cursor: 'pointer'
}
});
var draggable = new Draggable();
var modifier = new Modifier({
origin: [0, 0],
align: [0, 0],
transform: transTransform
});
function getTransform() {
var pos = draggable.getPosition();
surface.setContent('Draggable Position is ' + pos);
transTransform.setTranslate([pos[0] + 100, pos[1], 0]);
return transTransform.get();
}
draggable.subscribe(dragSurface);
surface._eventOutput.subscribe(draggable.eventOutput);
surface.on('updating', function(e) {
var pos = e.position;
surface.setContent('Draggable Position is ' + pos);
transTransform.setTranslate([pos[0] + 100, pos[1], 0]);
});
surface.on('startedEnd', function(e) {
modifier.transformFrom(getTransform);
});
surface.on('endedEnd', function(e) {
modifier.transformFrom(transTransform);
});
surface.setContent('Not Draggable');
mainContext.add(modifier).add(surface);
mainContext.add(draggable).add(dragSurface);
draggable.on('update', function(e) {
this.eventOutput.emit('updating', {
position: e.position
});
});
draggable.on('end', function(e) {
var finalPos = [0, 0];
var duration = 2000
this.eventOutput.emit('startedEnd', {
position: e.position,
finalPos: finalPos
});
this.setPosition(finalPos, {
duration: duration
}, function() {
this.eventOutput.emit('endedEnd', {
position: this.position
});
}.bind(this));
});
});
// Start Main App
require(['main']);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>

label near icon in fusion tables map

I created a map showing some restaurant in a particular area. I used fusion tables as data entry and the code generated to display this map:
here is the link
I tried with no luck to add a text label with the name of the restaurant near the placemark ( icon ) .
Any ideas on how I can do?
I searched a lot in the forums, but I didn't find a solution.
Thank you very much
JT
(here is the code )
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"></meta>
<title>Locali in zona Fiume e Quarnero - Google Fusion Tables</title>
<style type="text/css">
html, body, #googft-mapCanvas { height:100%; margin: 0; padding: 0;}
</style>
<script type="text/javascript" src="https://maps.google.com/maps/api/js? sensor=false&v=3"></script>
<script type="text/javascript">
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) ||
(navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '500px':'100%' ;
mapDiv.style.height = isMobile ? '300px':'100%' ;
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(45.19975321105807, 14.824613028515614),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col6",
from: "1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function() {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function() {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="googft-mapCanvas"></div>
</body>
</html>
One option (for tables with less than a couple hundred rows) would be to query the table for the data using GViz and use that to add labels to the map.
proof of concept fiddle
google.load('visualization', '1', {'packages':['corechart', 'table', 'geomap']});
var tableid ="1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx"
var map;
var labels = [];
function displayLabels() {
//set the query using the current bounds
var queryStr = "SELECT Posizione, Nome FROM "+ tableid;
var queryText = encodeURIComponent(queryStr);
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
// alert(queryStr);
//set the callback function
query.send(displayLabelText);
}
function displayLabelText(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
FTresponse = response;
//for more information on the response object, see the documentation
//http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
// alert(numRows);
// var bounds = new google.maps.LatLngBounds();
for(i = 0; i < numRows; i++) {
var label = response.getDataTable().getValue(i, 1);
var labelStr = label.toString()
var positionStr = response.getDataTable().getValue(i, 0);
var position = positionStr.split(',');
var point = new google.maps.LatLng(
parseFloat(position[0]),
parseFloat(position[1]));
// bounds.extend(point);
labels.push(new InfoBox({
content: labelStr
,boxStyle: {
border: "1px solid black"
,textAlign: "center"
,backgroundColor:"white"
,fontSize: "8pt"
,width: "50px"
}
,disableAutoPan: true
,pixelOffset: new google.maps.Size(-25, 0)
,position: point
,closeBoxURL: ""
,isHidden: false
,enableEventPropagation: true
}));
labels[labels.length-1].open(map);
}
// zoom to the bounds
// map.fitBounds(bounds);
}
google.setOnLoadCallback(displayLabels);
code snippet:
google.load('visualization', '1', {
'packages': ['corechart', 'table', 'geomap']
});
var tableid = "1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx"
var map;
var labels = [];
function displayLabels() {
//set the query using the current bounds
var queryStr = "SELECT Posizione, Nome FROM " + tableid;
var queryText = encodeURIComponent(queryStr);
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
// alert(queryStr);
//set the callback function
query.send(displayLabelText);
}
function displayLabelText(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
FTresponse = response;
//for more information on the response object, see the documentation
//http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
// alert(numRows);
// var bounds = new google.maps.LatLngBounds();
for (i = 0; i < numRows; i++) {
var label = response.getDataTable().getValue(i, 1);
var labelStr = label.toString()
var positionStr = response.getDataTable().getValue(i, 0);
var position = positionStr.split(',');
var point = new google.maps.LatLng(
parseFloat(position[0]),
parseFloat(position[1]));
// bounds.extend(point);
labels.push(new InfoBox({
content: labelStr,
boxStyle: {
border: "1px solid black",
textAlign: "center",
backgroundColor: "white",
fontSize: "8pt",
width: "50px"
},
disableAutoPan: true,
pixelOffset: new google.maps.Size(-25, 0),
position: point,
closeBoxURL: "",
isHidden: false,
enableEventPropagation: true
}));
labels[labels.length - 1].open(map);
}
// zoom to the bounds
// map.fitBounds(bounds);
}
google.setOnLoadCallback(displayLabels);
function initialize() {
google.maps.visualRefresh = true;
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) || (navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '500px' : '100%';
mapDiv.style.height = isMobile ? '300px' : '100%';
map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(45.19975321105807, 14.824613028515614),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend-open'));
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(document.getElementById('googft-legend'));
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: {
enabled: false
},
query: {
select: "col6",
from: "1e8PEAUCopFkL9XqgVp1gJAv6Hh6ttGkMViOGhSZx",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
google.maps.event.addListenerOnce(map, 'bounds_changed', displayLabels);
if (isMobile) {
var legend = document.getElementById('googft-legend');
var legendOpenButton = document.getElementById('googft-legend-open');
var legendCloseButton = document.getElementById('googft-legend-close');
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
legendCloseButton.style.display = 'block';
legendOpenButton.onclick = function() {
legend.style.display = 'block';
legendOpenButton.style.display = 'none';
}
legendCloseButton.onclick = function() {
legend.style.display = 'none';
legendOpenButton.style.display = 'block';
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#googft-mapCanvas {
height: 100%;
margin: 0;
padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry,places&ext=.js"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
<script src="http://www.google.com/jsapi"></script>
<div id="googft-mapCanvas"></div>

Google Maps InfoBubble windows neither closing nor recentering map

I have a successful working GM prototype using InfoBubble here.
I need the map to recenter when I open each new InfoBubble window.
The map recenters on closing each InfoBubble because I call [line 238 etc]:
google.maps.event.addListener(infoBubble, "closeclick", function ()
Secondly, why doesn't the Los Angeles (United States West Coast, LA) InfoBubble also close the most recent InfoBubble window open as all the others do, please?
Thanks so much in advance for any suggestions; I know it must be simple - but have spent hours and hours and searched S/O too!
javascript:
$(document).ready(function () { initialize(); });
var myLatlng = new google.maps.LatLng(51.30, 0.7);
function initialize() {
google.maps.Map.prototype.setCenterWithOffset = function(LatLng, offsetX, offsetY) {
var map = this;
var ov = new google.maps.OverlayView();
ov.onAdd = function() {
var proj = this.getProjection();
var aPoint = proj.fromLatLngToContainerPixel(LatLng);
aPoint.x = aPoint.x+offsetX;
aPoint.y = aPoint.y+offsetY;
map.setCenter(proj.fromContainerPixelToLatLng(aPoint));
};
ov.draw = function() {};
ov.setMap(this);
};
var centerMap = new google.maps.LatLng(51.30, 0.7);
var mapOptions = {
zoom: 2,
disableDefaultUI: true,
scrollwheel: false,
navigationControl: false,
mapTypeControl: false,
scaleControl: false,
draggable: false,
center: centerMap,
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setCenterWithOffset(myLatlng, 50, 225);
setMarkers(map, sites);
google.maps.event.addListener(infoBubble, "closeclick", function () {
map.setCenterWithOffset(myLatlng, 50, 225);
});
google.maps.event.addListener(infoBubbleLA, "closeclick", function () {
map.setCenterWithOffset(myLatlng, 50, 225);
});
};
var infoBubble = new InfoBubble({
maxWidth: 400,
});
var infoBubbleLA = new InfoBubble({
maxWidth: 400,
});
// locationstrings start
var losangeles1 = 'losangeles1';
var losangeles2 = 'losangeles2';
var losangeles3 = 'losangeles3';
var losangeles4 = 'losangeles4';
var losangelescontentString ='losangelescontentString';
var portonovocontentstring ='Porto Novo';
var shackletoncontentstring = 'Shackleton';
var florencecontentstring = 'Florence';
var buenosairescontentstring = 'Buenos Aires';
var jodhpurcontentstring = 'Jodhpur';
var mtsinaicontentstring = 'Mt Sainai';
var neworleanscontentstring = 'New Orleans';
var pariscontentstring='Paris';
// locationstrings end
infoBubbleLA.addTab('Electronic Cataloguing Initiative', losangeles1);
infoBubbleLA.addTab('Getty Leadership Institute at Claremont Graduate University', losangeles2);
infoBubbleLA.addTab('Tab 3', losangeles3);
infoBubbleLA.addTab('Preserve L.A.', losangeles4);
var sites = [
// 'Title', lat, long, contentstring
['Los Angeles', 34.054082,-118.24261, losangelescontentString],
['Porto Novo', 6.501411,2.604275, portonovocontentstring],
['Shackleton', -77.550000, 166.150000, shackletoncontentstring],
['Florence', 43.773046,11.255901, florencecontentstring],
['Buenos Aires', -34.578528,-58.526273, buenosairescontentstring],
['Jodhpur', 27.199507,73.73826, jodhpurcontentstring],
['Mt Sinai', 28.555972,33.975048, mtsinaicontentstring],
['New Orleans', 29.984676,-90.063171, neworleanscontentstring],
['Paris', 48.821799,2.404933, pariscontentstring]
];
var iconBase = 'http://gettylabs.org/visit/FoundationMap/images/';
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
icon: iconBase + 'bullet.png',
title: sites[0],
position: siteLatLng,
html: sites[3],
map: map
});
google.maps.event.addListener(marker, "click", function () {
map.setCenterWithOffset(myLatlng, 50, 25);
if (this.html == losangelescontentString) {
infoBubbleLA.setContent(this.html);
infoBubbleLA.open(map,this);
} else {
infoBubble.setContent(this.html);
infoBubble.open(map,this);
}
});
};
};
You have 2 different InfoBubbles in you code infoBubbleLA and infoBubble. Opening one won't close the the other.
var infoBubble = new InfoBubble({
maxWidth: 400,
});
var infoBubbleLA = new InfoBubble({
maxWidth: 400,
});
This should do that:
google.maps.event.addListener(marker, "click", function () {
map.setCenterWithOffset(myLatlng, 50, 25);
if (this.html == losangelescontentString) {
infoBubbleLA.setContent(this.html);
infoBubbleLA.open(map,this);
infoBubble.close();
} else {
infoBubble.setContent(this.html);
infoBubble.open(map,this);
infoBubbleLA.close();
}
});
working fiddle

No lines drawn when drawing Polyline with MVCArray, with API v3.16 and later

If you use Google Maps API v3.16 and later, polyline are not drawn when a new marker is added to the polyline path and MVCArray, only markers plotted on a map.
My program based on code from http://nettique.free.fr/gmap/toolbar.html
html file :
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>map toolbar implementation</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.exp&sensor=true"></script>
<style type="text/css">
--- truncate ----
</style>
<script type="text/javascript" src="toolbarv3_files/mapToolbar.js"></script>
<script type="text/javascript">
// Register an event listener to fire when the page finishes loading.
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
body section
drawing toolbar :
<div id="hand_b" onclick="MapToolbar.stopEditing()"/>
<div id="line_b" onclick="MapToolbar.initFeature('line')"/>
canvas :
<div id="map" style="width: 85%; height: 100%; position: absolute;"></div>
script file (mapToolbar.js):
var map;
var MapToolbar = {
//reorder index of a poly markers array
reindex:function(markers){
markers.forEach(function(marker, index){
marker.index = index;
});
},
//add a point to a poly, 'e' can be a click event or a latLng object
addPoint : function(e, poly, index) {
var e = (typeof e.latLng != "undefined")? e.latLng : e,
image = new google.maps.MarkerImage('images/marker-edition.png',
new google.maps.Size(9, 9),
new google.maps.Point(0, 0),
new google.maps.Point(5, 5)),
imageover = new google.maps.MarkerImage('images/marker-edition-over.png',
new google.maps.Size(9, 9),
new google.maps.Point(0, 0),
new google.maps.Point(5, 5)),
path = poly.getPath(),
index = (typeof index != "undefined")? index : path.length,
markers = (poly.markers)? poly.markers : new google.maps.MVCArray,
marker = new google.maps.Marker({
position: e,
map: map,
draggable: true,
icon: image
});
marker.index = index;
path.insertAt(index, e);
markers.insertAt(index, marker)
if(arguments[2]){
MapToolbar.reindex(markers);
}
features:{
.....
lineTab: {},
.....
},
//instanciate a new Feature instance and create a reference
initFeature: function(type){
new MapToolbar.Feature(type);
},
//check if a toolbar button is selected
isSelected: function(el){
return (el.className == "selected");
},
//the map DOM node container
....
lineCounter:0,
....
//select hand button
stopEditing: function() {
this.removeClickEvent();
this.select("hand_b");
},
//create new polyline function
MapToolbar.Feature.prototype.poly = function(type) {
var color = MapToolbar.getColor(false),
path = new google.maps.MVCArray,
poly,
self = this,
el = type + "_b";
if(type=="shape"){
poly = self.createShape( {strokeWeight: 3, fillColor: color}, path );
}else if(type=="line"){
poly = self.createLine( {strokeWeight: 3, strokeColor: color }, path );
}
poly.markers = new google.maps.MVCArray;
if(MapToolbar.isSelected(document.getElementById(el))) return;
MapToolbar.select(el);
MapToolbar.currentFeature = poly;
poly.setMap(map);
if(!poly.$el){
++MapToolbar[type+"Counter"];
poly.id = type + '_'+ MapToolbar[type+"Counter"];
poly.$el = MapToolbar.addFeatureEntry(poly.id, color);
MapToolbar.features[type+"Tab"][poly.id] = poly;
}
}
MapToolbar.Feature.prototype.createLine = function(opts, path) {
var poly = new google.maps.Polyline({
strokeWeight: opts.strokeWeight,
strokeColor: opts.strokeColor
}), self = this;
poly.setPath(new google.maps.MVCArray(path));
return poly;
}
//initialization function
function initialize(container) {
var options = {
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.TERRAIN],
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
}
}
map = new google.maps.Map(document.getElementById('map'));
map.setCenter(new google.maps.LatLng(47.9, 1.9 ));
map.setZoom(12);
map.setMapTypeId( google.maps.MapTypeId.ROADMAP );
with(MapToolbar){
with(buttons){
.....
$hand = document.getElementById("hand_b");
$line = document.getElementById("line_b");
....
}
....
select("hand_b");
}
MapToolbar.polyClickEvent = google.maps.event.addListener(map, 'click', function(event){
if( !MapToolbar.isSelected(MapToolbar.buttons.$shape) && !MapToolbar.isSelected(MapToolbar.buttons.$line) ) return;
if(MapToolbar.currentFeature){
MapToolbar.addPoint(event, MapToolbar.currentFeature);
}
});
}
complete version of "mapToolbar.js" script file is also available at : https://code.google.com/p/js2shapefile/source/browse/trunk/lib/mapToolbar.js?r=2
an error occurred when executing line "path.insertAt(index, e);" (addPoint function).
TypeError: this.j[qd] is not a function
...his[gd](a,b)}};L.insertAt=function(a,b){this.j[qd](a,0,b);bg(this);S[n](this,"in...
{main,g...try}.js (line 26, col 1473)
I had the same problem. I've solved changing poly.setPath in createLine function.
MapToolbar.Feature.prototype.createLine = function(opts, path) {
var poly = new google.maps.Polyline({
strokeWeight: opts.strokeWeight,
strokeColor: opts.strokeColor
}), self = this;
// 27/08/2014 - This not work
//poly.setPath(new google.maps.MVCArray(path));
poly.setPath(path);
return poly;
}

Resources