I've been implementing some very similar collide-and-slide collision detection and resolution. http://metareal.net/blog/wp-content/uploads/2015/08/2015-08-21.jpg
The main key I found was to handle X and Y separately. So, your code might be modified something like this (a little freeform but you should get the idea):
// step 1, modify X
prevX = x;
x += movementX;
work out top, left, bottom, right
if(new span collides with anything) x = prevX;
// step 2, modify Y
prevY = y;
y += movementY;
work out top, left, bottom, right
if(new span collides with anything) y = prevY;
In certain cases, the order of checking x and y will make a difference. Specifically, heading directly onto a colliding corner will now favor X movement. This is probably ok, but can be changed if you need. (Literally a corner case!)
Hope that helps a little.