How to make area of image clickable - javascript

This is not a: "Do all the work for me!" kind of question. I just wanna know which approach you think would be suitable for this challenge.
I have this map:
As you can see by the blue marker, I've roughly drawned some selections/areas of the map. Theese areas I want to serve as links.
But I don't quite know how to grasp this challenge, since all of the areas have quite odd shapes.
I have looked at cords, but it seems like a huge job with all of the twists and turns that I would need to do.
I would be awesome if I could just slice up the areas in Photoshop and save each of them as .png and just tell my page to ignore the transparent area! But that's just wishfull thinking I suppose.
I hope that one of you have a suggestion that I've overlooked.

Give a try to these -
http://polymaps.org/
http://www.amcharts.com/javascript-maps/
Raphael JS
You can try making an SVG version of your map and then implement it's clickiness with one of these libraries depending on which one you choose.
Here's one tutorial to do this with Raphael JS - http://parall.ax/blog/view/2985/tutorial-creating-an-interactive-svg-map

Make an image for each clickeable zone, like this:
Register to the click event of the img element from the page, this way:
var getAreaFromXY = function(x,y) {
// for each section colored map
// get pixel color on x,y (see http://stackoverflow.com/questions/8751020/how-to-get-a-pixels-x-y-coordinate-color-from-an-image)
// if the color is red, that is the zone
};
$(".post-text img").click(function(e) {
var area = getAreaFromXY(e.offsetX, e.offsetY);
});

Related

Masked element in Snap SVG doesn't come into view when translated

I have a group of elements that are masked by a rect in SnapSVG and I want to translate the elements, bringing new ones into view (and hiding ones that are currently in view). The code is really simple - here's a codepen: http://codepen.io/austinclemens/pen/ZbpVmX
As you can see from the pen, box1, which starts outside the mask element (clip) should cross through it when animated, but it never appears. Moreover, box2, which should move out of the clipping area, remains visible.
This example seems to do a similar thing and has no problems: http://svg.dabbles.info/snaptut-masks2
Here's the code from codepen:
var t = Snap('#target')
var clip=t.rect(200,200,200,200).attr({fill:'#fff'})
var box1=t.rect(300,100,50,50).attr({fill:'#000'})
var box2=t.rect(300,300,50,50).attr({fill:'#000'})
var boxgroup=t.group(box1,box2)
boxgroup.attr({mask:clip})
boxgroup.animate({transform:'t100,300'},2000)
I notice that the svg.dabbles examples translates the clip region by 0,0 at one point, but adding something like that doesn't seem to get me anywhere.
Ok, I figured this out thanks in part to this really great article about SVG transforms: http://sarasoueidan.com/blog/svg-transformations/
The upshot is that when I translate the box group, it takes the mask with it. This is a little confusing to me still - I guess the mask attribute is causing this somehow? Anyways, the solution is to apply an opposite translation to the mask to keep it in place. Check the pen to see it in action but basically I just had to add:
clip.animate({transform:'t-100,-300'},2000)
The tricky part of this is that you now need to synchronize the movement of the mask and the movement of the box group.
edit - I now demonstrate how synchronization can be achieved using snap's set.animate method on the codepen.

moving path to front changes selection?

