11480 sujets

JavaScript, DOM et API Web HTML5

Bonsoir,

Je recherche en ce moment comment faire afficher une image d'une icône en svg animée (qui ne s'anime qu'une fois!) qui s'animerait au moment ou elle apparait au scroll.

Le type d'animation serait léger genre des petite étoiles qui bougent et dans le style du site hellobloom.io (page d'accueil --> Bloom protocol)

Auriez-vous des idées?

Je pense aux plugins lazyload ou bien scrollreveal, scrollto mais je ne sais pas s'ils permettent de charger l'image gif au scroll pour ne voir que ne seule fois l'animation svg (qui durerait environ 5 secondes)

Merci
Modifié par Oryo (27 Dec 2017 - 15:28)
Bonjour,

Concernant le chargement de l'image, j'ai trouvé la solution via lazysizes.
Lorsque j'arrive au niveau de l'image, l'image png se remplace bien par le svg.
Par contre il ne s'anime pas. J'ai une erreur javascript me disant :
"Uncaught TypeError: Cannot read property 'getTotalLength' of null"

Or si le svg est placé directement dans le html, l'animation se passe correctement.
Le javascript aurait-il du mal à accéder au svg, vu que je le charge via "data-src"?

Voici le code hml et javascript main.js:




<!DOCTYPE html>
<html>
<head>
	<title>Test</title>
	<script
	  src="https://code.jquery.com/jquery-3.2.1.js"
	  integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
	  crossorigin="anonymous">
	</script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>

	<div>
	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In scelerisque justo ut vulputate dignissim. Aenean pulvinar, dui nec ullamcorper egestas, sem felis dignissim ipsum, et mollis diam dolor eget eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent semper varius mauris nec scelerisque. Nullam aliquam interdum molestie. Quisque leo lectus, rutrum id metus sed, semper euismod erat. Proin eu velit eget nunc gravida faucibus. Donec id venenatis arcu, quis sagittis tortor. Nunc id est nisl. Nunc pellentesque cursus rutrum. Ut feugiat mi ut justo porta convallis. Donec suscipit sagittis leo venenatis luctus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. In scelerisque justo ut vulputate dignissim. Aenean pulvinar, dui nec ullamcorper egestas, sem felis dignissim ipsum, et mollis diam dolor eget eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent semper varius mauris nec scelerisque. Nullam aliquam interdum molestie. Quisque leo lectus, rutrum id metus sed, semper euismod erat. Proin eu velit eget nunc gravida faucibus. Donec id venenatis arcu, quis sagittis tortor. Nunc id est nisl. Nunc pellentesque cursus rutrum. Ut feugiat mi ut justo porta convallis. Donec suscipit sagittis leo venenatis luctus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. In scelerisque justo ut vulputate dignissim. Aenean pulvinar, dui nec ullamcorper egestas, sem felis dignissim ipsum, et mollis diam dolor eget eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent semper varius mauris nec scelerisque. Nullam aliquam interdum molestie. Quisque leo lectus, rutrum id metus sed, semper euismod erat. Proin eu velit eget nunc gravida faucibus. Donec id venenatis arcu, quis sagittis tortor. Nunc id est nisl. Nunc pellentesque cursus rutrum. Ut feugiat mi ut justo porta convallis. Donec suscipit sagittis leo venenatis luctus.</p>

	
	</div>

	<div>
		<iframe src="svg-statique.png" data-src="test.svg" class="lazyload" data-expand="-300" frameborder="0" allowfullscreen></iframe>
	</div>

	<script src="lazysizes.js"></script>
	<script src="main.js"></script>

</body>
</html>



Et le code javascript:


$(document).ready(function(){
	var tl = new TimelineMax();

	function onComplete(){

		$('.fenetre').addClass('cls-11');
		tl.from($('.cls-11'),1.5,{
			opacity:0,
		})
		var length = document.querySelector('path:last-child').getTotalLength(); /*-->C'est ici que ça coince*/
		tl.set($(".cls-2"), {className: '+=cls-21'});
		tl.set('path:last-child',{
		  strokeDasharray: length
		});
		tl.from('path:last-child', 2,{
		  strokeDashoffset: length
		})
	};
	
	tl.from('.fenetre',1,{
		transformOrigin:"center",
		scale:0,
		opacity:0,
		ease:Power1.easeOut,
		onComplete: onComplete,
	});

});
Modérateur
Bonjour,

Pour que document.querySelector('path:last-child') puisse trouver le dernier path du "svg", il faudrait que celui-ci soit ajouté au DOM.

Or il me semble que le script (lazysizes.js?) qui "charge" ton image "svg" dans ta page ne crée pas de svg dans le dom, mais remplace la valeur de l'attribut "src" de ton image par le svg (j'ai regardé le script vite fait sur github, mais je n'ai pas cherché à tout vérifier dans le détail, aussi je peux me tromper).

