How to extend the text along the entire textPath in SVG - javascript

How do I make the text on a path (see screenshot) extend so that it follows the entire textPath?
I have tried using the method attribute value stretch but it doesn't work like I expect - it doesn't stretch the text along the path.
Is there a way to make this work in all browsers?

The way to spread out the text over the entire textPath is to use the textLength attribute. Also see this other question for how to compute a good value for textLength. Here's how to do it:
<svg viewBox="0 0 500 300" version="1.1">
<defs>
<path id="s3" d="M 10,90 Q 100,15 200,70" />
</defs>
<text font-size="20">
<textPath xlink:href="#s3" textLength="205">
Short text
</textPath>
</text>
<use xlink:href="#s3" fill="none" stroke="black" stroke-width="1"/>
</svg>
Viewable example: http://jsfiddle.net/zkZ2n/
Here's the bugreport for Firefox not supporting textLength: https://bugzilla.mozilla.org/show_bug.cgi?id=569722

Related

Is there a way to make a scrolling marquee on a SVG path using HTML and CSS?

I would like to make an effect as seen here or in the main menu of colin mcrae rally 2.0.
I would like to generate a path and then have text inside it that moves along the path and wraps around to the start as the the letters go off on end.
Looking at the html of the first example I saw that JS was used to make it but I'd like to avoid that if possible but that's not necessary.
Apologies since this is quite an open ended question with no actual code of my own to show, since this might be a problem of not knowing the correct search terms to get the correct resources I need to create this.
You can use textPath and SVG animation with SMIL.
I made two identical texts that are animated along the path. It is not perfect aligned - that is your task.
<svg width="200px" height="200px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<style>
text { font-size: 8px }
</style>
<symbol id="s1">
<path id="p1" d="M 0,0 C 5,10 5,40 20,40 35,40 60,55 60,70 60,85 100,100 100,100" />
</symbol>
<use href="#s1" stroke="silver" stroke-width="10" fill="none" />
<text dominant-baseline="middle">
<textPath href="#p1" startOffset="100%">
Text 1, text 2, text 3, text 3, text 4
<animate
attributeName="startOffset" from="100%" to="-100%"
dur="10s" repeatCount="indefinite" />
</textPath>
</text>
<text dominant-baseline="middle">
<textPath href="#p1" startOffset="100%">
Text 1, text 2, text 3, text 3, text 4
<animate
attributeName="startOffset" from="100%" to="-100%"
dur="10s" begin="5s" repeatCount="indefinite" />
</textPath>
</text>
</svg>

Keeping parts of an SVG at fixed size

Essentially I needed to make the center "cut-out" keep a fixed shape and size regardless of vector scale. Is there a way to achieve this?
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none" style="fill-rule:evenodd;" viewBox="0 0 2802 2657">
<path d="M290 4c-95,733 -191,1466 -286,2200 760,150 1520,300 2279,450 172,-223 343,-446 515,-669 -114,-572 -229,-1144 -343,-1716 -722,-88 -1444,-176 -2165,-264zm696 1027c-103,111 -205,222 -308,333 94,111 188,222 282,333 342,-205 684,-410 1026,-616 -333,-17 -667,-34 -1000,-51z"/>
</svg>
So I managed to do something after some editing to your SVG.
To achieve what you're asking you'll need to use / have :
- the SVG mask attribute
- A very large shape for the mask ( as much large as the max scale you want to use on the visible shape )
- The shape that you want to resize
- Resize the shape with transforms
Your SVG should looks like the following
<svg>
<defs>
<mask id="theMask">
<path fill="#ffffff" d=""/>
</mask>
</defs>
<g mask="url(#theMask)">
<path fill="#ffffff" id="shapetoresize" d=""/>
</g>
</svg>
I posted a pen as a "Proof of concept"
Feel free to fork it and use it to achieve what you're trying to do.
Codepen
note: as pointed out by #thioutp , The JS is only for demo purposes, you don't need GSAP to achieve this.

SVG Hover State with Multiple Elements

