javascript - 如何使高 DPI 画布变得灵活?
问题描述
我做了一个 js High DPI Canvas。但是如果我让窗口更小(浏览器窗口,因为它是从浏览器窗口计算的,而不是在 chrome 开发工具中) - 它超出了我设置的初始宽度和高度,它会改变它的宽度和高度,所以看不到左边或\和下边界。我怎样才能在不丢失部分画布的情况下制作可以适应较小尺寸的高 DPI 柔性画布?
// get pixel ratio
var PIXEL_RATIO = function () {
var ctx = document.createElement("canvas").getContext("2d");
var dpr = window.devicePixelRatio || 1;
var bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
return dpr / bsr;
};
// create such a canvas that is not blured on any display size
var createHiDPICanvas = function(w, h, ratio) {
if (!ratio) { ratio = PIXEL_RATIO(); }
var chart_container = document.getElementById("lifespan-chart-content");
var can = document.createElement("canvas");
can.width = w * ratio;
can.height = h * ratio;
can.style.width = w + "px";
can.style.height = h + "px";
can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
chart_container.appendChild(can);
return can;
}
// height and width of the canvas
var w = 500; // should be flexible
var h = 320; // should be constant
var text = "Center";
var font = "18px Arial"
var border_width = 50;
//Create canvas & context
canvas = createHiDPICanvas(w, h);
ctx = canvas.getContext("2d");
// create a text
var middle = {x : canvas.width/2, y : canvas.height/2};
var text_width = ctx.measureText(text).width;
ctx.font = font;
ctx.moveTo(middle.x, middle.y);
ctx.fillText("Center", middle.x - text_width / 2, middle.y);
// create left and down borders
createBorders(border_width);
function createBorders(border_width) {
ctx.save();
var canv_height = canvas.height;
var canv_width = canvas.width;
ctx.moveTo(0,0);
ctx.lineTo(border_width, 0);
ctx.lineTo(border_width, canv_height - border_width);
ctx.lineTo(canv_width, canv_height - border_width);
ctx.lineTo(canv_width, canv_height);
ctx.lineTo(0, canv_height);
ctx.lineTo(0, 0);
ctx.fill = "black";
ctx.stroke();
ctx.restore();
}
canvas {
background-color:bisque;
}
#lifespan-chart {
display: flex;
justify-content: center;
}
#lifespan-chart-content {
overflow: scroll;
}
<div id="lifespan-chart">
<div id="lifespan-chart-content"></div>
</div>
PS好的。添加overflow:scroll;
到带有画布的容器上,现在只有左侧部分可见。如果用户希望他可以向右滚动,但是有什么方法可以在这种情况下使左侧可见并且在没有 X 滚动的情况下隐藏右侧溢出(如果我的问题没有答案)?
编辑 1
回答我的 PS 问题:我需要添加overflow:hidden
,如果尺寸较小,它将不会显示画布的中心部分。它将从左侧部分开始并隐藏右侧部分。考虑到用户能够(在实际项目画布中)滚动画布 - 它可以向右移动并查看所有隐藏的对象
但这不是主要的按比例灵活的画布问题的答案
解决方案
我认为您ratio
几乎需要在任何地方使用,例如:
// get pixel ratio
var PIXEL_RATIO = function () {
var ctx = document.createElement("canvas").getContext("2d");
var dpr = window.devicePixelRatio || 1;
var bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
return dpr / bsr;
};
// create such a canvas that is not blured on any display size
var createHiDPICanvas = function(w, h, ratio) {
var chart_container = document.getElementById("lifespan-chart-content");
var can = document.createElement("canvas");
can.width = w * ratio;
can.height = h * ratio;
can.style.width = w + "px";
can.style.height = h + "px";
can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
chart_container.appendChild(can);
return can;
}
// height and width of the canvas
var w = 500; // should be flexible
var h = 320; // should be constant
var text = "Center";
var font = "18px Arial"
var border_width = 50;
var ratio = PIXEL_RATIO();
//Create canvas & context
canvas = createHiDPICanvas(w, h, ratio);
ctx = canvas.getContext("2d");
// create a text
var middle = {x : canvas.width / ratio / 2, y : canvas.height / ratio / 2};
var text_width = ctx.measureText(text).width / ratio;
ctx.font = font;
ctx.moveTo(middle.x, middle.y);
ctx.fillText("Center", middle.x - text_width / 2, middle.y);
// create left and down borders
createBorders(border_width);
function createBorders(border_width) {
ctx.save();
var canv_height = canvas.height / ratio;
var canv_width = canvas.width / ratio;
ctx.moveTo(0,0);
ctx.lineTo(border_width, 0);
ctx.lineTo(border_width, canv_height - border_width);
ctx.lineTo(canv_width, canv_height - border_width);
ctx.lineTo(canv_width, canv_height);
ctx.lineTo(0, canv_height);
ctx.lineTo(0, 0);
ctx.fill = "black";
ctx.stroke();
ctx.restore();
}
推荐阅读
- python - 操作 Pandas 数据框的数据
- c# - 解释这种类型的演员?
- javascript - Spring Boot WebSocket 连接到“ws://127.0.0.1:8081/getUsersList/”失败:WebSocket 握手期间出错:意外响应代码:200
- python-3.x - 神经网络适用于 XOR,但不适用于 MNIST 数据集
- amazon-web-services - 如何将 aws ec2 windows 机器与已安装的应用程序捆绑在一起
- tensorflow - Tensorflow:向 LSTM 添加前馈
- angular - Angular i18n AOT 编译 - 使用 nginx 的 CI 部署与使用 ng serve 的本地开发
- javascript - 如何检查产品是否已经在购物车中
- c++ - 如何以多态方式使用替代类型的 std::variant
- firebase - Flutter:如何在firebase中删除特定的数组数据