Google Maps API + Wax.g + IE = Tiny Tiles - javascript

I'm using wax.g to display custom tiles on a Google Map. This works fine in every browser I've tested, except IE. In other browsers, the tiles are rendered correctly, but in IE, the tiles a rendering as a smaller version of their true selves. The issue is best explained in the following screenshots:
What they should look like: http://cl.ly/image/2E0U2b0c0f0W
What they look like in IE: http://cl.ly/image/2F3B353q0G0c
This issue doesn't happen all the time, and if I pan or zoom, sometimes I get the correctly sized tiles, and sometimes I don't. Not sure if this is a Wax issue or an issue with how the Google Maps API renders custom overlayMapTypes. Has anyone else experienced this issue? Any insight is much appreciated...
(cross-posted from MapBox GitHub issue - no answers there yet)

So the problem is that my images were inheriting a style height and width of auto, and Wax.g's getTile method method creates an Image using new Image(256, 256), which writes to height and width attributes of the img itself (img attributes, not inline style). The inline styles took priority over the attributes, so the img was being sized using auto. I fixed this by ensuring the img had a height and width of 256 using inline styling.
Wax.g code:
// Get a tile element from a coordinate, zoom level, and an ownerDocument.
wax.g.connector.prototype.getTile = function(coord, zoom, ownerDocument) {
var key = zoom + '/' + coord.x + '/' + coord.y;
if (!this.cache[key]) {
var img = this.cache[key] = new Image(256, 256);
this.cache[key].src = this.getTileUrl(coord, zoom);
this.cache[key].setAttribute('gTileKey', key);
this.cache[key].onerror = function() { img.style.display = 'none'; };
}
return this.cache[key];
};
My modified code:
// Get a tile element from a coordinate, zoom level, and an ownerDocument.
wax.g.connector.prototype.getTile = function(coord, zoom, ownerDocument) {
var key = zoom + '/' + coord.x + '/' + coord.y;
if (!this.cache[key]) {
var img = this.cache[key] = new Image(256, 256);
img.style.height = '256px'; // added this line
img.style.width = '256px'; // added this line
this.cache[key].src = this.getTileUrl(coord, zoom);
this.cache[key].setAttribute('gTileKey', key);
this.cache[key].onerror = function() { img.style.display = 'none'; };
}
return this.cache[key];
};

Related

Weird stuttering when generating animated gifs using gifshot.js on ios

Ok, so a little bit of background... I'm trying to generate animated gifs from animations done on an HTML5 canvas using JavaScript. Specifically, I'm adding data layers to a Mapbox GL JS map and looping through them.
On each iteration, I save the canvas element and transform it to a blob before calling URL.createObjectURL(blob) and setting that as the source to a new image. After the loop is finished I generate a gif using gifshot (https://github.com/yahoo/gifshot) and the images I previously created.
This process works perfectly in all browsers (mobile too!) EXCEPT on iPhone ios. On ios the gif has weird stutters and transparency issues. I have tried other gif creation libraies but all have the same issue on ios. Could it be a memory problem or something? I'm at my wit's end on this, so any help is greatly appreciated!
This is the code inside each loop:
var cv = map.getCanvas()
var oneImage = new Image();
cv.toBlob(function(blob) {
url = URL.createObjectURL(blob);
oneImage.src = url
images_arr.push(oneImage)
i++;
setTimeout(function(){
gifLoop(images_arr);
},1000)
})
and this is the code I call when the loop is finished:
var w = window.innerWidth;
var h = window.innerHeight;
recalculated_size = calculateAspectRatioFit(w, h, maxWidth, maxHeight)
w = recalculated_size.width
h = recalculated_size.height
gifshot.createGIF({
'images': images_arr,
'gifWidth': w,
'gifHeight':h,
},function(obj) {
if(!obj.error) {
var image = dataURItoBlob(obj.image)
image = URL.createObjectURL(image);
var animatedImage = document.getElementById('gif');
animatedImage.src = image
var link = $('#gif-link');
link.attr('href',image);
filename = curr_layer_id + '_' + curr_time +'.gif'
link.attr('download', filename);
}
});

Bing Maps not displaying properly on website

I have used Bing Maps onto my website, in which I used Script
<script>
$(document).ready(function () {
var map = null;
function LoadMap() {
map = new Microsoft.Maps.Map(
document.getElementById('bing_maps_content'),
{
credentials: ".............."
});
}
$('#btnlocation').click(function () {
var url = "/Home/getlocation";
$.getJSON(url, null, function (data) {
$.each(data, function (index, LocationData) {
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), null);
pushpin.setLocation(new Microsoft.Maps.Location(
LocationData.longitutde,
LocationData.latitude
));
map.entities.push(pushpin);
map.setView({
zoom: 4, centre: new Microsoft.Maps.Location("-37.81633","144.97097")
});
});
});
});
LoadMap();
});
$(".jump-response").each(function () {
var hue = 'rgb(' + (Math.floor((256 - 199) * Math.random()) + 200) + ',' + (Math.floor((256 - 199) * Math.random()) + 200) + ',' + (Math.floor((256 - 199) * Math.random()) + 200) + ')';
$(this).css("background-color", hue);
});
and loaded the data using controller and Model using Microsoft Bing map tutorial C# MVC . It works fine but when displayed onto my website it becomes like this.
It's displaying these diamond white shapes even if I zoom in. How do I get rid of these covering the map?
lol, wow, that is impressive. In the 9+ years I have been working with Bing Maps I have never seen that before.
Ok, now onto solving the issue. The code you provided won't cause this effect. It looks like each circle consists of a single map tile which is nothing more than an image tag. I suspect that somewhere in your application you have a CSS style for images that gives them a large border radius in order to make them look like circles. This style appears to be applied to all images in your app. Take a look at your CSS and look for any definitions on the img tag.

