2016-09-17 2 views
5

Я разрабатываю инструмент диаграммы на основе fabricjs. Наш инструмент имеет свою собственную коллекцию форм, основанную на svg. Моя проблема заключается в том, что я масштабирую объект, масштаб (штрих). Мой вопрос: как я могу масштабировать объект, но фиксировать ширину хода. Проверьте вложения.
small versionFabricjs Как масштабировать объект, но фиксировать ширину рамки (ход)

scaled version

Большое спасибо!

ответ

6

Вот простой пример, где по шкале объекта мы сохраняем ссылку на исходный ход и вычисляем новый штрих, основанный на масштабе.

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) => { 
 
\t var o = e.target; 
 
\t if (!o.strokeWidthUnscaled && o.strokeWidth) { 
 
    \t o.strokeWidthUnscaled = o.strokeWidth; 
 
    } 
 
\t if (o.strokeWidthUnscaled) { 
 
    \t 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>

+0

Вы пытались импортировать svg. Я знаю, что он работает с этой встроенной формой, но не импортирован svg. – trongd

+0

Я не знаю никакого хорошего способа с любым произвольным svg. Получите форму, чтобы быть единственным путем. создайте файл fabric.Path(), а затем добавьте штрих к этому объекту пути. – StefanHayden

+1

Извините, это была моя ошибка. Ваше решение должно работать! – trongd

1

Я обнаружил, что чувствует себя еще лучшее решение, работает очень хорошо с SVG пути.

Вы можете переопределить метод fabricjs '_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, чтобы настроить рамку для учета разницы в размерах.

Также более полная реализация, вероятно, добавит свойство объекта ткани для условного управления этим изменением для обоих переопределенных методов.

Смежные вопросы