Bezier Curve Formula

Using percentage positions

by Ben Clayton

HTML

<div class="expand-wrapper">

    <div class="group-wrapper rtj-wrapper">

        <div id='man' ><img src='//hub.lrsuntory.com/images/dyn/000000-100.png' width=2 height=2 /></div>
        <div id='C1' class="epoint" ><img src='//hub.lrsuntory.com/images/dyn/ff0000-100.png' width=1 height=1 /></div>
        <div id='C2' class="cpoint" ><img src='//hub.lrsuntory.com/images/dyn/0000ff-100.png' width=1 height=1 /></div>
        <div id='C3' class="cpoint" ><img src='//hub.lrsuntory.com/images/dyn/0000ff-100.png' width=1 height=1 /></div>
        <div id='C4' class="epoint" ><img src='//hub.lrsuntory.com/images/dyn/ff0000-100.png' width=1 height=1 /></div>

        <div class="group-wrapper rtj-header">
            <div class="group-wrapper rtj-distance-travel">
                <div class="group-wrapper rtj-complete-live" style="width: 22.39%;"></div>
                <div class="group-wrapper rtj-remaining-live" style="width: 77.61%;"></div>
            </div>
        </div>
        <div class="group-wrapper rtj-completion-marker-live"></div>
        
        <div style="width:100%" class="-sys-dbnewpicture map">
            <img src="//hub.lrsuntory.com/images/spacer.gif" style="width: 100%; height:260px; background-image: url(//hub.lrsuntory.com/dyn/_pictures/race-to-japan/artworkv2.jpg);" class="-sys-dbnewpicture-img heightset bck" alt="artworkv2" title="artworkv2" data-aspectratio="0.5625" />
		
        </div>
 
    </div>            
</div>

CSS

* {
  box-sizing: border-box;
  -webkit-box-sizing: border-box;
}
.rtj-wrapper {
  position: relative;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  border:1px solid red;
}
.rtj-wrapper .rtj-complete-live,
.rtj-wrapper .rtj-remaining-live {
  position: absolute;
  height: 100%;
  bottom: 0;
  top: 0;
  background-size: auto 108%;
  background-repeat: no-repeat;
  z-index: 2;
    opacity:0.1;    
 }

.rtj-wrapper .rtj-complete-live {
  left: 0;
  background-image: url('//hub.lrsuntory.com/dyn/_pictures/race-to-japan/line-complete.png');
  background-position: left center;
    opacity:0.4;    
}



.rtj-wrapper .rtj-remaining-live {
  right: 0;
  background-image: url('//hub.lrsuntory.com/dyn/_pictures/race-to-japan/line-remaining.png');
  background-position: right center;
}

.rtj-wrapper .rtj-completion-marker-live {
  position: absolute;
  background-image: url('//hub.lrsuntory.com/dyn/_pictures/race-to-japan/character2-1.png');
  background-size: 80% ;
  xbackground-size: 400% 100%;

  background-repeat: no-repeat;
  background-position: right center;
  /* background-color:#e0e0e0; */
  opacity:0.9;    
  z-index: 3;
}
.-sys-dbnewpicture .-sys-dbnewpicture-img {
  width: 100%;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center center;
  overflow: hidden;
  display: block;
}
.-sys-dbnewpicture-img.bck {
    opacity:0.1;    
}

#man {
    position:absolute;
     z-index: 4;
}
.epoint {
    position:absolute;
    z-index: 4;
}
.cpoint {
    position:absolute;
    z-index: 4;

}

JavaScript

//====================================\\
// 13thParallel.org Beziér Curve Code \\
//   by Dan Pupius (www.pupius.net)   \\
// http://www.13thparallel.org/archive/bezier-curves/  \\
//====================================\\

var percent=0;
var y1=48;
var x1=10;
var x2=93;
var cx=24;
var cy=24;

var map_aspect = $('.map img').data('aspectratio');

console.log('map aspect',map_aspect);

coord = function (x,y) {
  x= x | 0;
  y= y | 0;
  return {x: x, y: y};
}

positioncoord = function(jref,cord){      
    $(jref).css({top:cord.y+'%',left:cord.x+'%'});
}

position_man = function(percent,cord){  
    var s = (y1 - cord.y)/2 +5;
    var h = s/map_aspect;
    var w = s; 
    $('.rtj-completion-marker-live').css({
        top:(cord.y -h+5.5) +'%',// -h to make man stands on line, not hang below
        left:(cord.x -(w/2) ) +'%',// -(w/2) middle of man (between his feet) above ref point
        width:w+'%',
        height:h+'%'
     });
}

position_track = function(x){      
    $('.rtj-complete-live').width(x+'%');
    $('.rtj-remaining-live').width((100-x)+'%');
}


function B1(t) { return (1-t)*(1-t)*(1-t) }
function B2(t) { return 3*t*(1-t)*(1-t) }
function B3(t) { return 3*t*t*(1-t) }
function B4(t) { return t*t*t }

function getBezier(percent,C1,C2,C3,C4) {
  var pos = new coord();
  pos.x = C1.x*B1(percent) + C2.x*B2(percent) + C3.x*B3(percent) + C4.x*B4(percent);
  pos.y = C1.y*B1(percent) + C2.y*B2(percent) + C3.y*B3(percent) + C4.y*B4(percent);
  return pos;
}

function doit(){
    var manpos = getBezier(percent,C1,C2,C3,C4)
    console.log(percent,manpos);
    positioncoord('#man',manpos);//debug
    position_man(percent,manpos);
    position_track(manpos.x);
    if (percent<=1){
        percent+=0.002;  
        setTimeout(doit,40);
    }
}

var C1 = coord(x1,y1);// UK start point as x% y%
var C2 = coord(x1+cx,y1-cy);// bezier control point as x% y%
var C3 = coord(x2-cx,y1-cy);// bezier control point as x% y%
var C4 = coord(x2,y1);// JAPAN endpoint as x%...