我想用fabricjs绘制一个大网格,但是太模糊了。我使用fabricJS canvas.toSVG()导出到svg文件,然后在浏览器中打开svg文件,它的视图很好。所以我认为这很可能是边缘漏洞。
测试代码为:
var data = [];
var temp = [0,0,-0.012,-0.012,-0.012,-0.012,-0.012,-0.012,0,0,-0.012,-0.012,0,0.049,0.073,0.049,0.049,0.037,-0.012,-0.012,-0.024,-0.049,-0.024,-0.049,-0.061,-0.012,-0.061,-0.086,0.061,0.146,0.354,0.403,-0.647,-1.88,-1.672,-0.757,-0.33,-0.098,0.024,0.012,0.073,0.122,0.098,0.146,0.183,0.171,0.207,0.232];
for (var i = 0; i < 200; i++) {
data = data.concat(temp);
}
// case 1 : blurry
var canvas1 = new fabric.Canvas("ecg1");
var width = 8000;
var height = 400;
canvas1.setWidth(width);
canvas1.setHeight(height);
var bg1 = getBackgroundPath(width, height);
var ecg1 = getEcgPath(data);
canvas1.add(bg1);
canvas1.add(ecg1);
canvas1.renderAll(); // blurry
// case 2 : ok
var canvas2 = new fabric.Canvas("ecg2");
var data2 = data.slice(0, 3000);
width = 1000;
height = 400;
canvas2.setWidth(width);
canvas2.setHeight(height);
var bg2 = getBackgroundPath(width, height);
var ecg2 = getEcgPath(data2);
canvas2.add(bg2);
canvas2.add(ecg2);
canvas2.renderAll();
// case 3 : blurry
var canvas3 = new fabric.Canvas("ecg3");
canvas3.setWidth(width);
canvas3.setHeight(height);
canvas3.add(new fabric.Group([bg2, ecg2]));
canvas3.renderAll();
function getBackgroundPath(width, height) {
var grid = [];
for (var y = 0; y <= height; y += 10) {
grid.push("M");
grid.push("0");
grid.push(y);
grid.push("H");
grid.push(width);
}
for (var x = 0; x <= width; x += 10) {
grid.push("M");
grid.push(x);
grid.push("0");
grid.push("V");
grid.push(height);
}
return new fabric.Path(grid.join(" "), {
top : 0,
left : 0,
stroke: 'pink',
strokeWidth: 1
});
}
function getEcgPath(data) {
var xm = 2;
var ym = 100;
var max = Math.max.apply(Math, data);
var path = [];
for (var i = 0; i < data.length; i++) {
path.push("L");
path.push(i * xm);
path.push((max - data[i]) * ym);
}
path[0] = "M";
return new fabric.Path(path.join(" "), {
top : 0,
left : 0,
fill : '',
stroke: 'black',
strokeWidth: 1
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<canvas id="ecg1"></canvas>
<canvas id="ecg2"></canvas>
<canvas id="ecg3"></canvas>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.min.js" ></script>
</body>
</html>
结果是 enter image description here enter image description here
答案 0 :(得分:0)
请在此处进一步阅读: http://fabricjs.com/fabric-object-caching
这个问题实际上很容易解决,可以禁用ECG行的缓存。 如果您的应用程序只需要绘制一条大路径或其中的一条,则无需进行缓存。
缓存如何工作? 缓存在单独的画布上绘制对象,然后在移动它的每一帧时重复使用该画布。 与必须对许多对象的每一帧执行多次填充和描边操作相比,这种方法具有更高的性能,尤其是当对象很复杂时。
为避免性能下降,默认情况下,用于缓存的画布限制为2兆像素(您可以通过更改fabric.perfLimitSizeTotal将其向上推),无论兆像素大小如何,默认情况下最大大小限制为4096(如果您不需要支持ie11,可以通过更改fabric.maxCacheSideLimit使其更大。
在您的情况下,路径可以由CPU顺利处理。
对于网格,我们需要更多代码。
var data = [];
var temp = [0,0,-0.012,-0.012,-0.012,-0.012,-0.012,-0.012,0,0,-0.012,-0.012,0,0.049,0.073,0.049,0.049,0.037,-0.012,-0.012,-0.024,-0.049,-0.024,-0.049,-0.061,-0.012,-0.061,-0.086,0.061,0.146,0.354,0.403,-0.647,-1.88,-1.672,-0.757,-0.33,-0.098,0.024,0.012,0.073,0.122,0.098,0.146,0.183,0.171,0.207,0.232];
for (var i = 0; i < 200; i++) {
data = data.concat(temp);
}
// case 1 : blurry
var canvas1 = new fabric.Canvas("ecg1");
var width = 8000;
var height = 400;
canvas1.setWidth(width);
canvas1.setHeight(height);
var bg1 = getBackgroundPath(width, height);
var ecg1 = getEcgPath(data);
canvas1.add(bg1);
canvas1.add(ecg1);
canvas1.renderAll(); // blurry
function getBackgroundPath(width, height) {
var grid = [];
for (var y = 0; y <= height; y += 10) {
grid.push("M");
grid.push("0");
grid.push(y);
grid.push("H");
grid.push(width);
}
for (var x = 0; x <= width; x += 10) {
grid.push("M");
grid.push(x);
grid.push("0");
grid.push("V");
grid.push(height);
}
return new fabric.Path(grid.join(" "), {
top : 0,
left : 0,
stroke: 'pink',
strokeWidth: 1
});
}
function getEcgPath(data) {
var xm = 2;
var ym = 100;
var max = Math.max.apply(Math, data);
var path = [];
for (var i = 0; i < data.length; i++) {
path.push("L");
path.push(i * xm);
path.push((max - data[i]) * ym);
}
path[0] = "M";
return new fabric.Path(path.join(" "), {
top : 0,
left : 0,
fill : '',
stroke: 'black',
strokeWidth: 1,
objectCaching: false,
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<canvas id="ecg1"></canvas>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.min.js" ></script>
</body>
</html>
答案 1 :(得分:0)
@AndreaBogazzi
谢谢您的回答。使用fabric.Object.prototype.objectCaching = false
之后,效果很好。
在我的应用程序中,绘制网格代码如下。
var data = [];
var temp = [0,0,-0.012,-0.012,-0.012,-0.012,-0.012,-0.012,0,0,-0.012,-0.012,0,0.049,0.073,0.049,0.049,0.037,-0.012,-0.012,-0.024,-0.049,-0.024,-0.049,-0.061,-0.012,-0.061,-0.086,0.061,0.146,0.354,0.403,-0.647,-1.88,-1.672,-0.757,-0.33,-0.098,0.024,0.012,0.073,0.122,0.098,0.146,0.183,0.171,0.207,0.232];
for (var i = 0; i < 200; i++) {
data = data.concat(temp);
}
// case 1 : blurry
var canvas1 = new fabric.Canvas("ecg1");
var width = 8000;
var height = 400;
canvas1.setWidth(width);
canvas1.setHeight(height);
var bg11 = getBackgroundDot(width, height);
var bg12 = getBackgroundPath(width, height);
var ecg1 = getEcgPath(data);
canvas1.add(bg11);
canvas1.add(bg12);
canvas1.add(ecg1);
canvas1.renderAll(); // blurry
function getBackgroundDot() {
var dotLineWidth = 2;
var dot = [];
dot.push("M 0 0");
for (var y = 0; y <= height; y += 10) {
if (y % 50 == 0) {
continue;
}
dot.push("M");
dot.push("0");
dot.push(y);
dot.push("H");
dot.push(width);
}
var sda = [0, 10];
for (var i = 1; i < 5; i++) {
sda.push(dotLineWidth);
sda.push(8);
}
return new fabric.Path(dot.join(" "), {
top : 0,
left : 0,
stroke: 'pink',
strokeWidth: dotLineWidth,
strokeDashArray: sda
});
}
function getBackgroundPath(width, height) {
var grid = [];
for (var y = 0; y <= height; y += 50) {
grid.push("M");
grid.push("0");
grid.push(y);
grid.push("H");
grid.push(width);
}
for (var x = 0; x <= width; x += 50) {
grid.push("M");
grid.push(x);
grid.push("0");
grid.push("V");
grid.push(height);
}
return new fabric.Path(grid.join(" "), {
top : 0,
left : 0,
stroke: 'pink',
strokeWidth: 1
});
}
function getEcgPath(data) {
var xm = 2;
var ym = 100;
var max = Math.max.apply(Math, data);
var path = [];
for (var i = 0; i < data.length; i++) {
path.push("L");
path.push(i * xm);
path.push((max - data[i]) * ym);
}
path[0] = "M";
return new fabric.Path(path.join(" "), {
top : 0,
left : 0,
fill : '',
stroke: 'black',
strokeWidth: 1
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<canvas id="ecg1"></canvas>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.min.js" ></script>
</body>
</html>