Good afternoon everyone,
I'm defining an SVG on my page with the following defs.
<svg width="0" height="0">
<defs>
<g id="stroke-hexagon">
<polygon fill="#002663" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="12" points="57.8,185 5.8,95 57.8,5 161.8,5 213.8,95 161.8,185 "/>
</g>
<g id="hexagon">
<polygon fill="#006890" points="52,180 0,90 52,0 156,0 208,90 156,180 "/>
</g>
</defs>
</svg>
...and implementing it later in the HTML using this:
<svg width="208px" height="180px" viewBox="0 0 208 180" >
<use xlink:href="#hexagon"></use>
<text class="faicon" x="50%" y="70px" fill="white" font-size="80px" text-anchor="middle">&#xf040</text>
<text text-anchor="middle" x="50%" y="70%" fill="white">Logo Here</text>
</svg>
Works totally fine. I am also able to style the polygon's fill with simple CSS. Looks like this:
#hexagon:hover polygon {
fill:#990000;
}
The hover effect fails, however, whenever the mouse leaves the polygon and instead hovers over either of the 'text' elements within the svg. Is there a way to define a CSS rule that prevents this behavior. Or, would it be better (easier) to change the attribute using JS / jQuery?
Thanks!
Your texts are rendered on top of your polygon and are therefore intercepting mouse events. You should set up a css rule like
text {
pointer-events: none;
}
This will prevent the text from becoming a target of mouse events which should give you the desired hover effect for the polygon.

JavaScript - Is there a way how to draw SVG path UNDER the content?

I need a path that goes UNDER the content (text) - is there a way how to do that?
(as already been answered somewhere else, z-index doesnt affect svg paths)
You can declare PATH and TEXT in different SVG layers, and put one layer onto another like this
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:1">
<text x="100" y="15" fill="red">I love SVG</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="position:absolute;z-index:0">
<path d="M150 0 L75 200 L225 200 Z" />
</svg>
http://jsfiddle.net/WJZrU/

How can I animate a drawing effect? (Preferably css3 only)

I want to make a drawing effect of tree that looks something like this one with a progressive line like here. I would prefer using only css3 with svg/canvas and js. Do you have any ideas?
More info:
I tried to cut a tree into pieces and animate piece by piece the appearance but it's not cursive cause it's to much details on syncronizing delays and durations because every piece has a different length and so on. All of this is made without svg. I want to now if i can animate a line path.
Yes, take a look at this rendering of the Bahamas Logo using CSS 3
It describes his process, and techniques. Also you can view the source.
There are more that can be found here
Update:
Also maybe this Sencha Animator product may help?
You can do this with plain SVG. SVG provides the <animate> element for declarative animation.
What you want (as I understand it) is a line that appears as if it was drawn in front of the viewer's eyes. You can use the stroke-dasharray property for this purpose. This property defines a dash pattern using a series of values that defines the length of dashes and gaps. The strategy would be: First we have a dash that has length 0 and a gap that is at least as long as the whole path. This means we see nothing (or only the first point at the start of the path). In the end we want a dash that's at least the full length of the path. We want the dash to gradually become longer and longer until it reaches its final length (the length of the full path).
The simplest case would be:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<!-- This is the path of a spiral -->
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305">
<!-- This defines the animation:
The path is roughly 2305 units long, it will be drawn in 5 seconds -->
<animate from="0,2305" to="2305,0" dur="5s"
attributeName="stroke-dasharray" repeatCount="indefinite"/>
</path>
</svg>
More sophisticated things can be done using multiple values (using the values attribute) instead of one from and one to value:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305">
<animate attributeName="stroke-dasharray" dur="5s" repeatCount="indefinite"
values="0,2305;
2000,305;
2305,0"/>
</path>
</svg>
You can specify the precise timing (when which value listed in values will be reached) using the keyTimes attribute:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305">
<animate attributeName="stroke-dasharray" dur="5s" repeatCount="indefinite"
values="0,2305;
2000,305;
2305,0"
keyTimes="0;.9;1"/>
</path>
</svg>
See this in action on Tinkerbin.
Something similar can be done using CSS3:
<svg xmlns="http://www.w3.org/2000/svg" width="400px" height="300px">
<style type="text/css">
path {
animation-name:animateDash;
animation-duration:5s;
animation-iteration-count:infinite;
}
#keyframes animateDash {
from{stroke-dasharray:0,2305}
to {stroke-dasharray:2305,0}
}
</style>
<path d="m 7.1428565,220.9336 c 0,0 13.6660115,54.75386 218.5714335,51.42857 C 430.61971,269.03688 478.47682,99.194335 206.69537,110.78149 -65.086093,122.36866 45.497658,213.22607 210.28635,207.29759 375.07503,201.3691 429.75297,97.468925 207.14285,82.362175 -15.467268,67.255425 64.868608,160.66909 210,153.79075 c 145.13139,-6.87834 137.69998,-93.087405 11.42857,-99.999995 -126.271412,-6.9126 -150.382292,28.03248 -24.28571,35.71428 126.09659,7.6818 72.6601,-44.83727 -5.71429,-84.2857095"
stroke-width="10" stroke-linecap="round" fill="none" stroke="black" stroke-dasharray="0,2305"/>
</svg>
Decide for yourself which method you prefer.

Categories

Resources