【发布时间】:2016-12-28 00:27:21
【问题描述】:
我得到了一些动态生成的svg 元素。它是根据input 字段中的文本生成的。
每个中断都意味着新的组元素结构类似
<g>
<svg>
<text/>
<rect/>
</svg>
</g>
还增加了字体更改选项。因此,在字体类型更改后,我需要在文本下重新绘制 rect,其大小取决于我在 text.getBBox() 数据上得到的内容。
问题是,当我第一次更改字体时(有事件触发,在您在select 下拉列表中选择其他字体类型后)我的矩形没有重新绘制,因为文本没有在 @ 内呈现987654333@ 元素,那么有没有办法检查所有<text> 元素中是否呈现了所有文本?
这里是问题的说明
UPD 1:
这对我不起作用
someSvgTextBlocks.ready(function() {
//call redraw rects functions here
})
UPD 2:
UPD 3
我使用 Angularjs 框架,所以这里是 Angular 的代码(我猜)
svg 的指令视图:
<svg ng-repeat="line in svgConfig.text track by $index">
<g>
<rect x="0" y="0"
ng-show="svgConfig.rectConfig[$index].active"
ng-attr-height="{{svgConfig.rectConfig[$index].height}}"
ng-attr-width="{{svgConfig.rectConfig[$index].width}}"
>
</rect>
<text ng-attr-font-family="{{svgConfig.textConfig.fontFamily}}"
ng-attr-font-size="{{svgConfig.textConfig.fontSize}}"
ng-attr-fill="{{svgConfig.textConfig.fontColor}}"
>
{{line}}
</text>
</g>
</svg>
指令本身:
app.directive('imageTxtSvgDirective', ['imageTxtSvgService', 'svgUtilsService', function(imageTxtSvgService, svgUtilsService) {
/**
* Set event bindings
*/
var setDomBindings = function($scope, $element, $attrs){
/**
* Sets watch to detect changes in text, fontsize, font family to recalculate binded svg-data
*/
$scope.$watchGroup(['svgConfig.text', 'svgConfig.textConfig.fontSize', 'svgConfig.textConfig.fontFamily', 'svgConfig.extras', 'svgConfig.rectsVisible'], function() {
var domText = $element.find('text'),
textExampleList = domText,
textConfig = $scope.svgConfig.textConfig,
font = textConfig.fontFamily,
size = textConfig.fontSize;
document.fonts.load(''+size + 'px ' + font+'').then(
function(){
$scope.setSvgRectanglesConfig(textExampleList);
}
);
});
}
/*
* Retruns initialized DOM element
*/
return {
restrict: 'E',
templateUrl: './app/shared/imageTextEditor/imageTxtSvgView.html',
controller: 'imageTxtSvgController',
transclude: true,
link: setDomBindings
};
}]);
控制器:
app.controller('imageTxtSvgController', ['$scope', 'imageTxtSvgService', '$filter', 'textConfigEnum', function($scope, imageTxtSvgService, $filter, textConfigEnum){
/**
* Returns config for each text line rect
*/
$scope.setSvgRectanglesConfig = function(textAreaList){
var me = this,
numberOfElements = (textAreaList) ? textAreaList.length : 0;
if (numberOfElements <= 0) {
return;
}
$scope.svgConfig.rectConfig = imageTxtSvgService.getSvgRectListData(textAreaList, $scope.svgConfig.rectsVisible, $scope.svgConfig);
};
$scope.init = function(){
// Fonts data
$scope.textFonts = textConfigEnum.data;
// Container for svg settings
$scope.svgConfig = {
text:'',
textConfig: {
fontFamily: $filter('getTextConfigByType')(textConfigEnum.info.Arial).fontFamily,
fontSize: 20,
fontDecoration: null,
fontWeigth: null,
fontColor:'black'
},
rectsVisible: true,
rectConfig: [],
};
};
$scope.init();
}]);
服务:
app.service('imageTxtSvgService', ['$rootScope', 'svgUtilsService', function($rootScope, svgUtilsService){
this.getSvgRectObject = function(data){
var me = this,
rectObject = {
height: 0,
width: 0,
fillColor: '#A8A8A8',
outlineColor: '#A8A8A8',
active: false
};
return angular.merge({}, rectObject, data);
}
/**
* Handles svg text creation
*/
this.getSvgText = function(data){
var me = this,
text = data.text,
stringArray = text.split('\n');
if(text === ""){
return null;
}
return stringArray;
},
/**
* Get data for rect object
*/
this.getSvgRectData = function(textArea, isActive, prevConfig){
var me = this,
box = textArea.getBBox(),
defaultRectConfig = {
height: box.height,
width: box.width,
active: isActive
},
rectConfig = angular.merge({}, prevConfig, defaultRectConfig);
return me.getSvgRectObject(rectConfig);
},
/**
*
* @returns {Array}
*/
this.getSvgRectListData = function(textAreaList, isActive, previousConfig){
var me = this,
active = isActive,
previousRectConfig,
result = [];
angular.forEach(textAreaList, function(textArea, index) {
if(previousConfig.rectConfig[index]){
previousRectConfig = previousConfig.rectConfig[index];
}
result.push(me.getSvgRectData(textArea, active, previousRectConfig));
});
return result;
}
}]);
UPD 4:问题解决方案
看来我有办法了。
不是这个
var domText = $element.find('text'),
textExampleList = domText,
textConfig = $scope.svgConfig.textConfig,
font = textConfig.fontFamily,
size = textConfig.fontSize;
document.fonts.load(''+size + 'px ' + font+'').then(
function(){
$scope.setSvgRectanglesConfig(textExampleList);
}
);
应该是这样的:
var textConfig = $scope.svgConfig.textConfig,
font = textConfig.fontFamily,
size = textConfig.fontSize;
document.fonts.load(''+size + 'px ' + font+'').then(
function(){
var textExampleList = $element.find('text');
$scope.setSvgRectanglesConfig(textExampleList);
$scope.$apply();
}
);
我应该在 字体加载后获取 dom 数据,但在旧版本中我使用的是旧版本的 dom 数据。另外,我忘了应用更改。
【问题讨论】:
-
你能再展示一些你的代码吗?也许是
setSvgRectanglesConfig函数? -
@RaphaelSchweikert 当然!自动更新!
-
已更新。尽量缩短它
标签: javascript jquery html angularjs svg