保持相同的字体大小的文本,不管viewBox缩放
Maintain same font-size text regardless of viewBox zooming
我有一个交互式SVG图表,它几乎完全不同于这个简单的演示…
演示:http://jsfiddle.net/CphxH/6/
…除非:
- 有一堆
<text>
元素, - 动态调节
viewBox
, - 我想在屏幕上看到的文本的字体大小是相同的,不管viewBox有多大。
理想情况下,我想等效的vector-effect:non-scaling-stroke
(至少在Webkit上),但font-size
。这样的东西存在吗?如果不是,我最好的选择是计算viewBox大小,将其与aspectRatio
结合以确定更大的轴,然后使用JS来操作font-size
属性的CSS规则?
不,如果你改变viewBox,没有任何自动保持文本大小不变的方法。您必须按照您的想法使用Javascript调整文本大小。
这是一个基于javascript的解决方案。在开始时调用recordSVGFontSizes()
一次,向它传递一个SVG元素和一个样式表。它计算SVG的视口,并遍历样式表,找到提到font-size
的所有规则,并记录原始字体大小。
然后,当你的viewBox改变时,将记录的值传递给normalizeSVGFontSizes()
。它将重新计算视口并适当地更新所有字体大小。
请注意,由于viewport计算目前不支持Firefox,因此此脚本在Firefox中不起作用。
演示:http://jsfiddle.net/CphxH/8/
// Do this once at startup
var recording = recordSVGFontSizes( mySVG, document.styleSheets[0] );
// Do this each time the viewport changes
normalizeSVGFontSizes(recording);
function recordSVGFontSizes(svgElement,styleSheet){
var rules = [];
var viewport = calculateViewport(svgElement);
for (var i=styleSheet.cssRules.length;i--;){
var rule = styleSheet.cssRules[i];
if (rule.style.fontSize){
var parts = rule.style.fontSize.split(/('D+)/);
rules.push({ rule:rule, units:parts[1], perpx:parts[0] / viewport.width });
}
}
return {rules:rules, svg:svgElement};
}
function normalizeSVGFontSizes(fontSizeRecording){
var viewport = calculateViewport(fontSizeRecording.svg);
for (var i=fontSizeRecording.rules.length;i--;){
var record = fontSizeRecording.rules[i];
record.rule.style.fontSize = record.perpx*viewport.width + record.units;
}
}
// Given an <svg> element, returns an object with the visible bounds
// expressed in local viewBox units, e.g.
// { x:-50, y:-50, width:100, height:100 }
function calculateViewport(svg){ // http://phrogz.net/JS/_ReuseLicense.txt
var outer = svg.getBoundingClientRect();
var aspect = svg.preserveAspectRatio.baseVal,
viewBox = svg.viewBox.baseVal,
width = viewBox && viewBox.width || outer.width,
height = viewBox && viewBox.height || outer.height,
x = viewBox ? viewBox.x : 0,
y = viewBox ? viewBox.y : 0;
if (!width || !height || !outer.width) return;
if (aspect.align==aspect.SVG_PRESERVEASPECTRATIO_NONE || !viewBox || !viewBox.height){
return {x:x,y:y,width:width,height:height};
}else{
var inRatio = viewBox.width / viewBox.height,
outRatio = outer.width / outer.height;
var meetFlag = aspect.meetOrSlice != aspect.SVG_MEETORSLICE_SLICE;
var fillAxis = outRatio>inRatio ? (meetFlag?'y':'x') : (meetFlag?'x':'y');
if (fillAxis=='x'){
height = width/outRatio;
var diff = viewBox.height - height;
switch (aspect.align){
case aspect.SVG_PRESERVEASPECTRATIO_UNKNOWN:
case aspect.SVG_PRESERVEASPECTRATIO_XMINYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMID:
y += diff/2;
break;
case aspect.SVG_PRESERVEASPECTRATIO_XMINYMAX:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMAX:
y += diff;
break;
}
}
else{
width = height*outRatio;
var diff = viewBox.width - width;
switch (aspect.align){
case aspect.SVG_PRESERVEASPECTRATIO_UNKNOWN:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMIDYMAX:
x += diff/2;
break;
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMID:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case aspect.SVG_PRESERVEASPECTRATIO_XMAXYMAX:
x += diff;
break;
}
}
return {x:x,y:y,width:width,height:height};
}
}
相关文章:
- 如何使用jquery在填充自动完成的值后使文本框只读
- 使用Clipboard.js复制span文本
- 使用JS如何动态更改显示的html文件中的文本背景颜色
- 用程序搜索JQuery数据表中的文本
- jQuery匹配JSON对象的部分文本
- onkeyup无法动态创建多个文本区域
- 如何在下面的ES6循环中获得前面的文本
- 将输入字段中的文本提交到我的数据库,同时将其添加到我的列表中
- 让文本输入幻灯片显示输入时的新文本输入?然后向后滑动
- 借助asp.net验证或java脚本对多个文本进行验证
- 无法在ajaxStart中更改跨度文本
- 高亮显示时编辑文本大小和颜色
- jquery中的文本框验证
- Javascript,有没有一种方法可以将数组写成没有逗号或空格的单个文本字符串
- Sails.js:同时发布文本输入和一个文件
- 当鼠标悬停在文本中的单词上时显示警报
- 是否有任何方法可以使用jQuery替换在数组中定义值的文本
- 将纯文本URL转换为可单击链接
- 使用jQuery UI自动完成,我如何确保一个特定的结果出现,不管输入什么文本
- 保持相同的字体大小的文本,不管viewBox缩放