-1

Let's suppose we have a virtual map, like this:

Map Example

This is just an example, the map can have different content and/or size. Let us suppose that we know the location of each house, which is located either in a circle, a rectangle or a polygon. Let's suppose further that we want to "animate a walk" from an arbitrary house1 to an arbitrary house2.

By "animate a walk" I mean that the road starting at house1 and ending at house2 should be temporally be colored, let's say, to red in a continuous fashion, that is, the animation should get the following parameters:

  • house1
  • house2
  • time

The road part should not be colored instantly, but based on a variable of time. The road initially should not be colored, then after t time elapsed, t/time of the road should be colored, with the direction of house1 -> house2.

I thought about using a map, like this:

                <img id="img-map" src="/img/maps/mymap.png" alt="" usemap="#Map" />
                <map name="Map" id="Map">
                    <area alt="" title="Babuka" href="" shape="poly" coords="189,433,179,456,185,479,208,484,235,481,236,459,217,439" />
                    <area alt="" title="Sheldonka" href="" shape="poly" coords="304,277,297,294,301,309,321,314,341,312,341,296,326,279" />
                    <area alt="" title="Herceg" href="" shape="poly" coords="95,278,114,287,128,283,128,275,122,267,104,262,95,269" />
                    <area alt="" title="Babuka elment Sheldonkahoz" href="#" shape="poly" coords="220,494,227,500,247,494,268,486,283,477,305,468,321,458,336,451,345,444,355,429,357,416,353,403,345,389,329,359,312,335,307,328,305,326,313,327,321,327,329,326,335,326,337,317,323,317,313,318,302,320,293,319,293,327,300,333,306,339,310,351,320,364,327,372,333,384,337,392,341,400,342,407,345,413,345,417,345,423,345,428,339,439" />
                </map>

One can create event handlers for areas, which is a very nice thing, since it would be cool to be able to catch click/hover, etc. events for the houses, but how would we handle the animation described above? I thought about temporarily displaying a canvas over the map, but that seems to be too hacky. Also, I thought about saving possible start/end points to the front of each house onto the road, so, at least when the animation starts, the system will know where to start and where to end. Knowing these two points in addition to a pattern for the road (possibly a color) the arc can be determined. Based on the arc, its length and total area (number of pixels) can be determined as well. If we know the total length and the time specified for the animation length, then the animation can be one using temporary pixel coloring.

This would be done either using a map and temporarily putting a canvas over it while the animation is being done or using only a canvas. How should this problem be solved taking into account the desired effect?

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • We need more information about the walkways? For example, are they created "freehand" in Photoshop or Illustrator. Are they built from vector paths? – markE Mar 03 '16 at 20:44
  • @markE, the roads were created with Photoshop, the potential start and end point of the houses will be defined manually, they will be points close to the related house. I very much thank you for your answer, I will (hopefully) soon reflect on it. – Lajos Arpad Mar 04 '16 at 09:21

1 Answers1

1

First determine the path of your road between your houses

Check out this previous Stackoverflow Q&A which shows how to determine a set of curves that pass through waypoints along your road. This set of curves is an html5 canvas path.

Then travel the road by calculating a uniform set of waypoints along that path

Then check out this previous Stackoverflow Q&A which shows how to travel along a path at a uniform speed.

Here's example code and a Demo:

This example shows how to travel along a path at a uniform speed.

enter image description here

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var nextTime=0;
var delay=1000/60*3;
var ptIndex=0;

var linepts=[{x:50,y:75},{x:150,y:50},{x:200,y:100},{x:100,y:175},{x:250,y:250}];
var points=[];
for(var i=1;i<linepts.length;i++){
    points=points.concat(plotLinePoints(linepts[i-1],linepts[i],5));
}

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house32x32transparent.png";
function start(){
    var last=linepts.length-1;
    unfilledStroke(linepts,25);
    ctx.drawImage(img,linepts[0].x-img.width-15,linepts[0].y-img.height);
    ctx.drawImage(img,linepts[last].x+img.width/2,linepts[last].y);
    requestAnimationFrame(animatePath);
}

function animatePath(time){
    ctx.beginPath();
    ctx.moveTo(points[ptIndex].x, points[ptIndex].y);
    ctx.lineTo(points[ptIndex+1].x, points[ptIndex+1].y);
    ctx.lineWidth=5;
    ctx.strokeStyle='red';
    ctx.stroke();
    ptIndex++;
    if(ptIndex<points.length-1){
        requestAnimationFrame(animatePath);
    }
}

function path(pts){
    ctx.beginPath();
    ctx.moveTo(pts[0].x,pts[0].y);
    for(var i=1;i<pts.length;i++){
        ctx.lineTo(pts[i].x,pts[i].y);
    }
}

function unfilledStroke(pts,linewidth){
    ctx.lineWidth=linewidth;
    ctx.lineCap='round';
    ctx.lineJoin='round';
    path(pts);
    ctx.stroke();
    //
    ctx.globalCompositeOperation='destination-out';
    ctx.lineWidth=linewidth/2;
    ctx.lineCap='round';
    path(pts);
    ctx.stroke();
    ctx.globalCompositeOperation='source-over';
}

function plotLinePoints(s,e,pctIncrement){
    var dx=e.x-s.x;
    var dy=e.y-s.y;
    var pts=[s];
    for(var p=pctIncrement;p<100;p+=pctIncrement){
        pts.push({
            x:s.x+dx*p/100,
            y:s.y+dy*p/100
        });
    }
    pts.push(e);
    return(pts);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=400 height=300></canvas>
Community
  • 1
  • 1
markE
  • 102,905
  • 11
  • 164
  • 176