Javascript为什么当我在`mousemove`中使用drawImage时,我的图像会变坏?

时间:2016-11-12 13:08:13

标签: javascript canvas html5-canvas

我想在动作鼠标移动时绘制一个图像,但是当我在mousemove中使用drawImage时,我会得到不好的图像(见右图):

enter image description here

为什么在操作mousemove

时图像被严重绘制

P.S。:我想用质量左图像绘制正确的图像;

var canvas = document.getElementById('canvas_test');
var context = canvas.getContext("2d");
var img_test__src = 'http://image.prntscr.com/image/8233c5a42e7e4b40a19c64d8e9b892ee.png';

var img = new Image();
img.src = img_test__src;
img.onload = function() {
  context.save();
  context.beginPath();
  context.drawImage(img, 100, 100, 71, 71);
  context.closePath();
  context.restore();
};

canvas.addEventListener('mousemove', function(evt) {
  var img = new Image();
  img.src = img_test__src;
  img.onload = function() {
    context.save();
    context.beginPath();
    context.drawImage(img, 200, 100, 71, 71);
    context.closePath();
    context.restore();
  };
});
#canvas_test {
  background: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas_test" width="500" height="500"></canvas>

2 个答案:

答案 0 :(得分:3)

您可以一次多次绘制图像。所以它重叠,你看到了这种效果。将mouseenter更改为mousemove,当您第一次进入时,它会正常工作。如果再次输入,由于多次绘制时的alpha重叠,您甚至会看到一个工件。

如果必须使用import java.sql.DriverManager; import java.sql.Connection; import java.sql.SQLException; public class Connect { public static void main(String[] argv) { System.out.println("-------- PostgreSQL " + "JDBC Connection Testing ------------"); try { Class.forName("org.postgresql.Driver"); } catch (ClassNotFoundException e) { System.out.println("Where is your PostgreSQL JDBC Driver? " + "postgresql-9.2-1002.jdbc4.jar"); e.printStackTrace(); return; } System.out.println("PostgreSQL JDBC Driver Registered!"); Connection connection = null; try { connection = DriverManager.getConnection( "jdbc:postgresql://localhost:5432/postgres", "postgres", "postgres"); } catch (SQLException e) { System.out.println("Connection Failed! Check output console"); e.printStackTrace(); return; } if (connection != null) { System.out.println("You made it, take control your database now!"); } else { System.out.println("Failed to make connection!"); } } } 或其他多次触发的事件,请在绘制前清除画布区域以省略此情况。

https://jsfiddle.net/uy55o8v5/

答案 1 :(得分:2)

从不在IO事件中进行渲染

如果可能的话,你永远不应该在事件中渲染。频率和时间是你无法控制的,它会产生各种各样的问题,特别是当你开始有很多这样的事情发生时。

使用requestAnimationFrame即使只是一帧也是如此。这将确保正确绘制图像并与正在发生的任何其他动画或视觉更新同步。

不要一遍又一遍地加载图片!!!

我必须给出一个答案,因为你还在事件中加载图像。

每次鼠标移动,每秒可能大约100或更多,你创建一个新图像并等待它加载。您应该已经注意到页面有时会滞后。

加载图像一次。

示例

我假设您想要鼠标超过FX

var canvas = document.getElementById('canvas_test');
var context = canvas.getContext("2d");
var img_test__src = 'http://image.prntscr.com/image/8233c5a42e7e4b40a19c64d8e9b892ee.png';

var img = new Image();
img.src = img_test__src;
img.onload = drawImg;
var mouseOver = false;
function drawImg(){
   if(img.complete){ // has image loaded
       context.clearRect(0,0,canvas.width,canvas.height);
       context.globalAlpha = mouseOver ? 1 : 0.5;
       context.drawImage(img,0,0);
       context.globalAlpha = 1;
   }
}
canvas.addEventListener('mouseover', function(evt) {
   mouseOver = true;
   requestAnimationFrame(drawImg);
});
canvas.addEventListener('mouseout', function(evt) {
   mouseOver = false;
   requestAnimationFrame(drawImg);
});
#canvas_test {
  background: #000;
}
   
<canvas id="canvas_test" width="65" height="65"></canvas>