Paper.js Subraster Selecting Wrong Area

I'm working in a Paper.js project where we're essentially doing image editing. There is one large Raster. I'm attempting to use the getSubRaster method to copy a section of the image (raster) that the user can then move around.
After the raster to edit is loaded, selectArea is called to register these listeners:
var selectArea = function() {
if(paper.project != null) {
var startDragPoint;
paper.project.layers[0].on('mousedown', function(event) { // TODO should be layer 0 in long run? // Capture start of drag selection
if(event.event.ctrlKey && event.event.altKey) {
startDragPoint = new paper.Point(event.point.x + imageWidth/2, (event.point.y + imageHeight/2));
//topLeftPointOfSelectionRectangleCanvasCoordinates = new paper.Point(event.point.x, event.point.y);
}
});
paper.project.layers[0].on('mouseup', function(event) { // TODO should be layer 0 in long run? // Capture end of drag selection
if(event.event.ctrlKey && event.event.altKey) {
var endDragPoint = new paper.Point(event.point.x + imageWidth/2, event.point.y + imageHeight/2);
// Don't know which corner user started dragging from, aggregate the data we have into the leftmost and topmost points for constructing a rectangle
var leftmostX;
if(startDragPoint.x < endDragPoint.x) {
leftmostX = startDragPoint.x;
} else {
leftmostX = endDragPoint.x;
}
var width = Math.abs(startDragPoint.x - endDragPoint.x);
var topmostY;
if(startDragPoint.y < endDragPoint.y) {
topmostY = startDragPoint.y;
} else {
topmostY = endDragPoint.y;
}
var height = Math.abs(startDragPoint.y - endDragPoint.y);
var boundingRectangle = new paper.Rectangle(leftmostX, topmostY, width, height);
console.log(boundingRectangle);
console.log(paper.view.center);
var selectedArea = raster.getSubRaster(boundingRectangle);
var selectedAreaAsDataUrl = selectedArea.toDataURL();
var subImage = new Image(width, height);
subImage.src = selectedAreaAsDataUrl;
subImage.onload = function(event) {
var subRaster = new paper.Raster(subImage);
// Make movable
subRaster.onMouseEnter = movableEvents.showSelected;
subRaster.onMouseDrag = movableEvents.dragItem;
subRaster.onMouseLeave = movableEvents.hideSelected;
};
}
});
}
};
The methods are triggered at the right time and the selection box seems to be the right size. It does indeed render a new raster for me that I can move around, but the contents of the raster are not what I selected. They are close to what I selected but not what I selected. Selecting different areas does not seem to yield different results. The content of the generated subraster always seems to be down and to the right of the actual selection.
Note that as I build the points for the bounding selection rectangle I do some translations. This is because of differences in coordinate systems. The coordinate system where I've drawn the rectangle selection has (0,0) in the center of the image and x increases rightward and y increases downward. But for getSubRaster, we are required to provide the pixel coordinates, per the documentation, which start at (0,0) at the top left of the image and increase going rightward and downward. Consequently, as I build the points, I translate the points to the raster/pixel coordinates by adding imageWidth/2 and imageHeight/2`.
So why does this code select the wrong area? Thanks in advance.
EDIT:
Unfortunately I can't share the image I'm working with because it is sensitive company data. But here is some metadata:
Image Width: 4250 pixels
Image Height: 5500 pixels
Canvas Width: 591 pixels
Canvas Height: 766 pixels
My canvas size varies by the size of the browser window, but those are the parameters I've been testing in. I don't think the canvas dimensions are particularly relevant because I'm doing everything in terms of image pixels. When I capture the event.point.x and event.point.y to the best of my knowledge these are image scaled coordinates, but from a different origin - the center rather than the top left. Unfortunately I can't find any documentation on this. Observe how the coordinates work in this sketch.
I've also been working on a sketch to illustrate the problem of this question. To use it, hold Ctrl + Alt and drag a box on the image. This should trigger some logging data and attempt to get a subraster, but I get an operation insecure error, which I think is because of security settings in the image request header. Using the base 64 string instead of the URL doesn't give the security error, but doesn't do anything. Using that string in the sketch produces a super long URL I can't paste here. But to get that you can download the image (or any image) and convert it here, and put that as the img.src.
The problem is that the mouse events all return points relative to 0, 0 of the canvas. And getSubRaster expects the coordinates to be relative to the 0, 0 of the raster item it is extracting from.
The adjustment needs to be eventpoint - raster.bounds.topLeft. It doesn't really have anything to do with the image width or height. You want to adjust the event points so they are relative to 0, 0 of the raster, and 0, 0 is raster.bounds.topLeft.
When you adjust the event points by 1/2 the image size that causes event points to be offset incorrectly. For the Mona Lisa example, the raster size (image size) is w: 320, h: 491; divided by two they are w: 160, h: 245.5. But bounds.topLeft of the image (when I ran my sketch) was x: 252.5, y: 155.5.
Here's a sketch that shows it working. I've added a little red square highlighting the selected area just to make it easier to compare when it's done. I also didn't include the toDataURL logic as that creates the security issues you mentioned.
Here you go: Sketch
Here's code I put into an HTML file; I noticed that the sketch I put together links to a previous version of the code that doesn't completely work.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Rasters</title>
<script src="./vendor/jquery-2.1.3.js"></script>
<script src="./vendor/paper-0.9.25.js"></script>
</head>
<body>
<main>
<h3>Raster Bug</h3>
<div>
<canvas id="canvas"></canvas>
</div>
<div id="position">
</div>
</main>
<script>
// initialization code
$(function() {
// setup paper
$("#canvas").attr({width: 600, height: 600});
var canvas = document.getElementById("canvas");
paper.setup(canvas);
// show a border to make range of canvas clear
var border = new paper.Path.Rectangle({
rectangle: {point: [0, 0], size: paper.view.size},
strokeColor: 'black',
strokeWidth: 2
});
var tool = new paper.Tool();
// setup mouse position tracking
tool.on('mousemove', function(e) {
$("#position").text("mouse: " + e.point);
});
// load the image from a dataURL to avoid CORS issues
var raster = new paper.Raster(dataURL);
raster.position = paper.view.center;
var lt = raster.bounds.topLeft;
var startDrag, endDrag;
console.log('rb', raster.bounds);
console.log('lt', lt);
// setup mouse handling
tool.on('mousedown', function(e) {
startDrag = new paper.Point(e.point);
console.log('sd', startDrag);
});
tool.on('mousedrag', function(e) {
var show = new paper.Path.Rectangle({
from: startDrag,
to: e.point,
strokeColor: 'red',
strokeWidth: 1
});
show.removeOn({
drag: true,
up: true
});
});
tool.on('mouseup', function(e) {
endDrag = new paper.Point(e.point);
console.log('ed', endDrag);
var bounds = new paper.Rectangle({
from: startDrag.subtract(lt),
to: endDrag.subtract(lt)
});
console.log('bounds', bounds);
var sub = raster.getSubRaster(bounds);
sub.bringToFront();
var subData = sub.toDataURL();
sub.remove();
var subRaster = new paper.Raster(subData);
subRaster.position = paper.view.center;
});
});
var dataURL = ; // insert data or real URL here
</script>
</body>
</html>

