Iβm working with an SVG element where I have a marquee effect with curved text using the <textpath>
element. Currently, I am using the π emoji as a part of the marquee text, but I would like to replace this emoji with a custom SVG image and rotate the image around its axis.
The problem Iβm encountering is that when I replace the emoji with a custom image (either through an <img>
tag or inline SVG), the image doesnβt appear, and the text simply shows. Additionally, I want to apply a custom class to this image for styling (e.g., to rotate it). However, whenever I try to add the class to the emoji, it disappears.
What Iβve Tried:
Replacing the emoji with an inline <img>
tag that references the custom SVG image or an SVG element inline.
Applying custom CSS classes like .rotate-image
to rotate the image.
Expected Outcome:
The custom SVG image should appear in the marquee path instead of the π emoji.
The image should be styled using a custom class (e.g., .rotate-image
) for rotation.
The image should rotate smoothly using the defined CSS animation.
Issue:
The custom image doesnβt appear when I replace the emoji. Only the text shows up, not the image.
If I try to insert the custom image or use inline HTML elements, the image disappears, leaving only the text behind.
Can anyone suggest a solution or provide guidance on how I can successfully replace the emoji with a custom SVG image in the <textpath>
and apply a custom CSS class for rotation and styling?
Hereβs the code Iβm currently working with:
function startMarquee(id, pathId, content, speed) {
const textPath = document.getElementById(id);
const path = document.getElementById(pathId);
const pathLength = path.getTotalLength();
textPath.innerHTML = content;
let offset = 0;
function animateText() {
offset = (offset + speed) % pathLength;
textPath.setAttribute('startOffset', `${offset}px`);
requestAnimationFrame(animateText);
}
requestAnimationFrame(animateText);
}
document.addEventListener('DOMContentLoaded', () => {
const textContent = "Web Design π Web Development π UI/UX Design π Front-end Development π HTML & CSS π JavaScript π Responsive Design π E-Commerce Solutions π SEO Optimization π Digital Marketing π Web Hosting π Content Management π Website Performance π Website Maintenance π Branding π User-Centered Design π Cross-Browser Compatibility π Website Security π Mobile Optimization π Conversion Rate Optimization π Site Speed Optimization";
startMarquee('marquee-text-curved', 'text-path-curved', textContent, 2);
});
body {
background-color: #0d0d0d;
padding: 0;
margin: 0;
}
.elementor-svg-marquee {
width: 100% !important;
height: 100vh !important;
display: block;
margin: 0 auto;
padding: 0 !important;
overflow: hidden;
}
.uppercase-text-curved {
fill: #FFFFFF;
font-size: 2rem !important;
}
text {
font-size: 2rem !important;
}
/* Outer border for the stroke */
.curved-path-border {
stroke-width: 6.1rem;
/* Simulates the border */
stroke: #2fb7d9;
/* Border color */
fill: none;
filter: drop-shadow(0px 0px 5px #2fb7d9);
}
/* Actual stroke */
.curved-path {
stroke-width: 6rem;
/* Slightly smaller than the border */
stroke: black;
/* Stroke color */
fill: none;
}
@media (max-width: 768px) {
text {
font-size: 4rem !important;
}
.curved-path-border {
stroke-width: 8.1rem;
}
.curved-path {
stroke-width: 8rem;
}
}
@media (max-width: 480px) {
text {
font-size: 2rem !important;
}
.curved-path-border {
stroke-width: 6.1rem;
}
.curved-path {
stroke-width: 6rem;
}
}
<div>
<svg class="elementor-svg-marquee" viewbox="-50 0 1300 300" xmlns="http://www.w3.org/2000/svg">
<defs>
<path
id="text-path-curved"
d="M -100 150 Q 200 -50, 400 150 Q 600 350, 800 150 Q 1000 -50, 1300 150"
/>
</defs>
<!-- Simulated border -->
<path
class="curved-path-border"
d="M -100 150 Q 200 -50, 400 150 Q 600 350, 800 150 Q 1000 -50, 1300 150"
/>
<!-- Actual stroke -->
<path
class="curved-path"
d="M -100 150 Q 200 -50, 400 150 Q 600 350, 800 150 Q 1000 -50, 1300 150"
/>
<!-- Scrolling text -->
<text
font-family="Rubik, sans-serif"
class="uppercase-text-curved"
text-anchor="middle"
dominant-baseline="middle"
>
<textpath id="marquee-text-curved" href="#text-path-curved"></textpath>
</text>
</svg>
</div>
Neither <img>
nor <svg>
are permitted content for a <textpath>
.
You could arrive at a partial solution by building your own font.
@font-face
style rule which establishes a font-family
name and a reference to your font file.<tspan></tspan>
tags (permitted content for a <textpath>
)<tspan></tspan>
tags, probably by using an escape sequence for your character code.textpath > tspan
style rule specifying your font-family
name.This would at least be an improvement on the emoji, even without any animated rotation.
My research leads me to believe that while SVG does support animation generally, it cannot be applied to <tspan>
elements.