SVG animation on scroll once - javascript

Hi everyone I can program, and I saw a few weeks ago, that SVG animations are pretty useful!
Now my question:
I want to animate text like this website: https://weaintplastic.com/ I do not want the other things, just the Animation! I tried a lot of things, Exported via Illustrator a svg but it did not worked out. I do not want to use, any tool from github!
My assumption is:
I have to animate any letter in a Word (like the website), such that I have to know the paths from the svg! But this makes problem! How can I get a animation like this? Lets assume I want the word for ABOUT ME for example, how can I achieve CSS and JS which does the job for any svg if I have the path, or do I have to do for every Letter an own CSS and JS?
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 315 45" style="enable-background:new 0 0 315 45;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;}
</style>
<g>
<path d="M78.55,26.83l-2,5.75h-2.57l6.53-18.3h2.99l6.56,18.3h-2.65l-2.05-5.75H78.55z M84.85,24.98l-1.88-5.27
c-0.43-1.19-0.71-2.28-1-3.34h-0.06c-0.29,1.09-0.6,2.2-0.97,3.31l-1.88,5.29H84.85z"/>
<path d="M92.61,32.58c0.06-0.9,0.11-2.23,0.11-3.39V13.31h2.48v8.25h0.06c0.88-1.47,2.48-2.42,4.71-2.42c3.42,0,5.85,2.71,5.82,6.7
c0,4.7-3.11,7.03-6.19,7.03c-2,0-3.59-0.73-4.62-2.47h-0.09l-0.11,2.17H92.61z M95.2,27.32c0,0.3,0.06,0.6,0.11,0.87
c0.48,1.66,1.94,2.8,3.76,2.8c2.62,0,4.19-2.04,4.19-5.05c0-2.63-1.43-4.89-4.11-4.89c-1.71,0-3.31,1.11-3.82,2.93
c-0.06,0.27-0.14,0.6-0.14,0.98V27.32z"/>
<path d="M121.44,25.9c0,4.86-3.54,6.98-6.87,6.98c-3.74,0-6.62-2.61-6.62-6.76c0-4.4,3.02-6.98,6.84-6.98
C118.75,19.15,121.44,21.89,121.44,25.9z M110.48,26.04c0,2.88,1.74,5.05,4.19,5.05c2.4,0,4.19-2.14,4.19-5.1
c0-2.23-1.17-5.05-4.14-5.05S110.48,23.54,110.48,26.04z"/>
<path d="M136.15,29c0,1.36,0.03,2.55,0.11,3.58h-2.22l-0.14-2.14h-0.06c-0.66,1.06-2.11,2.44-4.56,2.44
c-2.17,0-4.76-1.14-4.76-5.75v-7.68h2.51v7.27c0,2.5,0.8,4.18,3.08,4.18c1.68,0,2.85-1.11,3.31-2.17c0.14-0.35,0.23-0.79,0.23-1.22
v-8.06h2.51V29z"/>
<path d="M143.33,15.67v3.77h3.59v1.82h-3.59v7.09c0,1.63,0.48,2.55,1.88,2.55c0.66,0,1.14-0.08,1.45-0.16l0.11,1.79
c-0.48,0.19-1.25,0.33-2.22,0.33c-1.17,0-2.11-0.35-2.71-1c-0.71-0.71-0.97-1.87-0.97-3.42v-7.17h-2.14v-1.82h2.14v-3.15
L143.33,15.67z"/>
<path d="M172.08,24.55c-0.14-2.55-0.31-5.62-0.29-7.9h-0.09c-0.66,2.14-1.45,4.42-2.42,6.95l-3.39,8.88h-1.88l-3.11-8.71
c-0.91-2.58-1.68-4.94-2.22-7.11h-0.06c-0.06,2.28-0.2,5.35-0.37,8.09l-0.51,7.84h-2.37l1.34-18.3h3.17l3.28,8.85
c0.8,2.25,1.46,4.26,1.94,6.16h0.09c0.48-1.85,1.17-3.86,2.02-6.16l3.42-8.85h3.17l1.2,18.3h-2.42L172.08,24.55z"/>
<path d="M188.76,24h-7.47v6.6h8.33v1.98H178.8v-18.3h10.38v1.98h-7.9v5.78h7.47V24z"/>
</g>
<g>
<rect x="54.72" y="8.99" class="st0" width="69.62" height="7.96"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>
I tried figma and svgator, and so on, but this is not useful, since I want to DO the ANIMATION WHEN I SCROLL on the section. (Once like the website).
I am sorry if my question is not Perfect, I tried my best to be precise as possible, and searched first on the Forum before I asked.