JavaScript filter hueRotate does not work

I am trying to change an image's (#bgImage) hue when hovering over a button (profIcon) in JavaScript. This type of button is created with JS, and there are 9 of them.
Here is the code that creates a DOM image element, sets it's source, position, size and transition. Finally it appends it to it's container. The image appears correctly, where it should be.
I am using quickID in place of document.getElementById, and it is working without error.
var bgImage = document.createElement("img");
bgImage.id = "bgImage";
bgImage.src = "./resources/images/backgrounds/profession/selector.jpg";
bgImage.style.position = "absolute";
bgImage.style.left = "0px";
bgImage.style.top = "0px";
bgImage.style.width = "100%";
bgImage.style.height = "100%";
bgImage.style.zIndex = 1;
bgImage.style.webkitTransition = "all 0.5s ease";
quickID("centerdiv").appendChild(bgImage);
Here is the code that runs when I hover over an image:
profIcon.onmouseover = function () {
var thisNr = this.id.substr(8); //last char of the profIcon ID; number between 0 and 8
var newHue = profTomb[thisNr][3]; //this contains the value and only that.
console.log(newHue); //always returns the correct value
quickID(this.id).style.webkitFilter = "grayscale(0%)"; //this part works, too
quickID("bgImage").style.webkitFilter = "hueRotate(" + newHue + "deg)";
}
My problem: for some reason, the filter does not apply. newHue is either a positive (75), or a negative (-23) value and it's inserted correctly, as it appears in the console log. I only use webkit vendor prefix as I use Google Chrome.
I waited up to 1 minute with my mouse cursor over the image, thinking my system needs time to process the transformation, but nothing happened.
Does anyone knows what is the problem?
The correct string to use is hue-rotate, not hueRotate. The following should work:
quickID("bgImage").style.webkitFilter = "hue-rotate(" + newHue + "deg)";

