简体   繁体   中英

Fitting text into an SVG path

I have an SVG path that draws the outline of a jersey, and I want to center players' last names within that jersey. Also, since I'll be putting names of varying length into the jersey, I wanted to make the size of the text dynamically scale to fit the jersey.

I was able to center the text with some math involving getBoundingClientRect(), but I'm struggling with the dynamic sizing of the text. It looks fine at first, but then when I resize the screen, the text size does not remain proportional to the size of jersey.

I've included a code snippet below to demonstrate. Please help me understand why this sizing issue is occurring, and what I can do to achieve the proper text resizing.

EDIT: I now have enough reputation points to add images (woo!), so here are some pictures to demonstrate the resizing problem I'm referring to. The text does not scale proportionally with the jersey size when I zoom in/out. BUT, if I refresh the page after I zoom in/out, ie so that I start out with the zoomed-in/out version, the text size readjusts to the current jersey size and fits the jersey as desired.

原始尺寸缩小了放大了

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Jersey</title> </head> <body> <svg id="jersey"> <switch> <g> <g id="jerseyShape"> <path id="outline" fill="green" transform="translate(-40,0)" opacity="0.35" fill="none" stroke="#000000" stroke-width="1.5" d="M116.462,113.911V39.01 c0,0-18.493-5.977-15.317-30.633c0,0-8.033-2.616-8.78-3.363S91.617,9.311,79.29,9.124h-1.305 C65.656,9.311,65.656,4.268,64.909,5.015s-8.778,3.363-8.778,3.363C59.305,33.034,40.813,39.01,40.813,39.01v74.901 C40.813,113.911,74.434,126.427,116.462,113.911z" /> </g> <g id="jerseyContent"> <svg> <text id="name" font-family="Verdana" text-anchor="middle" dominant-baseline="central"> Jordan </text> <!-- Dynamically re-size name to fit jersey --> <script type="application/ecmascript"> //Get path's bounding rectangle var pathNode = document.getElementById("outline"); var pRect = pathNode.getBoundingClientRect(); //Get text's bounding rectangle var textNode = document.getElementById("name"); var tRect = textNode.getBBox(); //Calculate the necessary scale to make the text fit within the jersey width while //not exceeding a height of 30 var widthRatio = (pRect.width * 0.85) / tRect.width; var heightRatio = (pRect.height*0.3) / tRect.height; var textScale = Math.min(widthRatio, heightRatio); //Translate text to center of jersey and scale to fit textNode.setAttribute("transform", "translate(" + (1 + pRect.width / 2) + " " + (pRect.top + pRect.height / 2) + ")scale(" + textScale + ")"); </script> </svg> </g> </g> </switch> </svg> </body> </html> 

You should also use getBBox() fo get the size of the path as well. That way, the dimensions will be in the same coordinate space even after scaling.

The problem is because you are calculating the scale on the group which contains the textnode.

I have solved you problem by giving the scale on the whole g element with id= "full"

So now you can change the scale value on id="full" and get desired result without the label going out. I have updated the code such that it takes into account the scale value on zoom in zoom out (ctrl +/ ctrl -)

 $(window).on("resize", function(){ var scale = "scale("+window.devicePixelRatio+")" $("#full").attr("transform", scale) console.log($("#full").attr("transform")); }) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Jersey</title> </head> <body style="width:100%; height:100%"> <svg style=" height: 602px; width: 100%;"> <g id="full" transform="scale(1)"> <g id="jerseyShape" transform="translate(-40,0)"> <path id="outline" fill="green" opacity="0.35" fill="none" stroke="#000000" stroke-width="1.5" d="M116.462,113.911V39.01 c0,0-18.493-5.977-15.317-30.633c0,0-8.033-2.616-8.78-3.363S91.617,9.311,79.29,9.124h-1.305 C65.656,9.311,65.656,4.268,64.909,5.015s-8.778,3.363-8.778,3.363C59.305,33.034,40.813,39.01,40.813,39.01v74.901 C40.813,113.911,74.434,126.427,116.462,113.911z" /> <text id="name" transform="translate(80,80)" font-family="Verdana" text-anchor="middle" dominant-baseline="central"> Jordan </text> </g> </g> </svg> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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