javascript - 如何使 Canvas 变得流畅

标签 javascript canvas responsive

我有一个 Canvas ,它从页面的包装器获取其全 Angular 尺寸。 Canvas 包含图像。

包装器具有响应能力,但 Canvas 不会随包装器调整大小。

这是我正在使用的代码:

var canvas = document.getElementById("canvasTop");
// set the canvas element's width/height to cover #wrapper
var wrapper=document.getElementById('wrapper');
var wrapperStyle=window.getComputedStyle(wrapper,null);
canvas.width=parseInt(wrapperStyle.getPropertyValue("width"));
canvas.height=parseInt(wrapperStyle.getPropertyValue("height"));
//
var ctx = canvas.getContext("2d");
    ctx.lineWidth = 10;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.fillStyle = "skyblue";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

var img=new Image();
    img.src= "els.png";
    ctx.drawImage(img, (canvas.width-img.width)/2, (canvas.height-img.height)/2, 990,172);
    // set "erase" compositing once at start of app for better performance
    ctx.globalCompositeOperation = "destination-out";

var canvasOffset = $("#canvasTop").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var startX;
var startY;
var isDown = false;

function handleMouseDown(e) {
    e.preventDefault();
    startX = parseInt(e.clientX - offsetX);
    startY = parseInt(e.clientY - offsetY);
    isDown = true;
}

function handleMouseUp(e) {
    e.preventDefault();
    isDown = false;
}

function handleMouseOut(e) {
    e.preventDefault();
    isDown = false;
}

function handleMouseMove(e) {
    if (!isDown) {
        return;
    }
    mouseX = parseInt(e.clientX - offsetX);
    mouseY = parseInt(e.clientY - offsetY);

    // Put your mousemove stuff here
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(mouseX, mouseY);
    ctx.stroke();
    startX = mouseX;
    startY = mouseY;
}

$("#canvasTop").mousedown(function (e) {
    handleMouseDown(e);
});
$("#canvasTop").mousemove(function (e) {
    handleMouseMove(e);
});
$("#canvasTop").mouseup(function (e) {
    handleMouseUp(e);
});
$("#canvasTop").mouseout(function (e) {
    handleMouseOut(e);
});
#wrapper {
  position:relative; 
  margin:auto; 
  width:100%; 
  height:100%; 
}

#container {
	position:absolute;
	width:80%;
	height:80%;
	left:0;
	bottom:0;
	margin-left:60px;
	}

#canvasTop {
  position:absolute; 
  top:0px; 
  left:0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
  <div id="container">
   Stuff happen here ...
   </div>
 </div>
 <canvas id="canvasTop" width=512 height=512></canvas>

希望大家能帮忙!

最佳答案

检测调整大小

您必须订阅窗口的调整大小事件:

window.addEventListener("resize", updateCanvas);

function updateCanvas() {

  // update canvas size (and position) here
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  // redraw canvas content based on new size
  // ...
}

updateCanvas();   // initial call

由于调整 Canvas 大小会使其内容变得清晰,因此我们必须再次重新绘制所有内容。

使用CSS(不推荐)

在大多数情况下,您不想使用 CSS 调整大小,因为这会拉伸(stretch)绘制到 Canvas 上的所有内容,使其变得模糊。但是,在您仍然使用 CSS 的情况下,您可以通过以下方式根据 CSS 大小设置 Canvas 的大小:

#canvas {
  width: 100vw;   /* or use 100% depending on your scenario */
  height: 100vh;
  }

然后在resize事件处理程序中:

var rect = canvas.getBoundingClientRect();  // get absolute size in pixels
canvas.width = rect.width;
canvas.height = rect.height;

这应该为您提供位图大小和元素大小之间的 1:1 关系。如果您使用填充或边框,则还必须添加它们的尺寸。最好使用 Canvas 来避免这些。相反,将 Canvas 包裹在 div 元素中,并在其上设置此类样式。

处理事件流

调整大小时要注意的另一件事是,将会有许多事件发送到订阅者。其中大部分你都不需要。因此,为了使其更加流畅和响应更快,您可以对事件进行反跳:

var timer;
window.addEventListener("resize", function () {
  clearTimeout(timer);
  timer = setTimeout(updateCanvas, 100);  // adjust time to liking
});

关于javascript - 如何使 Canvas 变得流畅,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38190136/

相关文章:

javascript - 返回包含另一个函数的对象列表的函数

javascript - 如何计算点后面两位小数的小时差

css - 如何排除响应式设计中的元素? [ Bootstrap ]

html - 如何处理移动屏幕和标签屏幕中宽度和高度为 100% 的背景图片?

html - 在桌面上使用缩放而不是断点

javascript - 如何卸载/阻止加载的 JavaScript

javascript - `#` 的一致 keyCode

javascript - 使用 html5 和 javascript 在浏览器中显示交互式 2D 平面图

java - 可以在 Java 中绘制 YCbCr 吗?

memory-management - 删除 WebGL 上下文