Scale Image from current size and not from original size

Basically i am trying to scale an img with an id="room" according to a parameter wich will be +1 or -1 (and its a constant that i want to scale +-10%)
this is how i am trying
function scalar(scaleP100){ /* scaleP100 is +1 or -1 (no other posible value)*/
var addX = $('#room').width()*10*scaleP100/100;
var addY = $('#room').height()*10*scaleP100/100;
var newW = $('#room').width()+ addX;
var newH = $('#room').height() + addY;
$('img#room').css({'width':newW,'height':newH});
console.log(newW +','+ newH+':'+$('img#room').length);
return false;
}
This is inside a mouswheel detection,
So it has two stages: +10% from original size, and -10% from original size. I just don't know why it doesn't scale acording the current size (instead of the original size)
what am i doing wrong?
If you want to see what i probably didn't explain well, please check http://toniweb.us/m/3d/adam.html (but mousewheel outside the image only)
Thanks
you have two elements with same id:
<div id="room"> and <img id="room">
This should work, but I suggest you to make your html cleaner..
function scalar(scaleP100){ /* scaleP100 is +1 or -1 (no other posible value)*/
var addX = $('img#room').width()*10*scaleP100/100;
var addY = $('img#room').height()*10*scaleP100/100;
var newW = $('img#room').width()+ addX;
var newH = $('img#room').height() + addY;
$('img#room').css({'width':newW,'height':newH});
console.log(newW +','+ newH+':'+$('img#room').length);
return false;
}

Categories

Resources