Ceci expliquerait pourquoi document.querySelector('path:last-child') fonctionne quand tu mets le svg dans le html (car du coup il est dans le dom), et expliquerait pourquoi document.querySelector('path:last-child') ne fonctionne pas quand le svg est chargé via le script (lazysizes.js?), puisqu'il n'est pas dans le dom (ou plus exactement pas accessible de la même manière).

Amicalement,
Modifié par parsimonhi (27 Dec 2017 - 19:23)
Modérateur
Bonjour,

Il se pourrait que tu puisses t'en sortir en mettant simplement ton code javascript à la fin de ton svg (en ajoutant aussi l'appel à jquery dans le svg, mais en laissant l'appel à lazysizes.js là où il est déjà).

Tu pourrais aussi, au lieu de faire l'animation en javascript, la faire en css (toujours en mettant le css d'animation dans le svg).

Je viens de faire le test avec le code suivant (en gros c'est ton code avec des choses en moins ! Smiley cligne ) :
<!DOCTYPE html>
<html>
<head>
	<title>Test</title>
	<style>
		iframe {width:150px;}
	</style>
</head>
<body>
	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. In scelerisque justo ut vulputate dignissim. Aenean pulvinar, dui nec ullamcorper egestas, sem felis dignissim ipsum, et mollis diam dolor eget eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent semper varius mauris nec scelerisque. Nullam aliquam interdum molestie. Quisque leo lectus, rutrum id metus sed, semper euismod erat. Proin eu velit eget nunc gravida faucibus. Donec id venenatis arcu, quis sagittis tortor. Nunc id est nisl. Nunc pellentesque cursus rutrum. Ut feugiat mi ut justo porta convallis. Donec suscipit sagittis leo venenatis luctus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. In scelerisque justo ut vulputate dignissim. Aenean pulvinar, dui nec ullamcorper egestas, sem felis dignissim ipsum, et mollis diam dolor eget eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent semper varius mauris nec scelerisque. Nullam aliquam interdum molestie. Quisque leo lectus, rutrum id metus sed, semper euismod erat. Proin eu velit eget nunc gravida faucibus. Donec id venenatis arcu, quis sagittis tortor. Nunc id est nisl. Nunc pellentesque cursus rutrum. Ut feugiat mi ut justo porta convallis. Donec suscipit sagittis leo venenatis luctus.Lorem ipsum dolor sit amet, consectetur adipiscing elit. In scelerisque justo ut vulputate dignissim. Aenean pulvinar, dui nec ullamcorper egestas, sem felis dignissim ipsum, et mollis diam dolor eget eros. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Praesent semper varius mauris nec scelerisque. Nullam aliquam interdum molestie. Quisque leo lectus, rutrum id metus sed, semper euismod erat. Proin eu velit eget nunc gravida faucibus. Donec id venenatis arcu, quis sagittis tortor. Nunc id est nisl. Nunc pellentesque cursus rutrum. Ut feugiat mi ut justo porta convallis. Donec suscipit sagittis leo venenatis luctus.</p>
	<div>
		<iframe src="go.png" data-src="go.svg" class="lazyload" data-expand="-150" frameborder="0" allowfullscreen></iframe>
	</div>
	<script src="lazysizes.js"></script>
</body>
</html>



L'image svg "go.svg" a le code suivant :
<!--
AnimCJK 2016-2017 Copyright Francois Mizessyn,  http://gooo.free.fr/animCJK/
 
Derived from:
    MakeMeAHanzi project -  https://github.com/skishore/makemeahanzi
 
    Arphic PL KaitiM GB -  https://apps.ubuntu.com/cat/applications/precise/fonts-arphic-gkai00mp/
 
    Arphic PL UKai -  https://apps.ubuntu.com/cat/applications/fonts-arphic-ukai/
 
You can redistribute and/or modify this file under the terms of the Arphic Public License
as published by Arphic Technology Co., Ltd.
You should have received a copy of this license (the directory "APL") along with this file;
if not, see  http://ftp.gnu.org/non-gnu/chinese-fonts-truetype/LICENSE.
 
-->
<svg id="z30849" class="acjk" version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
<![CDATA[
@keyframes z30849k {
	from {
		stroke:#c00;
		stroke-dashoffset:3000;
	}
	75% {
		stroke:#c00;
		stroke-dashoffset:0;
	}
	to {
		stroke:#000;
	}
}
#z30849 path[clip-path] {
	animation:z30849k 1s linear both;
	stroke-dasharray:3000;
	stroke-width:128;
	stroke-linecap:round;
	fill:none;
}
#z30849 path[clip-path="url(#z30849c1)"] {animation-delay:1s;}
#z30849 path[clip-path="url(#z30849c2)"] {animation-delay:2s;}
#z30849 path[clip-path="url(#z30849c3)"] {animation-delay:3s;}
#z30849 path[clip-path="url(#z30849c4)"] {animation-delay:4s;}
#z30849 path[clip-path="url(#z30849c5)"] {animation-delay:5s;}
#z30849 path[clip-path="url(#z30849c6)"] {animation-delay:6s;}
#z30849 path[clip-path="url(#z30849c7)"] {animation-delay:7s;}
#z30849 path[clip-path="url(#z30849c8)"] {animation-delay:8s;}
#z30849 path[clip-path="url(#z30849c9)"] {animation-delay:9s;}
#z30849 path[clip-path="url(#z30849c10)"] {animation-delay:10s;}
#z30849 path[clip-path="url(#z30849c11)"] {animation-delay:11s;}
#z30849 path[clip-path="url(#z30849c12)"] {animation-delay:12s;}
#z30849 path[clip-path="url(#z30849c13)"] {animation-delay:13s;}
#z30849 path {fill:#ccc;}
]]>
</style>
<path id="z30849d1" d="M637 209C645 207 653 206 663 205C709 197 736 191 744 185C750 181 752 175 750 168C746 160 734 152 715 146C693 140 669 142 643 150L583 165C514 179 457 189 413 195L356 200C329 201 301 202 273 203C248 206 244 214 260 226C290 245 323 251 359 245C359 245 360 245 362 245L411 239C465 231 523 223 584 215 Z"/>
<path id="z30849d2" d="M413 195C413 179 415 167 418 159C420 143 417 130 407 120C391 108 373 97 354 89C344 85 335 85 329 89C324 94 323 102 327 112C339 141 349 170 356 200L362 245C364 292 366 363 368 491L410 487C409 465 409 444 409 424L409 397L409 333L409 306C409 266 409 254 411 239 Z"/>
<path id="z30849d3" d="M619 463C625 369 631 295 637 209L643 150C645 138 647 127 649 118C653 104 657 91 659 80C661 72 656 63 643 53C618 41 597 32 581 28C570 26 562 27 556 33C551 39 551 47 556 57C572 83 581 105 582 121C582 135 582 150 583 165L584 215C584 300 581 374 575 469 Z"/>
<path id="z30849d4" d="M409 333L413 333C461 325 503 319 539 315C553 313 558 307 553 299C546 291 535 285 519 281C499 279 462 288 409 306 Z"/>
<path id="z30849d5" d="M409 424C457 418 499 413 535 407C549 405 554 399 549 391C542 383 531 377 515 373C496 371 461 379 409 397 Z"/>
<path id="z30849d6" d="M602 506C654 504 713 504 779 506C827 508 853 506 858 500C862 492 858 484 848 474C810 444 769 435 725 447C693 451 657 457 619 463L575 469C548 471 520 474 492 478C465 481 438 484 410 487L368 491C303 497 235 504 165 510C151 511 149 517 159 529C167 539 178 546 191 549C205 554 217 555 228 551C258 545 290 538 324 532L362 527C420 517 489 510 570 508 Z"/>
<path id="z30849d7" d="M324 532C324 580 280 641 193 715C191 716 189 717 188 719C163 740 120 770 59 809C53 812 53 815 60 817C102 817 165 776 249 713C251 711 253 709 256 707C286 683 325 653 374 598C380 592 386 587 390 584C394 582 397 577 398 570C398 564 394 557 388 548C380 538 371 531 362 527 Z"/>
<path id="z30849d8" d="M570 508C626 570 669 617 758 705C772 719 793 728 820 730C870 733 921 730 973 722C985 722 993 719 995 715C995 711 991 706 981 701C839 655 748 604 604 508L602 506 Z"/>
<path id="z30849d9" d="M432 659C474 652 611 640 646 627C655 623 649 614 642 607C635 600 625 597 611 591C585 583 521 602 463 610C430 616 401 620 371 621C352 623 349 639 363 647C369 652 389 654 401 657L402 658 Z"/>
<path id="z30849d10" d="M400 751C420 731 442 706 453 697C459 691 461 686 460 681C459 675 450 668 432 659L402 658C400 659 398 661 398 665C392 683 371 716 348 744L330 764C292 802 232 858 152 910C141 916 143 920 157 920C199 916 264 870 350 800 Z"/>
<path id="z30849d11" d="M348 744C346 744 344 743 342 743C335 743 330 744 328 746C325 749 326 755 330 764L350 800C358 820 367 854 375 882C377 896 383 907 393 915C403 927 410 928 414 919C414 915 415 910 416 906L412 875C403 835 397 797 395 781 Z"/>
<path id="z30849d12" d="M628 863C648 829 665 798 681 791C691 781 693 771 686 759C677 751 664 727 634 709C623 705 611 704 599 707C546 723 469 743 400 751L380 770L395 781C397 781 464 775 576 759C586 757 594 759 600 764C604 771 598 808 582 854 Z"/>
<path id="z30849d13" d="M416 906C422 906 428 906 435 906C475 900 549 897 637 894C643 894 647 891 649 885C649 881 642 873 628 863L582 854C581 854 580 854 579 854C520 865 458 871 412 875 Z"/>
<defs>
	<clipPath id="z30849c1"><use xlink:href="#z30849d1"/></clipPath>
	<clipPath id="z30849c2"><use xlink:href="#z30849d2"/></clipPath>
	<clipPath id="z30849c3"><use xlink:href="#z30849d3"/></clipPath>
	<clipPath id="z30849c4"><use xlink:href="#z30849d4"/></clipPath>
	<clipPath id="z30849c5"><use xlink:href="#z30849d5"/></clipPath>
	<clipPath id="z30849c6"><use xlink:href="#z30849d6"/></clipPath>
	<clipPath id="z30849c7"><use xlink:href="#z30849d7"/></clipPath>
	<clipPath id="z30849c8"><use xlink:href="#z30849d8"/></clipPath>
	<clipPath id="z30849c9"><use xlink:href="#z30849d9"/></clipPath>
	<clipPath id="z30849c10"><use xlink:href="#z30849d10"/></clipPath>
	<clipPath id="z30849c11"><use xlink:href="#z30849d11"/></clipPath>
	<clipPath id="z30849c12"><use xlink:href="#z30849d12"/></clipPath>
	<clipPath id="z30849c13"><use xlink:href="#z30849d13"/></clipPath>
