I am trying to convert text to svg to get the length of svg path. But I am getting the error:
Uncaught TypeError: svgPath.getBBox is not a function
I tried a lot and search a lot but didn't find any solution.
If i have to insert the SVG
element in the Html, then how can i get the svg element
in the context api file?
The texts and svgs will be multiple.
You can check the live website here, if you need to review first: https://uineon.hadithapi.com/
Component:
import { useCustomizer } from '../context/CustomizerContext'
export default function Preview() {
const { settings } = useCustomizer()
return (
<div className="preview">
<div className="preview-items">
{settings.textItems.map((item, index) => (
<div
className="preview-items--item"
style={{
"--text-color": item.color
}}
>
<div
className={`preview-items--item__text ${item.backplate}`}
style={{
fontFamily: item.font,
fontSize: `${item.size}px`
}}
>{item.text}</div>
</div>
))}
</div>
</div>
)
}
Context File:
import { createContext, useContext } from "react"
export const CustomizerContext = createContext()
export default function CustomizerState(props) {
const backplateUnitPrice = 3
const size = 30
const backplatePrice = size * backplateUnitPrice
const initialTextItem = {
text: "Hello",
font: "Raleway",
size,
color: "#000",
backplate: "cut-sharp",
uvPrint: false,
neonPrice: 0,
backplatePrice,
totalPrice: 0
}
const [settings, setSettings] = useState({
textItems: [initialTextItem]
})
const addTextItem = () => {
textToSvg("Hello");
const newItems = [...settings.textItems, initialTextItem]
setSettings((prevState) => (
{...prevState, textItems: newItems}
))
}
function textToSvg(text) {
const svgString = `<svg viewbox="387 390 74 20"> <g> <path class="st37" d="M452,408h-56c-4.42,0-8-3.58-8-8l0,0c0-4.42,3.58-8,8-8h56c4.42,0,8,3.58,8,8l0,0 C460,404.42,456.42,408,452,408z" /> </g></svg>`
const parser = new DOMParser();
const parsedDoc = parser.parseFromString(svgString, "image/svg+xml");
const parsedSvg = parsedDoc.querySelector('svg');
const svgPath = parsedSvg.querySelector('path')
console.log(parsedDoc)
console.log(parsedSvg)
console.log(svgPath)
let bbox = svgPath.getBBox();
let x = bbox.x + bbox.width / 2;
let y = bbox.y + bbox.height / 2;
// Create a <text> element
let textElem = document.createElementNS(svgPath.namespaceURI, "text");
textElem.setAttribute("x", x);
textElem.setAttribute("y", y);
// Centre text horizontally at x,y
textElem.setAttribute("text-anchor", "middle");
// Give it a class that will determine the text size, colour, etc
textElem.classList.add("label-text");
// Set the text
textElem.textContent = text;
// Add this text element directly after the label background path
svgPath.after(textElem);
console.log(svgPath);
}
return (
<CustomizerContext.Provider value={{settings, addTextItem}}>
{props.children}
</CustomizerContext.Provider>
)
}
export function useCustomizer() {
return useContext(CustomizerContext)
}
I am stuck, can someone help me to achieve this?
You have an odd viewBox
and path
If your objective is to center text over that path
, add a guide
path.
<svg viewbox="387 390 74 20"> <path d="M452,408h-56c-4.42,0-8-3.58-8-8l0,0c0-4.42,3.58-8,8-8h56c4.42,0,8,3.58,8,8l0,0 C460,404.42,456.42,408,452,408z"/> <path id="guide" d="M388 401h72" stroke="grey" pathLength="100"/> <text> <textPath href="#guide" startoffset="50" text-anchor="middle" dominant-baseline="middle" fill="gold" font-size="14px">Hello</textPath> </text> </svg>
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.