feat(snapping): add basic snapping implementation