简体   繁体   English

如何使用JavaScript动态调整SVG中文本元素的高度和宽度

[英]How to resize height and width of text element in SVG dynamically using JavaScript

I'm working on a project where i have to add Svg Text element dynamically using javascript with given width and height of text frame without getting disturbed the font ratio. 我正在一个项目中,我必须使用给定宽度和高度的文本框架,使用javascript动态添加Svg Text元素,而不会干扰字体比率。 I am unable to do that please help me. 我无法做到这一点,请帮助我。

Thanks in advance 提前致谢

 function opacityValue() { var opValue = document.getElementById("myRange").value; document.getElementById("opacityValue").textContent = "(" + opValue / 100 + ")"; } // function txtOnFloor() { var color = document.getElementById("clr").value; var opacity = document.getElementById("myRange").value / 100; var fontFamily = document.getElementById("family").value; var svgs = document.getElementById("svgcontent"); var svg = svgs.getElementsByTagName("g")[0]; svg.innerHTML = ""; var g = document.createElementNS("http://www.w3.org/2000/svg", "g"); var g2 = document.createElementNS("http://www.w3.org/2000/svg", "g"); var rectNull = document.createElementNS("http://www.w3.org/2000/svg", "rect"); var svgText = document.createElementNS("http://www.w3.org/2000/svg", "text"); var svgTexttemp = document.getElementById("bg_svgtext").value; var textWidth = svgTexttemp.length; g.setAttribute("id", "gvr"); var textNode = document.createTextNode("" + svgTexttemp + ""); svgText.appendChild(textNode); ///// var width1 = parseInt(document.getElementById("w1").value); var width2 = document.getElementById("w2"); if (width2 != null && width2 != 0) { width2 = parseInt(width2.value) / 100; } else { width2 = 0; } var width = width1 + width2; var depth1 = parseInt(document.getElementById("d1").value); var depth2 = document.getElementById("d2"); if (depth2 != null && width2 != 0) { depth2 = parseInt(width2.value) / 100; } else { depth2 = 0; } var depth = depth1 + depth2; var ratio = width / depth; // if (ratio > 1) { for (var i = 1; i <= 100; i++) { if (ratio >= i && ratio < i + 1) { var fSize = (width / textWidth)*i; svgText.setAttribute("font-size", fSize); } } svgText.setAttribute("textLength", (fSize * textWidth) / ratio); svgText.setAttribute("lengthAdjust", "spacingAndGlyphs"); } else if (ratio <= 1) { svgText.setAttribute("font-size", (width / textWidth)*2.3); svgText.setAttribute("textLength", width); svgText.setAttribute("lengthAdjust", "spacingAndGlyphs"); } // svgText.setAttribute("fill", "" + color + ""); svgText.setAttribute("opacity", "" + opacity + ""); if (fontFamily == "Fira Bold") { svgText.setAttribute("font-family", "Fira"); svgText.setAttribute("font-weight", "bold"); } else if (fontFamily == "Verdana Bold") { svgText.setAttribute("font-family", "Verdana"); svgText.setAttribute("font-weight", "bold"); } else if (fontFamily == "Arial Bold") { svgText.setAttribute("font-family", "Arial"); svgText.setAttribute("font-weight", "bold"); } else if (fontFamily == "Calibri Bold") { svgText.setAttribute("font-family", "Calibri"); svgText.setAttribute("font-weight", "bold"); } else { svgText.setAttribute("font-family", "" + fontFamily + ""); } // svgText.setAttribute("x", "5"); svgText.setAttribute("y", depth); svgText.setAttribute("id", "bg_txt"); // debugger; var textWidth = svgText.getAttribute("textLength"); var x = (width - textWidth)/2; rectNull.setAttribute("x", x); rectNull.setAttribute("y", "0"); rectNull.setAttribute("stroke", "null"); rectNull.setAttribute("fill", "none"); rectNull.setAttribute("height", depth); rectNull.setAttribute("width", width); // g2.appendChild(rectNull); g2.appendChild(svgText); g.appendChild(g2); svg.appendChild(g); } 
 <div class="table table-bordered" id="btext" style="border:none;"> <div class="bTexts"> <span style="color:#000;font-size:15px; font-family:Helvetica">Text Value:</span><br /> <input type="text" id="bg_svgtext" placeholder="Enter your text value" value="Floor Plan" style="font-size:14px;height:16px; width:220px;margin-top:7px;font-family:Helvetica" /> </div> <div> <table style="margin-top:10px;color:#000;font-size:13px; font-weight:bold; font-family:Helvetica;"> <tr> <td style="padding:0px; padding-right:22px;"><span style="">Width:</span></td> <td style="padding:0px; padding-right:22px;"><input id="w1" type="text" name="width" value="100" style="width:30px;height:16px;" />m</td> <td style="padding:0px; padding-right:22px;"><input id="w2" type="text" name="width" value="0" style="width:30px;height:16px;" />cm</td> </tr> <tr style=""> <td style="padding:0px; padding-right:22px;padding-top:8px;"><span style="">Depth:</span></td> <td style="padding:0px; padding-right:22px;padding-top:8px;"><input id="d1" type="text" name="Depth" value="100" style="width:30px;height:16px;" />m</td> <td style="padding:0px; padding-right:22px;padding-top:8px;"><input id="d2" type="text" name="Depth" value="0" style="width:30px;height:16px;" />cm</td> </tr> </table> </div> <div class="boothname" style="margin-bottom:10px;padding-left:0px;"> <span style="font-family: Helvetica; font-size:15px;">Font Settings</span> </div> <div> <table style="color:#000;font-size:13px; width:210px; font-weight:bold; font-family:Helvetica;"> <tr> <td><span style="padding-right:20px;">Font</span></td> <td style="padding-left:60px;"> <select id="family" style="color:black; width:100px; height:23px; font-size:11px;padding: 2px 26px 2px 10px !important;background-position: calc(114% - 22px) calc(1em + 0px), calc(114% - 17px) calc(1em + 0px), 120% 0;" class="form-control classic ddldesign"> <option style="font-size:12px;" value="Fira">Fira</option> <option style="font-size:12px;" value="Fira Bold">Fira Bold</option> <option style="font-size:12px;" value="Verdana">Verdana</option> <option style="font-size:12px;" value="Verdana Bold">Verdana Bold</option> <option style="font-size:12px;" value="Calibri">Calibri</option> <option style="font-size:12px;" value="Calibri Bold">Calibri Bold</option> <option style="font-size:12px;" value="Arial">Arial</option> <option style="font-size:12px;" value="Arial Bold">Arial Bold</option> </select> </td> </tr> <tr> <td><span>Color</span></td> <td style="padding-left:60px;"><input type="color" style="width:20px;" name="color" value="#046FAA" id="clr" /></td> </tr> <tr> <td><span>Alpha</span></td> <td style="padding-left:60px;"> <input type="range" oninput="opacityValue()" min="0" max="100" value="100" style="width:50px;float:left;" id="myRange"> <span id="opacityValue" style="margin-left:5px;">(1)</span> </td> </tr> </table> </div> <div class="boothname" style="margin-bottom:10px;padding-left:0px;"> <div style="font-family: Helvetica; font-size:15px;">Click For Add To The Floor</div> <div style="margin-left:85px; margin-top:5px;"><button class="btn" style="height:26px; padding: 5px 20px" onclick="txtOnFloor()">Add</button></div> </div> </div> <div> <svg id="svgcontent"> <g></g> <g></g> </svg> </div> 

