我正在开发一个基于fabricjs的图表工具。我们的工具有我们自己的形状集合,这是基于svg。我的问题是当我缩放对象时,边界(笔划)比例也是如此。我的问题是:如何缩放对象但保持笔划宽度固定。请检查附件
非常感谢!
答案 0 :(得分:8)
这是一个简单的例子,在对象的比例上,我们保持对原始笔划的引用,并根据比例计算新的笔划。
var canvas = new fabric.Canvas('c', { selection: false, preserveObjectStacking:true });
window.canvas = canvas;
canvas.add(new fabric.Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: '#faa',
originX: 'left',
originY: 'top',
stroke: "#000",
strokeWidth: 1,
centeredRotation: true
}));
canvas.on('object:scaling', (e) => {
var o = e.target;
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
o.strokeWidth = o.strokeWidthUnscaled / o.scaleX;
}
})

canvas {
border: 1px solid #ccc;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.4/fabric.min.js"></script>
<canvas id="c" width="600" height="600"></canvas>
&#13;
答案 1 :(得分:5)
我发现了一种更好的解决方案,适用于SVG路径。
您可以覆盖fabricjs&#39; _renderStroke
方法,并在ctx.scale(1 / this.scaleX, 1 / this.scaleY);
之前添加ctx.stroke();
,如下所示。
fabric.Object.prototype._renderStroke = function(ctx) {
if (!this.stroke || this.strokeWidth === 0) {
return;
}
if (this.shadow && !this.shadow.affectStroke) {
this._removeShadow(ctx);
}
ctx.save();
ctx.scale(1 / this.scaleX, 1 / this.scaleY);
this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);
this._applyPatternGradientTransform(ctx, this.stroke);
ctx.stroke();
ctx.restore();
};
您可能还需要覆盖fabric.Object.prototype._getTransformedDimensions
来调整边界框以解决尺寸差异。
此外,更完整的实现可能会添加一个结构对象属性,以有条件地控制这两个重写方法的更改。
答案 2 :(得分:1)
另一种方法是按比例绘制一个新对象并移除已缩放的对象。
const Bottleneck = require('bottleneck');
const main = () => {
console.log('starting main');
const limiter = new Bottleneck({
maxConcurrent: 3,
minTime: 100
});
const worker = (text, limiterCb) => {
Promise.resolve()
.then(() => {
console.log(`starting ${text}`);
let res;
for (let i = 0; i < 10000000000; i++) {
res++
}
console.log(`ending ${text}`);
limiterCb();
});
};
const limiterCb = res => console.log('limiter finished');
limiter.submit(worker, 'hello', limiterCb);
limiter.submit(worker, 'hello', limiterCb);
limiter.submit(worker, 'hello', limiterCb);
limiter.submit(worker, 'hello', limiterCb);
}
main();
console.log('exiting')
对我来说很完美。
答案 3 :(得分:0)
有一个名为的属性:strokeUniform 这样使用 shape.set({stroke:'#f55b76',strokeWidth:2,strokeUniform:true})