</defs>
<path pathLength="2999" clip-path="url(#z30849c1)" d="M260 214L383 220L746 169"/>
<path pathLength="2999" clip-path="url(#z30849c2)" d="M335 92L383 157L392 488"/>
<path pathLength="2999" clip-path="url(#z30849c3)" d="M560 34L619 101L590 466"/>
<path pathLength="2999" clip-path="url(#z30849c4)" d="M414 325L547 303"/>
<path pathLength="2999" clip-path="url(#z30849c5)" d="M417 415L546 393"/>
<path pathLength="2999" clip-path="url(#z30849c6)" d="M160 516L215 529L747 474L854 485"/>
<path pathLength="2999" clip-path="url(#z30849c7)" d="M329 539L353 578L284 660L65 812"/>
<path pathLength="2999" clip-path="url(#z30849c8)" d="M581 514L790 663L986 713"/>
<path pathLength="2999" clip-path="url(#z30849c9)" d="M363 638L638 617"/>
<path pathLength="2999" clip-path="url(#z30849c10)" d="M453 680L413 692L296 819L155 915"/>
<path pathLength="2999" clip-path="url(#z30849c11)" d="M335 752L374 795L406 918"/>
<path pathLength="2999" clip-path="url(#z30849c12)" d="M387 771L609 739L644 782L600 857"/>
<path pathLength="2999" clip-path="url(#z30849c13)" d="M419 882L643 883"/>
</svg>