I had tried a function on add button click but the font get disturbed. 我已经尝试过在添加按钮单击上的功能,但是字体受到干扰。

How can I implement getBBox if it will work? 如果可以正常工作,如何实现getBBox?

To make the example clearer, I've shortened it to the relevant parts. 为了使示例更清楚,我将其简化为相关部分。 The best strategy will be to let the browser do the sizing of the text for you. 最好的策略是让浏览器为您确定文本的大小。 It will work for all aspect ratios, so the case distinction you made is not needed. 它适用于所有纵横比,因此不需要您区分大小写。

  • first, add a text at a fixed font size 首先,以固定的字体大小添加文本
  • after it has been added to the document (so that it is actually rendered), get the size of its bounding box. 在将其添加到文档中(以便实际渲染)之后,获取其边框的大小。 For the .getBBox() method for text elements 对于文本元素的.getBBox()方法

    each glyph must be treated as a separate graphics element. 每个字形都必须视为单独的图形元素。 The calculations must assume that all glyphs occupy the full glyph cell . 计算必须假定所有字形都占据整个字形单元 The full glyph cell must have width equal to the horizontal advance and height equal to the EM box for horizontal text. 完整的字形单元必须具有等于水平行进的宽度和等于水平文本的EM框的高度。

  • If you surround the <text> element with a inner <svg> element, you can define the viewBox attribute to equal that bounding box. 如果用内部<svg>元素包围<text>元素,则可以将viewBox属性定义为等于该边界框。 If the width and height attributes match your desired final size, the text will be automatically fitted. 如果width和height属性与所需的最终大小匹配,则文本将自动适合。 The preserveAspectRatio attribute defines the exact rules for that fitting. preserveAspectRatio属性定义该拟合的确切规则。

 var width = 100, height = 100, text="Floor Plan"; var content = document.querySelector("#svgcontent"); // add a rect to visualize the target size var rectNull = document.createElementNS("http://www.w3.org/2000/svg", "rect"); rectNull.classList.add("booth-outline"); rectNull.setAttribute("width", width); rectNull.setAttribute("height", height); content.appendChild(rectNull); // inner svg as a container for the text with sizing capabilities var innerSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); innerSvg.classList.add("booth"); // target sizes innerSvg.setAttribute("width", width); innerSvg.setAttribute("height", height); // position text content to the bottom left such that its size // fills the target dimensions innerSvg.setAttribute("preserveAspectRatio", "xMinYMax meet"); // text content var svgText = document.createElementNS("http://www.w3.org/2000/svg", "text"); svgText.textContent = text; innerSvg.appendChild(svgText); // render content.appendChild(innerSvg); // and measure size var box = svgText.getBBox(); // convert to viewBox attribute format var viewBox = [box.x, box.y, box.width, box.height].join(" "); innerSvg.setAttribute("viewBox", viewBox); 
 #svgcontent { overflow: visible; } .booth-outline { fill: none; stroke: black; } .booth text { font-family: serif; font-size: 10px; } 
 <svg id="svgcontent" width="250" height="250"></svg> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM