使图像轻松跟随鼠标在HTML5画布 [英] Make image follow mouse with ease in HTML5 Canvas

查看:260
本文介绍了使图像轻松跟随鼠标在HTML5画布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个HTLM5画布工作,我想让一个图像跟随鼠标光标一些轻松。问题是每次我移动鼠标的图像位置被重置为原点(我相信)。



这是我的代码:



  var AN = AN || {}; pic = new Image(); AN.initialize = function(){//监听鼠标行为并在每次移动时读取window.addEventListener(mousemove,AN.moveMouse,false); // load canvas cv = $('#canvas')[0]; canvas = cv.getContext('2d'); // load image pic.src =http://fc01.deviantart.net/fs71/f/2014/349/b/e/i_hate_you__i_love_you__zoro_x_reader__by_riseagisestevil-d88ovwj.png\";};AN.moveMouse = function(e){/ /获取鼠标位置var xPos = e.clientX; var yPos = e.clientY; var position = getPosition(pic); var x = xPos-pic.width / 2; // final position var y = yPos  -  pic.height / 2; // final position var t = 0; // 0-1,这是你在动画循环中改变var tx = position.x; // x的元素的实际位置var ty = position.y; // y的元素的实际位置function myLoop(){canvas.clearRect(0,0,600,600); tx = EasingFunctions.easeInOutQuad(t)* x; ty = EasingFunctions.easeInOutQuad(t)* y; //如果你需要Y,然后做相同的(ty)//集合元素通过tx canvas.drawImage(pic,tx,ty,pic.width,pic.height); position = getPosition(pic); if(t <1){t + = 0.01; //确定速度requestAnimationFrame(myLoop); // setTimeout(myLoop,16); // option to above}} myLoop();}; EasingFunctions = {linear:function(t){return t; },easeInQuad:function(t){return t * t; },easeOutQuad:function(t){return t *(2  -  t); },easeInOutQuad:function(t){return t& .5? 2 * t * t:-1 +(4-2 * t)* t; },easeInCubic:function(t){return t * t * t; },easeOutCubic:function(t){return( -  t)* t * t + 1; },easeInOutCubic:function(t){return t< .5? 4 * t * t * t:(t-1)*(2 * t-2)*(2 * t-2) },easeInQuart:function(t){return t * t * t * t; },easeOutQuart:function(t){return 1  - ( -  t)* t * t * t; },easeInOutQuart:function(t){return t< .5? 8 * t * t * t * t:1  -  8 *( -  t)* t * t * t; },easeInQuint:function(t){return t * t * t * t * t; },easeOutQuint:function(t){return 1 +( -  t)* t * t * t * t; },easeInOutQuint:function(t){return t& .5? 16 * t * t * t * t * t:1 + 16 *( -  t)* t * t * t * t; }} function getPosition(element){var xPosition = 0; var yPosition = 0; while(element){xPosition + =(element.offsetLeft  -  element.scrollLeft + element.clientLeft); yPosition + =(element.offsetTop  -  element.scrollTop + element.clientTop); element = element.offsetParent; } return {x:xPosition,y:yPosition};} $(document).ready(function(){// initialize funtion AN.initialize();});  

 < script src =https://ajax.googleapis.com/ajax/libs/jquery/1.8.1 /jquery.min.js\"> ;</script> ;<section id =main> < / canvas>< / section> < canvas id =canvaswidth =600pxheight =600px>升级到现代浏览器以查看此绘画; / pre> 



有关如何阻止它回到中心并使其保持在实际位置的任何想法? / p>

谨慎,
Iniestar

解决方案



基本上,它归结为两件事情。



我立即在您的代码中注意到了这一点:

  var tx = position.x; //元素的实际位置x 
var ty = position.y; //元素的实际位置y

在你的主循环中跟着这个:

  tx = EasingFunctions.easeInOutQuad(t)* x; 
ty = EasingFunctions.easeInOutQuad(t)* y;

我假设你要考虑tx的位置,立即覆盖它,使它多余!至于数学,缓和是正确的,但你不是真的考虑一个新的鼠标位置,它是如何影响的东西。



想象你有一条线从图像的中心一直运行到鼠标位置。当你考虑时间t时,你得到向量线方程: r = r0 + tv 。这个方程式简单地说明,为了得到点 r ,你提供一个点 r0 ,方向向量 v 和一些标量 t



this,

  x + = EasingFunctions.easeInOutQuad(t)*(position.x  -  x); 
y + = EasingFunctions.easeInOutQuad(t)*(position.y-y);

y 指的是图像的当前位置。你总是需要修改这个,所以你的图像实际上正确移动,考虑到其最后的位置。因为它是添加自己,你可以认为它 r0 在方程式。您的宽松函数提供标量值 t ,而位置只是最后一点(即您的鼠标坐标)。然而,这个位置需要是一个向量,所以通过使用 B - A ,我们可以使用两个端点 - 鼠标和图像位置。



以下是小提琴


I'm working in a HTLM5 Canvas where I'm trying to make an image follow mouse cursor with some ease. The problem is every time I move the mouse the image position is reset to origin (I believe). I wanted to keep actual position and from there move to mouse new position.

Here is my code:

var AN = AN || {};

pic = new Image();

AN.initialize = function() {
  //listen to mouse behavior and read every time he moves
  window.addEventListener("mousemove", AN.moveMouse, false);
  //load canvas
  cv = $('#canvas')[0];
  canvas = cv.getContext('2d');
  //load image
  pic.src = "http://fc01.deviantart.net/fs71/f/2014/349/b/e/i_hate_you__i_love_you__zoro_x_reader__by_riseagainstevil-d88ovwj.png";
};


AN.moveMouse = function(e) {

  //get mouse position
  var xPos = e.clientX;
  var yPos = e.clientY;

  var position = getPosition(pic);

  var x = xPos - pic.width / 2; //final position
  var y = yPos - pic.height / 2; //final position
  var t = 0; //0-1, this is what you change in animation loop
  var tx = position.x; //actual position of element for x
  var ty = position.y; //actual position of element for y

  function myLoop() {

    canvas.clearRect(0, 0, 600, 600);

    tx = EasingFunctions.easeInOutQuad(t) * x;
    ty = EasingFunctions.easeInOutQuad(t) * y;

    //if you need Y then do the same for that (ty)

    // set element by tx
    canvas.drawImage(pic, tx, ty, pic.width, pic.height);
    position = getPosition(pic);

    if (t < 1) {
      t += 0.01; //determines speed
      requestAnimationFrame(myLoop);
      //setTimeout(myLoop, 16); //option to above
    }
  }
  myLoop();
};

EasingFunctions = {
  linear: function(t) {
    return t;
  },
  easeInQuad: function(t) {
    return t * t;
  },
  easeOutQuad: function(t) {
    return t * (2 - t);
  },
  easeInOutQuad: function(t) {
    return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
  },
  easeInCubic: function(t) {
    return t * t * t;
  },
  easeOutCubic: function(t) {
    return (--t) * t * t + 1;
  },
  easeInOutCubic: function(t) {
    return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
  },
  easeInQuart: function(t) {
    return t * t * t * t;
  },
  easeOutQuart: function(t) {
    return 1 - (--t) * t * t * t;
  },
  easeInOutQuart: function(t) {
    return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
  },
  easeInQuint: function(t) {
    return t * t * t * t * t;
  },
  easeOutQuint: function(t) {
    return 1 + (--t) * t * t * t * t;
  },
  easeInOutQuint: function(t) {
    return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;
  }
}

function getPosition(element) {
  var xPosition = 0;
  var yPosition = 0;

  while (element) {
    xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
    yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
    element = element.offsetParent;
  }
  return {
    x: xPosition,
    y: yPosition
  };
}

$(document).ready(function() {
  //initialize funtion
  AN.initialize();
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<section id="main">
  <canvas id="canvas" width="600px" height="600px">Upgrade to modern browser in order to see this painting ;)</canvas>
</section>

Any idea on how to stop it from going back to center and make it stay in actual position?

Regards, Iniestar

解决方案

Alright, so I messed around quite a lot with your code so I apologise there.

Essentially, it comes down to two things. You aren't keeping track of the image's position correctly and are applying the wrong mathematics.

I noticed this immediately in your code:

var tx = position.x; //actual position of element for x
var ty = position.y; //actual position of element for y

Followed by this in your main loop:

tx = EasingFunctions.easeInOutQuad(t) * x;
ty = EasingFunctions.easeInOutQuad(t) * y;

I'm assuming you're trying to take into account the position of tx, but you're overwriting it immediately, making it redundant! As for the maths, the easing is correct, but you're not really considering a new mouse position and how it has an effect on things.

Imagine you have a line running from the centre of the image to the mouse position at all times. When you factor in time, t, then you get the vector line equation: r = r0 + tv. This equation simply states that to get the point r, you supply a point r0, the direction vector v and some scalar t.

I modified your code to do exactly this,

x += EasingFunctions.easeInOutQuad(t) * (position.x - x);
y += EasingFunctions.easeInOutQuad(t) * (position.y - y);

x and y refer to the current position of your image. You always need to modify this so your image actually moves around correctly taking into account its last position. Since it is adding itself on, you can consider it as r0 in terms of the equation. Your easing function provides the scalar value t while the position is simply the final point (i.e. your mouse coordinates). However, this position needs to be a vector and so by using B - A we can achieve that by using two endpoints - the mouse and image position.

Here's the fiddle

这篇关于使图像轻松跟随鼠标在HTML5画布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