Enfin l'image png est l'image de mon avatar d'Alsacreations aux dimensions 150x150px.

Amicalement,
Modifié par parsimonhi (27 Dec 2017 - 20:23)
Bonjour,

Merci pour ta réponse, elle m'aura aidé à y voir plus clair.
J'ai tenté de mettre les javascript directement dans le svg ainsi que les liens menant au jquery et tweenmax via l'attribut xlink et même le simple src. Avec src, je voyait le svg mais toujours sans l'animation. Ave x:link, le svg n'était pas visible. L'image était comme introuvable.
https://fr.flossmanuals.net/svg/ajout-de-balise-script/
Je découvre aussi l'univers des svg par la même occasion et cela m'a l'air plutôt complexe et puissant à la fois.

J'ai par contre essayé de charger le svg avec une simple animation css et le tout fonctionne correctement. Toujours avec une balise img.
Apparememnt, il serait préférable via la balise object ou embed (pour un svg animé, interactif) mais j'utilise rarement ces balises. Je ne les connais pas très bien et je ne pense pas que lazysizes les prends en compte.

Merci!
Bon, je n'ai toujours pas réussi à faire afficher l'animation en utilisant des liens javascript externes.

Par contre, en placant tous les codes javascript sous les balises
<script>
<![CDATA[
// script ici
]]> </script>

et en placant également tout le code css dans le svg, cela fonctionne. En n'oubliant pas de charger mon svg via la balise iframe.

Ça progresse Smiley cligne

EDIT: Finalement, j'ai réussi avec xlink : https://www.wenovio.com/2016/11/22/marier-svg-javascript/

Sans doute que l'animation en fonctionnait pas avant car je n'avais pas placé tout le code css dans le svg correctement. Ouf! Je peux passer le nouvel an tranquille Smiley smile
Modifié par Oryo (31 Dec 2017 - 13:04)