i'm struggling to understand the following behaviour: i have two maps (based on topojson-data, visualised through d3), and on mouseover over certain parts of map1, the corresponding parts of map2 should light up. i got it to work with changing the style (opacity or fill), but now i wanted to highlight the borders of each map-part.
as seen for instance here one needs to move the specific path to the front to make all the borders visible. this is no problem for the area where i move the mouse across (using this), but when i select the corresponding part of the other map, it works one time and after that other parts get selected - so my guess is something is messing with the selection.
here is the code:
.on("mouseover",function(d){
var old=d.properties.iso; //this is the identifying number of the map-part(s)
sel=svg2.selectAll("path")
.data(datastore2015.features)
.filter(function(d){return d.properties.iso==old;})
.node(); //here the corresponding part(s) get filtered
d3.select(sel.parentNode.appendChild(sel)).classed("high2",true); //and this moves it to front and highlights the borders
on mouseout, it just resets:
.on("mouseout",function(d){
svg2.selectAll("path").classed("high2",false);
when i log the data to the console it seems that each mouseover moves +1 entry through the dataset, starting by the first entry the mouse moved over. i could not figure out why this happens and how to avoid it.
i'd appreciate any ideas you could give me, mainly i'd like to understand what's going wrong and why.
thanks
so i found my error, calling the data-variable once again seems to have messed things up - somehow i was under the impression that i need it, but it works just fine this way:
sel=svg2.selectAll("path").filter(function(d){return d.properties.iso==old;}).node();
d3.select(sel.parentNode.appendChild(sel)).classed("high2",true);
sorry for the bother, i didn't see this possibility before.

How to add square tiles to leaflet map with hovering effect?

I want to split my map into tiles/territories. So i've prepared another layer showing squares. But this layer is full of .png image files so there is no data/object for this squares.
I've also tried to draw squares with leaflet's geometry objects. But it causing performance issues, there is times to show 500+ squares.
If you develop something like that what method would you prefer? UTFGrid? GeoJSON/Geometry? Or maybe any other better solution?
UPDATE:
Actually i don't want to get data belongs to square's territory i just want to change the square's color somehow i mean somehow i want to highlight that area maybe i can create a rectangle on the fly when user mouseover.
And im trying avoid to use UTFGrid for just highlighting. But I want to ensure the UTFGrid is the only way or not.
This sounds like the exact reason that UTFGrid was created! This site links to the tutorial that I used when learning UTFGrid, and it is solid.
Updated after your update:
MarkerCluster might have the look/feel you are going after, they basically paint a polygon onto the map layer. You can check the source here, and here's a relevant snippet:
_showCoverage: function (e) {
var map = this._map;
if (this._inZoomAnimation) {
return;
}
if (this._shownPolygon) {
map.removeLayer(this._shownPolygon);
}
if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
map.addLayer(this._shownPolygon);
}
},

javascript easelJs onPress enlarge image circle

Working with javascript and the Easeljs lib and createjs, i need some help.
my program draws some circles and fills them with color. also with a Ticker they are moving and with some if statements they are bouncing from the walls of the window.
The circles are created dynamicly and the amount of circles is different everytime.
Now I need to implement a feature so that the circles will enlarge when you press them. They should get their radius +1px bigger every 30 ms. I don't know how to do that.
1. Do u use onPress for this?which callbacks do i need to use and how will i find out if the mouse is released and the circle can stop growing?
2. do i need to delete circleObject from my circlesArray or is it enough to delete it from the stage and draw them again?
I'm desperate for help, i would be glad if someone could give me some clues!
Greetings T
With the information you provided I would refer you to take a look at this EaselJS Example on github: https://github.com/CreateJS/EaselJS/blob/master/examples/DragAndDrop_hitArea.html
The onPress-Method is used there in a way that you could probably almost copy as is.
Yours could look like this:
function(target){
target.onPress = function(evt) {
target.grow = true; //or a grow-factor or so
evt.onMouseUp = function(ev) {
target.grow = false;
}
}
}(circle);
and in your tick-function you look through all circles, check for their grow==true and increase their radius if so
And 2:
Your circleObjects all are a createjs.Shape right? You don't have to delete them from the stage or from the array, you can use circle.graphics.clear(); and then redraw the circle with the new radius.

Per pixel collision detection in Javascript/Jquery/Gamequery

I am trying to program a web game in Jquery with the GameQuery plugin, problem is the GameQuery plugin has no support for per pixel collision detection only collision detection with bounding boxes. Is it possible to implement per pixel collision detection in javascript/Jquery?
I have a world map with countries and a player which is moved using the arrow keys, I want to be able to tell which country the player is in at any time and the countries are irregular shapes.
Or attack it from a different angle...so to speak...
Vectors may be your key, cool stuff happening at http://www.raphaeljs.com
maybe some sort of combo/integration could work?
alright here is kind of a solution:
assign each country a different color in you map (do not assign special colors to borders, borders should be colored in either color of the countries).
load that image into a canvas
var img = new Image();
img.src = 'worldmap.png';
var map = document.getElementById('canvas').getContext('2d');
map.drawImage(img, 0, 0);
after that you can display your normal map above that map (it is only a reference, and can be hidden under other stuff - use divs and z-index for that).
to determine in which country the player is just get the pixel-data at his position
data = map.getImageData(x, y, 1, 1).data;
key = data.join("-"); // something like "255-0-0-255" for red
country = countries[key];
it should be an rgba-array, you may then look up what country is assigned to that color.
so you will have to keep an array with the imploded rgba-values as key and the country names as value.
countries = {
"255-0-0-255" : "Russia",
"255-0-255-255" : "China",
...
};
this does only work in browsers that have the canvas object. so if you are doing this on iphone or android you are lucky!
The images are just pngs with solid colours for the country and transparency for the rest.
It is not possible.
You have, however, a not very complicated alternative: use polygon-based collision.
Use an image to present the countries to the user, but use a polygon internally.
You may find a very complete explanation about how to implement this on this forum entry (you may have to scroll down a bit, until you see the images). The guy asking the question there wanted to do more or less the same as you want todo (mouse position instead of character position).
Regards!

Categories

Resources