<svg id="svg" viewBox="0 0 800 400">
  <polygon id="star" points="461,220 498,335 400,264 302,335 339,220 242,149 362,148 400,34 438,148 558,149" />
  <circle id="dot" r="8" fill="red" />
</svg>
body {
  background: #e8e9e8;
  font-family:sans-serif;
  color:#555;
}

#svg {
  position: fixed;
  top: 20px;
  left: 0;
  width: 100%;
  height: 100%;
}

#star {
  stroke: #29e;
  stroke-width: 5;
  stroke-linejoin: round;
  fill: none;
}
//play with the xVelocity and yVelocity values - it'll always land on a point of the star (unless it's beyond the snapDistance or snapToStar is false)
var xVelocity = 310,
    yVelocity = 120,
    snapToStar = true,
    snapDistance = 1000,
    starPoints = pointsToArray(document.getElementById("star")),
    dot = document.getElementById("dot");

gsap.to(dot, {
  inertia: {
    x: {
      velocity: xVelocity, 
      end: snap
    },
    y: {
      velocity: yVelocity, 
      end: snap
    },
    linkedProps: "x,y" //<- this is the key that makes x and y get combined into an object and passed to the "end" function
  }
});

/*
The object that gets passed as the only parameter to the "end" function will have the properties are listed in linkedProps. So, for example, if linkedProps is "x,y", then an object like {x:100, y:140} gets passed to the function as a parameter. Those values are the natural ending values, but of course your function should return a similar object with the new values you want the end values to be, like return {x:200, y:300}. 
*/

//finds the closest point in the starPoints array to the one provided (within the snapDistance). 
function snap(p) {
  var i = starPoints.length,
      closest = 0,
      minDist = 999999999,
      x, y, point, dist;
  if (!snapToStar) {
    return p;
  }
  while (--i > -1) {
    point = starPoints[i];
    x = point.x - p.x;
    y = point.y - p.y;
    dist = x * x + y * y;
    if (dist < minDist) {
      closest = i;
      minDist = dist;
    }
  }
  return (minDist <= snapDistance * snapDistance) ? starPoints[closest] : p;
}

//returns all the SVGPoints in a <polygon> or <polyline> as an array. (note: not all browsers support [].slice.call(element.points) which is why we need this function)
function pointsToArray(element) {
  var points = element.points,
      result = [],
      i;
  for (i = 0; i < points.numberOfItems; i++) {
    result[i] = points.getItem(i);
  }
  return result;
}

//or if you'd rather enable tracking on the x/y properties and have ThrowPropsPlugin 
//just take over in the middle of some other motion which we're simulating here with 
//a simple x/y tween, here's an example of that...
/* 
InertiaPlugin.track(dot, "x,y");
gsap.to(dot, {duration: 3, x: 420, y: 190});
//halfway through the tween, take over...
gsap.delayedCall(1.5, function() {
  gsap.to(dot, {
    inertia:{
      x: {velocity: "auto", end: snap},
      y: {velocity: "auto", end: snap},
      linkedProps: "x,y"
    }
  });
});
*/

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.2/gsap.min.js
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/InertiaPlugin.min.js