There are a couple of things wrong with this plunk.
First, there's no reason to use ng-model here. Just set it as a scope variable, seeing as you are editing it from the controller anyway.
Second, mousemove will execute continuously. Every time you move the mouse it's going to create a new timeout and it's not going to cancel the old one. This is why it flickers. It's also very inefficient to call this function and constanly make calls to $timeout.cancel() and $timeout(function() { }, 3000).
Instead consider using mouseenter and mouseleave and make sure you cancel old timeouts.
HTML
<div ng-app="myApp" ng-controller="myController">
<div class="mousemove" ng-mouseenter="enter()" ng-mouseleave="leave()"></div>
<div class="show" ng-show="loading"></div>
</div>
Javascript
var myApp = angular.module('myApp',[]);
myApp.controller('myController', function($scope, $timeout) {
var timeoutCanceller = null;
$scope.loading = false;
$scope.enter = function() {
cancelTimeout();
$scope.loading = true;
};
$scope.leave = function() {
timeoutCanceller = $timeout(function() {
$scope.loading = false;
}, 3000);
};
function cancelTimeout() {
if (timeoutCanceller) $timeout.cancel(timeoutCanceller);
}
});
Here is a working demo.
Edit: Might also be a good idea to bind those events to a parent container instead of directly on the element. If that loader is an overlay bringing that up might accidentally call the mouseleave event. Also gives you more options for styling.
<div ng-app="myApp" ng-controller="myController">
<div ng-mouseenter="enter()" ng-mouseleave="leave()">
<div class="mousemove"></div>
<div class="show" ng-show="loading"></div>
</div>
</div>