The technique has to be a combination with SVGGeometryElement.getTotalLength, stroke-dasharray, stroke-dashoffset, and the Intersection Observer API.
The example you provided has a lot more complex SVG elements than your own example. If you inspect the SVG you'll see that each letter consists of 1 or more <polygon> elements that are being animated. Being that your own SVG is a bit simpler I've built the example below on it.
First thing that is important is that the animation in the example animates the stroke property of each polygon. They do that by calculating the entire length of each path and setting both the stroke-dasharray and stroke-dashoffset properties with that total calculated path length. This will push the stroke out of the svg to be invisible, setting up the animation. (Each path has a different length, so setting the properties manually is a tedious job, let JS do it).
Then use the Intersection Observer API to determine when certain elements come into view. In this case I've chosen to watch for whole sections to come into view. Whenever a section enters the viewport, it will add an animate class to the section. In CSS I've defined that the class will trigger an animation that will change the stroke-dashoffset property. This will cause the stroke to animate back into the SVG.
const paths = document.querySelectorAll('svg path');
const sections = document.querySelectorAll('section');
paths.forEach((path, index) => {
const length = path.getTotalLength();
path.style.strokeDashoffset = `${length}px`;
path.style.strokeDasharray = `${length}px`;
path.style.animationDelay = `${index * 250}ms`;
});
const onInterSection = (entries, observer) => {
for (const { isIntersecting, target } of entries) {
if (isIntersecting) {
target.classList.add('animate');
observer.unobserve(target);
}
}
};
const observer = new IntersectionObserver(onInterSection);
for (const section of sections) {
observer.observe(section);
}
.st0 {
fill: none;
}
section {
display: grid;
place-items: center;
height: 75vh;
}
section:first-of-type {
background-color: #f7f7f7;
}
section:nth-of-type(2) {
background-color: #d7d7d7;
}
section:nth-of-type(2) {
background-color: #e7e7e7;
}
path {
stroke: black;
stroke-width: 1px;
fill: none;
}
section.animate path {
animation: letter 2s 1s forwards ease-out;
}
#keyframes letter {
to {
stroke-dashoffset: 0;
}
}
<section>
<span>Scroll down to animation</span>
</section>
<section>
<span>A bit further</span>
</section>
<section>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 315 45" style="enable-background:new 0 0 315 45;" xml:space="preserve">
<path d="M78.55,26.83l-2,5.75h-2.57l6.53-18.3h2.99l6.56,18.3h-2.65l-2.05-5.75H78.55z M84.85,24.98l-1.88-5.27
c-0.43-1.19-0.71-2.28-1-3.34h-0.06c-0.29,1.09-0.6,2.2-0.97,3.31l-1.88,5.29H84.85z"/>
<path d="M92.61,32.58c0.06-0.9,0.11-2.23,0.11-3.39V13.31h2.48v8.25h0.06c0.88-1.47,2.48-2.42,4.71-2.42c3.42,0,5.85,2.71,5.82,6.7
c0,4.7-3.11,7.03-6.19,7.03c-2,0-3.59-0.73-4.62-2.47h-0.09l-0.11,2.17H92.61z M95.2,27.32c0,0.3,0.06,0.6,0.11,0.87
c0.48,1.66,1.94,2.8,3.76,2.8c2.62,0,4.19-2.04,4.19-5.05c0-2.63-1.43-4.89-4.11-4.89c-1.71,0-3.31,1.11-3.82,2.93
c-0.06,0.27-0.14,0.6-0.14,0.98V27.32z"/>
<path d="M121.44,25.9c0,4.86-3.54,6.98-6.87,6.98c-3.74,0-6.62-2.61-6.62-6.76c0-4.4,3.02-6.98,6.84-6.98
C118.75,19.15,121.44,21.89,121.44,25.9z M110.48,26.04c0,2.88,1.74,5.05,4.19,5.05c2.4,0,4.19-2.14,4.19-5.1
c0-2.23-1.17-5.05-4.14-5.05S110.48,23.54,110.48,26.04z"/>
<path d="M136.15,29c0,1.36,0.03,2.55,0.11,3.58h-2.22l-0.14-2.14h-0.06c-0.66,1.06-2.11,2.44-4.56,2.44
c-2.17,0-4.76-1.14-4.76-5.75v-7.68h2.51v7.27c0,2.5,0.8,4.18,3.08,4.18c1.68,0,2.85-1.11,3.31-2.17c0.14-0.35,0.23-0.79,0.23-1.22
v-8.06h2.51V29z"/>
<path d="M143.33,15.67v3.77h3.59v1.82h-3.59v7.09c0,1.63,0.48,2.55,1.88,2.55c0.66,0,1.14-0.08,1.45-0.16l0.11,1.79
c-0.48,0.19-1.25,0.33-2.22,0.33c-1.17,0-2.11-0.35-2.71-1c-0.71-0.71-0.97-1.87-0.97-3.42v-7.17h-2.14v-1.82h2.14v-3.15
L143.33,15.67z"/>
<path d="M172.08,24.55c-0.14-2.55-0.31-5.62-0.29-7.9h-0.09c-0.66,2.14-1.45,4.42-2.42,6.95l-3.39,8.88h-1.88l-3.11-8.71
c-0.91-2.58-1.68-4.94-2.22-7.11h-0.06c-0.06,2.28-0.2,5.35-0.37,8.09l-0.51,7.84h-2.37l1.34-18.3h3.17l3.28,8.85
c0.8,2.25,1.46,4.26,1.94,6.16h0.09c0.48-1.85,1.17-3.86,2.02-6.16l3.42-8.85h3.17l1.2,18.3h-2.42L172.08,24.55z"/>
<path d="M188.76,24h-7.47v6.6h8.33v1.98H178.8v-18.3h10.38v1.98h-7.9v5.78h7.47V24z"/>
<rect x="54.72" y="8.99" class="st0" width="69.62" height="7.96"/>
</svg>
</section>

