Обработчик события на mousemove/анимация

183
20 апреля 2017, 16:28

Добрый день уважаемые. Подскажите пожалуйста, как написать правильно функцию которая будет следить за положением курсора на экране и смещать блоки (через transform: translateX translateY), но на ограниченное пространство для каждого блока? Вот пример

var bl1 = $(".block1"), 
  bl2 = $(".block2"), 
  bl3 = $(".block3"), 
  bl4 = $(".block4"); 
 
var doc = { 
  w: $(window).width(), 
  h: $(window).height(), 
  wC: $(window).width() / 2, 
  hC: $(window).height() / 2 
}; 
var mouse = { 
  x: 0, 
  y: 0 
}; 
 
$(window).resize(function() { 
  doc = { 
    w: $(window).width(), 
    h: $(window).height(), 
    wC: $(window).width() / 2, 
    hC: $(window).height() / 2 
  } 
}); 
 
$(window).mousemove(function(e) { 
  mouse.x = ((e.pageX - doc.w + doc.wC) / (doc.wC / 50)); 
  mouse.y = ((e.pageY - doc.h + doc.hC) / (doc.hC / 50)); 
 
  bl1.css('transform', 'translate(' + mouse.x + 'px, ' + mouse.y + 'px)'); 
 
});
.wrappen { 
  position: relative; 
  width: 400px; 
  height: 400px; 
  border: 1px solid #000; 
  margin: 0 auto; 
} 
 
.block1 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -75px; 
  margin-top: -75px; 
  background: red; 
  width: 150px; 
  height: 150px; 
} 
 
.block2 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -50px; 
  margin-top: -50px; 
  background: gold; 
  width: 100px; 
  height: 100px; 
} 
 
.block3 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -40px; 
  margin-top: -40px; 
  background: pink; 
  width: 80px; 
  height: 80px; 
} 
 
.block4 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -20px; 
  margin-top: -20px; 
  background: green; 
  width: 40px; 
  height: 40px; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="wrappen"> 
  <div class="block1"> </div> 
  <div class="block2"> </div> 
  <div class="block3"> </div> 
  <div class="block4"></div>   
</div>

но он немного не коректен, мне необходимо что б первый блок мог смещаться в приделах по Х ( -14 до 14) и по Y ( от -13 до 12), как бы следя за курсором, ну и с остальными блоками аналогично, только что б реакция отклика была скажем по +40мс (с небольшой задержкой) на каждый новый блок?

Answer 1

Есть простой способ решить такую задержку, называется Slow Parent.

Для простоты я записал текущее отклонение в bl.data('x') и bl.data('y'). Тогда координата будет рассчитываться как среднее арифметическое между текущим положением и положением рассчитанным от положения мыши:

 bl.data('x', (mouse.x + 1*bl.data('x')*(i-1))/i);

Где i номер блока. Итого функция которая будет рисовать кадр анимации:

function draw() {
  for (i = 1; i <= 4; i++) {
    bl=$(".block"+i)
    bl.data('x', (mouse.x + 1*bl.data('x')*(i-1))/i);
    bl.data('y', (mouse.y + 1*bl.data('y')*(i-1))/i);
    bl.css('transform', 'translate(' + bl.data('x') + 'px, '
                                     + bl.data('y') + 'px)');
  }
}

Остальное - дело техники. Создаем кроссплатформенный requestAnimationFrame():

window.requestAnimFrame = function() {
  return (
    window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    }
  );
}();

И делаем на основе него функцию анимации:

function animate() {
  requestAnimFrame(animate);
  draw();
}

Ограничить координаты можно таким образом:

   mouse.x=Math.min(20,Math.max(-20,mouse.x))
   mouse.y=Math.min(20,Math.max(-20,mouse.y))

Рабочий код:

var bl1 = $(".block1"), 
  bl2 = $(".block2"), 
  bl3 = $(".block3"), 
  bl4 = $(".block4"); 
 
var doc = { 
  w: $(window).width(), 
  h: $(window).height(), 
  wC: $(window).width() / 2, 
  hC: $(window).height() / 2 
}; 
var mouse = { 
  x: 0, 
  y: 0 
}; 
 
 
$(window).resize(function() { 
  doc = { 
    w: $(window).width(), 
    h: $(window).height(), 
    wC: $(window).width() / 2, 
    hC: $(window).height() / 2 
  } 
}); 
 
 
window.requestAnimFrame = function() { 
  return ( 
    window.requestAnimationFrame || 
    window.webkitRequestAnimationFrame || 
    window.mozRequestAnimationFrame || 
    window.oRequestAnimationFrame || 
    window.msRequestAnimationFrame || 
    function(callback) { 
      window.setTimeout(callback, 1000 / 60); 
    } 
  ); 
}(); 
 
function animate() { 
  requestAnimFrame(animate); 
  draw(); 
} 
 
  for (i = 1; i <= 4; i++) { 
     $(".block"+i).data('x',0); 
     $(".block"+i).data('y',0); 
       
  } 
 
function draw() { 
  
  for (i = 1; i <= 4; i++) { 
    bl=$(".block"+i) 
    bl.data('x', (mouse.x + 1*bl.data('x')*(i-1))/i); 
    bl.data('y', (mouse.y + 1*bl.data('y')*(i-1))/i); 
   
    bl.css('transform', 'translate(' + bl.data('x') + 'px, ' 
                                     + bl.data('y') + 'px)'); 
 
  } 
} 
 
 
 
animate(); 
 
$(window).mousemove(function(e) { 
 
  mouse.x = ((e.pageX - doc.w + doc.wC) / (doc.wC / 50)); 
  mouse.y = ((e.pageY - doc.h + doc.hC) / (doc.hC / 50)); 
 
   mouse.x=Math.min(20,Math.max(-20,mouse.x)) 
   mouse.y=Math.min(20,Math.max(-20,mouse.y)) 
    
});
.wrappen { 
  position: relative; 
  width: 400px; 
  height: 400px; 
  border: 1px solid #000; 
  margin: 0 auto; 
} 
 
.block1 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -75px; 
  margin-top: -75px; 
  background: red; 
  width: 150px; 
  height: 150px; 
} 
 
.block2 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -50px; 
  margin-top: -50px; 
  background: gold; 
  width: 100px; 
  height: 100px; 
} 
 
.block3 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -40px; 
  margin-top: -40px; 
  background: pink; 
  width: 80px; 
  height: 80px; 
} 
 
.block4 { 
  position: absolute; 
  top: 50%; 
  left: 50%; 
  margin-left: -20px; 
  margin-top: -20px; 
  background: green; 
  width: 40px; 
  height: 40px; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="wrappen"> 
  <div class="block1"> </div> 
  <div class="block2"> </div> 
  <div class="block3"> </div> 
  <div class="block4"></div> 
</div>

READ ALSO
Какой препроцессор CSS сейчас актуален? [требует правки]

Какой препроцессор CSS сейчас актуален? [требует правки]

Пробовал LESS и SassНо всё же может использовать другой, за которым будущее, ваш совет как всегда очень кстати

233
Позиционирование фона от правого края

Позиционирование фона от правого края

Мне нужно спозиционировать фоновое изображение таким образом, чтобы правая половина экрана была без фона, а левая половина была с фоновой...

216
MySQL ошибка: unknown option &#39;--no-beep&#39;

MySQL ошибка: unknown option '--no-beep'

Столкнулся с ошибкой: unknown option '--no-beep', вычитал, что нужна правка конфигурационного файла myini

346