I use AngularJS. I want to present an InfoBubble with dynamic content and some functions of AngularJS like ng-click, ng-mouseover. Using InfoWindows I had to compile html first and then set the compiled html as the content of the InfoWindows. Unfortunately, this is not working for InfoBubbles. When I add static html it has no problem, but when I add the compiled html it seems to have nothing as content.
var htmlElement = '<div ng-include="\'/home/include/infoBubble.html\'"></div>'
var compiled = $compile(htmlElement)($scope)
infoWindow = new InfoBubble({
content: compiled[0],
shadowStyle: 1,
padding: 0,
backgroundColor: 'rgb(57,57,57)',
borderRadius: 4,
arrowSize: 10,
borderWidth: 1,
borderColor: '#2c2c2c',
disableAutoPan: true,
hideCloseButton: true,
arrowPosition: 30,
backgroundClassName: 'phoney',
arrowStyle: 2
});
infoWindow.open(vm.map, marker);
The problem was that I had no max and min heights and widths. Setting those solved the problem.
Related
I have a simple meteor app with two templates using flowrouter to navigate between them. Each template has a single HTML canvas element in it both have a fabricjs canvas assigned and a box drawn.
When I navigate between the two templates while doing a memory performance profile I see the memory continuously increase at every navigation between templates.
I expected the garbage collector to clean up the canvas vars but its not. So something keeping them in context. I can't see what I'm missing here.
Template HTML
<template name="one">
Template One
two
<div>
<canvas id="canvasONE" width="2000" height="1601"></canvas>
</div>
</template>
<template name="two">
Template Two
one
<div>
<canvas id="canvasTWO" width="2000" height="1601"></canvas>
</div>
</template>
// JavaScript
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
//////////////////////////////////////////////
// Template One
Template.one.onRendered( function(){
var canvas = new fabric.Canvas('canvasONE',{selection:true});
var rec = new fabric.Rect({
left: 0,
top: 0,
width: 120,
height: 50,
rx: 4,
ry: 4,
fill: '#64b5f6',
stroke: '#6Ebfff',
strokeWidth: 2,
originX: 'left',
originY: 'top',
lockScalingX: true,
lockScalingY: true
});
canvas.add(rec)
})
/////////////////////////////////////////////////////
// Template Two
Template.two.onRendered( function(){
var canvas = new fabric.Canvas('canvasTWO',{selection:true});
var rec = new fabric.Rect({
left: 0,
top: 0,
width: 120,
height: 50,
rx: 4,
ry: 4,
fill: '#223344',
stroke: '#6Ebfff',
strokeWidth: 2,
originX: 'left',
originY: 'top',
lockScalingX: true,
lockScalingY: true
});
canvas.add(rec)
})
Thanks...
UPDATE: after a few hours debugging, it appears to be DOM related. The meteor template removes the DOM elements but fabric could still be referencing it. The GC leaves it in memory. I added an extra function to each template to try clear the fabric canvas.
Template.one.onDestroyed( function(){
rec = null;
canvas.clear();
canvas.dispose();
$(canvas.wrapperEl).remove()
})
but still seeing the memory leak continue.
The problem was resolved.
I moved the var canvas definition outside of the function blocks to the root of the file, In meteor this makes it global to the scope of the file, not a true application global. The fabricjs canvas clear() dispose() were from a recommendation by one of the authors of fabric posted as an answer to someone else's question,
So I've been trying to load a remote image using titanium, here's a snippet that I'm using, but it always shows the default image. Any clue what I am doing wrong, I'm sorry it's a naive question
here's my view
<View id="image">
</View>
and my controller
userImage = Ti.UI.createImageView({
id : "userImage",
image : "http://graphics.ucsd.edu/~henrik/images/imgs/face_bssrdf.jpg",
width : 90,
center:0,
height : 90,
});
$.image.add(userImage);
had to upgrade the sdks was buggy at 4.0.0.RC
The following code works fine for me with 4.0.0.GA and 4.1.0.GA:
var win = Ti.UI.createWindow({
backgroundColor: 'green'
});
var userImage = Ti.UI.createImageView({
id: "userImage",
image: "http://graphics.ucsd.edu/~henrik/images/imgs/face_bssrdf.jpg",
width: 90,
center: 0,
height: 90,
});
win.add(userImage);
win.open();
We are using google utility script to have a custom icon with information below it.
var marker5 = new MarkerWithLabel({position: point,
map: map,
draggable: false,
raiseOnDrag: false,
labelContent: infor,
labelAnchor: new google.maps.Point(20, 0),
labelClass: "labels", // the CSS class for the label
labelStyle: {opacity: 0.75},
icon: {
url: entImage,
size: new google.maps.Size(30, 30),
origin: new google.maps.Point(20, 0)
},
marker: MarkerWithLabel
});
The issue when we size the icon using new google.maps.Size(30, 30) it could not show up the full icon just partial of it. How ensure that when we resize it covers the whole image.
I have managed to solve this problem via a simple way and for the benefit of the rest just create one image icon like this
var pIcon = new google.maps.MarkerImage('logo.png',
null,
null,
null,
new google.maps.Size(30, 30));
Thereafter just apply into the rest of the codes.
I am trying to use Jcrop with preview pane in the page of changing avatar. However, after uploading new image file, when I call setImage to set the new image(with different width/height) and also set the attr of the preview image, the preview pane show up incorrectly. I use firebug the trace, it seems the img is still using the height, width of previous image. I modify the tutorial3 in the download package, simply adding a botton to change the image to see if the preview pane is correct or not. I seem to be the same error. Here below is the code for button click function.
Any solutions?
$('#img1').click(function(e) {
$('#preview').attr('src','demo_files/img50d5753eb067c.jpg');
jcrop_api.setImage('demo_files/img50d5753eb067c.jpg');
$('#target').Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 1,
boxWidth: 450
},function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
});
});
I see the same problem with yours in this topic Change an Image while using JCrop and the answer of AdmSteck in which is the best one.
Hope this help!
within the unminified version of the plugin "boundx and boundy" are declared as local variables that do not get updated outside of the setImage function. All you need to do is remove the 'var' for these two variables and make them global.
from line 328,
var boundx = $img.width(),
boundy = $img.height(),
$div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({
position: 'relative',
backgroundColor: options.bgColor
}).insertAfter($origimg).append($img);
change to
boundx = $img.width();
boundy = $img.height();
var $div = $('<div />').width(boundx).height(boundy).addClass(cssClass('holder')).css({
position: 'relative',
backgroundColor: options.bgColor
}).insertAfter($origimg).append($img);
I want to display Markers on Google map with title displayed under them as shown in picture:
Now this I read was possible in v2 using ELabel but is deprecated in v3. Is there any possible way to show some text under icons of markers in Google Maps V3?
Since at least October 2016, the official API provides a way to add permanently visible labels that are longer than one letter. See this reply by a Google project member.
var m = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
label: 'Hello world',
});
By default, the result looks like:
Pretty unreadable. Fortunately the API also allows a MarkerLabel object instead of a plain string:
var m = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
label: {
color: 'white',
fontWeight: 'bold',
text: 'Hello world',
},
});
Snippet above yields the following result:
However, the original question asked if the label could be located below the marker. The MarkerLabel docs mention this is possible with a custom icon and labelOrigin property. If we want to use the default icon, one is available at GitHub. Let us add the icon object:
var m = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
label: {
color: 'white',
fontWeight: 'bold',
text: 'Hello world',
},
icon: {
labelOrigin: new google.maps.Point(11, 50),
url: 'default_marker.png',
size: new google.maps.Size(22, 40),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(11, 40),
},
});
This results:
Pretty good! However, this whole approach has a shortcoming that the box in the original question does not have: readability with each map type. If the map type is changed from the satellite to the default the resulting label is hard to read:
An easy but not perfect way to avoid the low contrast in the both types is to set color: 'gray':
However, the gray color fails near urban areas. A better option would be to apply text-shadow CSS property to draw black linings for the white text. However, I cannot find a way to apply the property to the labels because few DOM elements created by Google Maps define a class:
The best option I came up to is to detect changes in the map type and update label color for each marker:
map.addListener('maptypeid_changed', function () {
var typeToColor, type, color, k, label;
typeToColor = {
'terrain': 'black',
'roadmap': 'black',
'hybrid': 'white',
'satellite': 'white',
};
type = map.getMapTypeId();
color = typeToColor[type];
for (k in markers) {
if (markers.hasOwnProperty(k)) {
label = markers[k].getLabel();
label.color = color;
markers[k].setLabel(label);
}
}
});
However, even this would fail on snowy or cloudy satellite imagery. I think it is still good enough in most of the cases. Nevertheless, it is nice to have the ability to display visible labels with the official API, without any plugins :)
I found the solution in an other post which worked perfectly for me.
Add numbering label to google map marker
You can't! But there's another part of maps API you can use to have permanently displayed text attached to your markers (without requiring any third party component), it's called infoWindow. Have a look at this for sample code & see it in action: https://developers.google.com/maps/documentation/javascript/examples/event-closure
If you dare using third party code, then here's something that is closer from the look & feel you want: http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/docs/examples.html
I use the following:
MarkerWithLabel.js
( the image is just a flag.png file)
Using javascript in my X.html document
it looks something like this....
<style type="text/css">
.labels {
color: black;
background-color: white;
font-family: "Lucida Grande", "Arial", sans-serif;
font-size: 0.8em;
font-weight: bold;
text-align: center;
width: 6em;
border: 1px solid black;
white-space: normal;
}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.9&sensor=true"></script>
<!--MarkerwithLabelClass - adjust the path!! -->
<script src="YourPathHere/markerwithlabel.js"></script>
<script type="text/javascript">
//insert standaard initializing of googlemaps here
//and other windows.onload function
window.onload = function Initialize() {
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function CreateMarker(lat, long, titel, label, image, anchorY, anchorX){
var latlng = new google.maps.LatLng(parseFloat(lat), parseFloat(long));//I use parseFloat cause my parameters are strings(coming from JSON-string)
var marker = new MarkerWithLabel({
zIndex: 1,
title: titel,
position: latlng,
draggable: false,
icon: image,
labelContent: label,
labelAnchor: new google.maps.Point(30, -2),
labelClass: "labels", // the CSS class for the label
labelStyle: { opacity: 0.80 }
});
return marker;
}
</script>
Read up on license info for google maps API here : https://www.google.com/intx/en_uk/work/mapsearth/products/mapsapi.html
You should be able to use the same principle as in this example. Instead of listening to the mouse events you should create a new custom control for each marker and then position it below the marker. Hope it works out.