Related

Svg button path animation

I have this SVG button that I'm trying to animate on hover . I want the button to have a blob effect on the hover. I hope you guys can help me out. Here is the link to the SVG
https://codepen.io/haroldhall/pen/ZEJWJqo
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 169.5451 69.2823">
<defs>
<style>
.fbfb67fb-85bf-41e7-ba32-d1082da05d29 {
fill: #ff83b5;
}
</style>
</defs>
<g id="ee4ac112-3396-4e4b-9bd2-9cf074846425" data-name="Layer 2">
<g id="b0f8822e-1e1e-4dce-a2e6-9a8bebf20196" data-name="Background">
<path id="original" class="fbfb67fb-85bf-41e7-ba32-d1082da05d29" d="M76.9857,59.1319C52.7693,55.9614,1.16,89.3257.01,40.4447-.7354,8.7354,38.7113-11.033,76.1673,6.64c33.8056,15.9511,84.1836-17.2117,85.0374,23.6112C162.2335,79.4411,111.2431,65.3513,76.9857,59.1319Z" />
</g>
</g>
</svg>
CSS rule d: path (" M76 .....); not currently supported by the W3C SVG spec.
This is so far only an experimental technology of browsers based on the Blink engine.
Therefore, a solution based on rule d: path` will not be cross-browser, for example Firefox it does not work.
Consider a solution with SVG SMIL.
SMIL support
To morph the contours of the button, you need to create a final path in the vector editor in the form of a drop
The figures below show the process of getting the final path in the vector editor.
Grab the anchor point and drag it down until you get the desired shape.
Save the svg file and copy the final path to the morph animation command.
Below is the code for animating the morphing of the button outline into a drop shape:
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 169.5451 69.2823">
<defs>
<style>
.fbfb67fb-85bf-41e7-ba32-d1082da05d29 {
fill: #ff83b5;
}
</style>
</defs>
<g id="ee4ac112-3396-4e4b-9bd2-9cf074846425" data-name="Layer 2">
<g id="b0f8822e-1e1e-4dce-a2e6-9a8bebf20196" data-name="Background">
<path id="original" class="fbfb67fb-85bf-41e7-ba32-d1082da05d29" d="M77 59C53 56 1 89 0 40-1 9 39-11 76 7c34 16 84-18 85 23 1 49-50 35-84 29Z" >
<animate
attributeName="d"
begin="original.mouseover"
dur="1s"
fill="freeze"
restart="WhenNotActive"
values="
M77 59C53 56 1 89 0 40-1 9 39-11 76 7c34 16 84-18 85 23 1 49-50 35-84 29Z;
M81 113C57 110 1 89 0 40-1 9 39-11 76 7c34 16 84-18 85 23 1 49-45 89-80 83z"
/>
</path>
</g>
</g>
</svg>
not sure what kind of blob effect you're looking to have, but you can do this either with JS or CSS. Both involve changing the path to the new desired positions. I am including an example that changes a bit on hover. If you need help creating a blob I recommend https://www.blobmaker.app/
svg #original {
transition: all 0.5s;
}
svg:hover #original {
d: path("M76.9857,59.1319C52.7693,55.9614,1.16,189.3257.01,40.4447-.7354,8.7354,38.7113-11.033,76.1673,6.64c33.8056,15.9511,84.1836-17.2117,85.0374,23.6112C162.2335,179.4411,11.2431,65.3513,76.9857,59.1319Z");
}
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 169.5451 69.2823"><defs><style>.fbfb67fb-85bf-41e7-ba32-d1082da05d29{fill:#ff83b5;}</style></defs><g id="ee4ac112-3396-4e4b-9bd2-9cf074846425" data-name="Layer 2"><g id="b0f8822e-1e1e-4dce-a2e6-9a8bebf20196" data-name="Background"><path id="original" class="fbfb67fb-85bf-41e7-ba32-d1082da05d29" d="M76.9857,59.1319C52.7693,55.9614,1.16,89.3257.01,40.4447-.7354,8.7354,38.7113-11.033,76.1673,6.64c33.8056,15.9511,84.1836-17.2117,85.0374,23.6112C162.2335,79.4411,111.2431,65.3513,76.9857,59.1319Z"/>
</g></g></svg>

How to use and style (selector) nested symbols in SVG

I have something like the following:
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
grove > tree > triangle {
/* some triangle styles */
}
#grove1 > tree > triangle {
/* some triangle styles for grove 1 */
}
#grove2 > tree > triangle {
/* some triangle styles for grove 2 */
}
#grove3 > tree > triangle {
/* some triangle styles for grove 3 */
}
#grove3 > tree {
/* animate the tree */
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3000 3000">
<defs>
<symbol id="triangle" viewBox="0 0 100 100">
<polygon points="0,100 50,0 100,100" class="triangle" />
</symbol>
<symbol id="tree" viewBox="0 0 100 100">
<use href="#triangle" width="100" height="100" />
</symbol>
<symbol id="grove" viewBox="0 0 100 100">
<use href="#tree" width="10" height="10" />
<use href="#tree" width="10" height="10" x="20" />
<use href="#tree" width="10" height="10" x="40" />
<use href="#tree" width="10" height="10" x="60" />
<use href="#tree" width="10" height="10" x="80" />
</symbol>
</defs>
<use id="grove1" href="#grove" x="10" y="10" height="10"/>
<use id="grove2" href="#grove" x="30" y="100" height="100"/>
<use id="grove3" href="#grove" x="50" y="600" height="600"/>
</svg>
</body>
</html>
Notice that symbols are nested 3 levels deep. And the sizing definitions change at each symbol. For example, in the grove symbol, the viewBox is 100x100, but the trees which it contains also have their own view box of 100x100. The trees are sized to 10x10 in the grove, so they have a different scaling system.
Basically though, I compose these symbols into the grove symbol, then add those using use in 3 different places. Each one appears larger/closer than the one before. Or that's how it should work.
The question is how I can change the colors on these symbols efficiently and properly (best-practice). If I can do something like the example CSS above:
grove > tree > triangle {
/* some triangle styles */
}
Or if I have to use JavaScript somehow to change the styles in this situation, or otherwise not really use symbols at all, or create symbol for every color variation I want (somehow).
Please let me know how I should structure this SVG system so I can properly style each chunk of stuff (each "grove" for example, and its contents).
Another example I'd like for this to handle is, say each tree has branches. I want to have 5 rows of trees, as if it's parallax and each row is further in the distance than the one before, and as such they get lighter and lighter. So I would like to set the color of the branches and the "leaves" (main tree triangle) to be lighter and lighter as they move back. In addition, maybe I want to slightly change the color of the trees at a specific row. So I should be able to do something like this:
#grove1 > tree > branch { /* style */ }
#grove1 > #tree1 { /* style */ }
#grove1 > #tree2 { /* style */ }
#grove1 > #tree2 > #branch1 { /* style */ }
#grove1 > #tree2 > #branch2 { /* style */ }
#grove1 > etc...
Basically how to style the nested symbols individually. If it's not possible, then what the design pattern is I should be using instead.
Styles can inherit into the children of a <use> see below:
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
#grove {
/* some triangle styles */
}
#grove1 {
/* some triangle styles for grove 1 */
fill: red;
}
#grove2 {
/* some triangle styles for grove 2 */
fill: green;
}
#grove3 {
/* some triangle styles for grove 3 */
fill: gold;
}
#grove3 > tree {
/* animate the tree */
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3000 3000">
<defs>
<symbol id="triangle" viewBox="0 0 100 100">
<polygon points="0,100 50,0 100,100" class="triangle" />
</symbol>
<symbol id="tree" viewBox="0 0 100 100">
<use href="#triangle" width="100" height="100" />
</symbol>
<symbol id="grove" viewBox="0 0 100 100">
<use href="#tree" width="10" height="10" />
<use href="#tree" width="10" height="10" x="20" />
<use href="#tree" width="10" height="10" x="40" />
<use href="#tree" width="10" height="10" x="60" />
<use href="#tree" width="10" height="10" x="80" />
</symbol>
</defs>
<use id="grove1" href="#grove" x="10" y="10" height="10"/>
<use id="grove2" href="#grove" x="30" y="100" height="100"/>
<use id="grove3" href="#grove" x="50" y="600" height="600"/>
</svg>
</body>
</html>
You can style the <symbol> and it's children.
You can style the <use> element.
However you can't have selectors that cross the <use> "boundary".
#myuse > #mysymbol-child
will not work. You cannot use a selector to target a specific instance of that symbol. Except by inheritance from the <use> as I have done in my example.
A symbol is a definition. If you give it a direct style, then that symbol with whatever style it has, will be used everywhere. That includes things like animation. If you animate the symbol, all instances of it will be animated the same way.
If I remember correctly, the trick to do that is to set the properties you want to set differently for each instance of <use> to "inherit" or "currentColor" (or if they're inherited by default, don't set them, if you don't need to) and then place each <use> in a <g> and apply the style declarations to each <g>.
SVG - inherit multiple colors

Vivus JS doesn't seem to animate certain <path> nodes

I'm playing with the Vivus JS library, which is very cool for animating paths like drawing a picture. Now, I have this SVG icon that should animate to a 100% line-width, but it doesn't seem to work. On other icons in my project it works well.
See this CodePen: http://codepen.io/anon/pen/yOqdbN summarized as follows
<svg xmlns="http://www.w3.org/2000/svg">
<path d="...">
<path d="...">
</svg>
Does anyone know why this is happening? Thank you very much for any help pointing me in the right direction.
Vivus works by animating the strokeDashOffset property of a path which requires that your path has a stroke defined, e.g.
<path d="..." stroke="black">
Note that from your nodes I see that you can achieve better results setting fill="transparent"
var els = document.querySelectorAll('path');
Array.prototype.slice.call(els).forEach(function(el) {
el.setAttribute('stroke', 'black')
el.setAttribute('fill', 'transparent')
})
var SVGcrown = new Vivus('SVGcrown', {
duration: 300,
animTimingFunction: Vivus.EASE_OUT
});
body {
background: #FFF;
}
#SVGcrown {
width: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vivus/0.3.0/vivus.js"></script>
<svg id="SVGcrown" enable-background="new 0 0 48 48" version="1.1" viewBox="0 0 48 48" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M41.93,38H6.07l-0.251-0.167C2.175,35.413,0,31.363,0,27c0-7.168,5.832-13,13-13c2.069,0,4.128,0.499,5.954,1.442 l-0.918,1.777C16.47,16.41,14.776,16,13,16C6.935,16,2,20.935,2,27c0,3.594,1.744,6.936,4.681,9h34.638 C44.256,33.936,46,30.594,46,27c0-6.065-4.935-11-11-11c-1.778,0-3.473,0.411-5.04,1.222l-0.919-1.775 C30.868,14.5,32.929,14,35,14c7.168,0,13,5.832,13,13c0,4.363-2.175,8.413-5.819,10.833L41.93,38z"
/>
<path d="M42,48H6c-2.611,0-3.978-2.013-3.978-4.001C2.022,42.012,3.389,40,6,40h36c2.611,0,3.978,2.013,3.978,4.001 C45.978,45.988,44.611,48,42,48z M6,42c-1.46,0-1.978,1.077-1.978,1.999C4.022,44.922,4.54,46,6,46h36 c1.46,0,1.978-1.077,1.978-1.999C43.978,43.078,43.46,42,42,42H6z"
/>
<path d="M12.695,32.032c-0.411,0-0.795-0.255-0.942-0.663C11.253,29.97,11,28.5,11,27c0-7.168,5.832-13,13-13s13,5.832,13,13 c0,1.49-0.251,2.952-0.746,4.346c-0.186,0.52-0.76,0.789-1.277,0.607c-0.521-0.185-0.792-0.757-0.608-1.277 C34.788,29.498,35,28.262,35,27c0-6.065-4.935-11-11-11s-11,4.935-11,11c0,1.27,0.214,2.513,0.637,3.695 c0.186,0.521-0.085,1.093-0.605,1.278C12.92,32.014,12.807,32.032,12.695,32.032z"
/>
<path d="M24,12c-3.309,0-6-2.691-6-6s2.691-6,6-6s6,2.691,6,6S27.309,12,24,12z M24,2c-2.206,0-4,1.794-4,4s1.794,4,4,4 s4-1.794,4-4S26.206,2,24,2z" />
<path d="M29,7H19c-0.552,0-1-0.447-1-1s0.448-1,1-1h10c0.552,0,1,0.447,1,1S29.552,7,29,7z" />
<path d="M24,16c-0.552,0-1-0.447-1-1v-4c0-0.553,0.448-1,1-1s1,0.447,1,1v4C25,15.553,24.552,16,24,16z" />
</svg>

How to scale individual SVG elements with jQuery/Javascript?

I have a SVG with randomly dispersed squares on the page that scale up when the user scrolls past a certain point.
The issue I am having is that once the squares scale, it creates a horizontal scroll bar as if the entire SVG block scales, rather than the individual elements.
Is it possible to target each individual rect to scale in place with an easing motion rather than bluntly changing size (to give the impression that it's growing) so that it also doesn't stretch out the page, and then once the user continues to scroll, it reverts back to the original size?
Here is my: Updated JSFiddle
HTML:
<div class="move-wrapper">
<svg class="enlarge" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="82 -117 1363 770" style="enable-background:new 82 -117 1363 770;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#A7A9AC;stroke-width:5;stroke-miterlimit:10;}
</style>
<rect x="153" y="-34" class="st0" width="22.1" height="22.1"/>
<rect x="335.5" y="55.5" class="st0" width="22.1" height="22.1"/>
<rect x="529.5" y="343.1" class="st0" width="22.1" height="22.1"/>
<rect x="153.6" y="464.4" class="st0" width="22.1" height="22.1"/>
<rect x="976.5" y="166.4" class="st0" width="22.1" height="22.1"/>
<rect x="1288.3" y="-12.1" class="st0" width="22.1" height="22.1"/>
<rect x="941.9" y="575.3" class="st0" width="22.1" height="22.1"/>
<rect x="1355.9" y="434.9" class="st0" width="22.1" height="22.1"/>
</svg>
</div>
<div class="spacer"></div>
<div class="spacer"></div>
CSS:
.move-wrapper {
width:100%;
position:absolute;
}
.spacer {
height:500px;
}
JS:
$(function() {
$(window).on('scroll', function() {
scrollPosition = $(this).scrollTop();
if (scrollPosition >= 20) {
$(".enlarge").css({"-moz-transform": "scale(1.5,1.5)", "webkit-transform": "scale(1.5,1.5)"});
$(this).off('scroll');
}
if (scrollPosition >= 40) {
$(".enlarge").css({"-moz-transform": "scale(1,1)", "webkit-transform": "scale(1,1)"});
$(this).off('scroll');
}
});
});
Here's one possible solution: http://jsfiddle.net/_jered/0yy0nLam/
Move stylings into CSS whenever possible.
Wrap each rect in an svg to control positioning independent of scale.
Offset each rect by half it's width so that the transform is centered.
One thing to beware of is that I'm not sure if x and y attributes are part of the spec for svg elements. Seems to work in Chrome but not might be consistent across browsers. A more solid approach which I was too lazy to implement was to do a CSS transform instead.

Repeatedly selecting groups out of loaded SVG with Snap.svg

I'm kinda new with the whole SVG business, now I'm stumbling upon a problem that I really don't understand.
I'm animating icons at the moment and noticed that repeatedly selecting g's and applying them doesn't work for me. For the sake of the question I've made an example. What I would like it to do is: Load svg > Apply the first 'G' with mask > on click animate the child 'G' upwards > clear > Select a specific 'G' (this time again the first one) > animate it from the bottom to the center
For some reason in stead of grabbing the first 'G' it iterates over the 'G's in the SVG. I've tried this with using Select with Id's, but it's giving me the same troubles.
Sooo what am I doing wrong?
html
<svg id="svg"></svg>
js
var s = Snap("#svg");
s.attr({ viewBox: "0 0 300 300" });
var bigCircle = s.circle(150, 150, 100);
var bigCircle2 = s.circle(150, 150, 100);
bigCircle2.attr({
fill:"none",
stroke: "#0000e6",
strokeWidth: 6
});
bigCircle.attr({
fill: "#fff",
stroke: "#fff",
strokeWidth: 6
});
Snap.load("images/numbers.svg", function (f) {
var apply = function(number){
g = f.select("svg g:nth-child("+number+")");
s.append(g);
g.attr({
mask: bigCircle,
});
p = g.select("g");
};
apply(1); //Please give me the first g in the svg
var g_animate = function(){
p.animate({ transform: 't0,-200' }, 500, mina.easeout, function(){
p.remove();
apply(1); //Let's repeat the first g in the svg
p.attr({transform: 't0,200'});
p.animate({ transform: 't0,0' }, 500, mina.easein)
})
};
$("#svg").click(function(){
g_animate();
});
});
loaded svg
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="300px" height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
<g>
<g>
<path d="M162.367,212.803v-34.396h-58.358v-11.016l56.04-80.193h18.357v78.068h17.584v13.141h-17.584v34.396H162.367z
M162.367,165.266v-41.932c0-6.57,0.193-13.14,0.58-19.71h-0.58c-3.865,7.343-6.957,12.753-10.436,18.551l-30.724,42.705v0.387
H162.367z"/>
<rect fill="none" width="300" height="300"/>
</g>
</g>
<g>
<g>
<path d="M115.411,193.479c4.83,2.898,15.846,7.73,27.826,7.73c21.642,0,28.599-13.721,28.406-24.35
c-0.193-17.584-16.039-25.119-32.464-25.119h-9.469v-12.754h9.469c12.367,0,28.019-6.377,28.019-21.256
c0-10.049-6.377-18.938-22.029-18.938c-10.048,0-19.71,4.444-25.12,8.309l-4.638-12.367c6.764-4.83,19.517-9.662,33.043-9.662
c24.734,0,35.943,14.687,35.943,29.952c0,13.141-7.924,24.155-23.189,29.759v0.387c15.459,2.898,27.826,14.493,28.02,32.077
c0,20.098-15.846,37.682-45.796,37.682c-14.106,0-26.474-4.443-32.657-8.502L115.411,193.479z"/>
<rect fill="none" width="300" height="300"/>
</g>
</g>
<g>
<g>
<path d="M109.903,213.865v-10.435l13.334-12.947c32.077-30.531,46.764-46.764,46.764-65.7c0-12.754-5.991-24.542-24.735-24.542
c-11.4,0-20.869,5.798-26.666,10.628l-5.411-11.98c8.503-7.149,21.062-12.754,35.362-12.754c27.054,0,38.454,18.551,38.454,36.522
c0,23.188-16.812,41.933-43.285,67.439l-9.854,9.275v0.387h56.231v14.106H109.903z"/>
<rect fill="none" width="300" height="300"/>
</g>
</g>
<g>
<g>
<path d="M154.541,103.043h-0.387l-21.835,11.787l-3.285-12.946l27.439-14.687h14.494v125.605h-16.426V103.043z"/>
<rect fill="none" width="300" height="300"/>
</g>
</g>
</svg>
It won't keep repeating the same g element, as you remove it from the DOM with this...
p.remove();
So next time it selects, it the 2nd initial g will now be the first one.
Edit:
Its also worth looking at what happens with 'append'. If you append an element from a fragment (the data loaded from the file) into the DOM, then that element is no longer in the fragment f. So if you now select a new element, it will be the next g element (as the other one has been removed and added to the DOM). So if you wanted the SAME element, you want to use a css selector on s rather than f.
I'd be tempted to use a selectAll initially on the svg to get all of the g elements into an array and use those to reference them, it may feel more intuitive.

Categories

Resources