Home > Software design >  How to port JS code with dollar sign to svelte
How to port JS code with dollar sign to svelte

Time:09-10

Im trying to get this animated polygon background from codepen working within a svelte component.

https://codepen.io/NyX/pen/bEbKZz

$(function () {
  const $polygons = $('.bg > polygon');

  const ANIM = {
    duration: 0.6,
    stagger: 0.005,

    from: {
      opacity: 0,
      scale: 0,
      transformOrigin: 'center center',
      force3D: true },


    to: {
      opacity: 1,
      scale: 1,
      ease: Elastic.easeInOut,
      force3D: true } };



  const timeline = new TimelineMax({
    delay: 0,
    repeat: 0
    //repeatDelay: 0.5,
    //yoyo: true
  });


  timeline.staggerFromTo($polygons, ANIM.duration, ANIM.from, ANIM.to, ANIM.stagger, 0);
  //TweenMax.staggerFromTo(polygons, ANIM.duration, ANIM.from, ANIM.to, ANIM.stagger);

  $('body').addClass('loaded');
});

I've tried a number of things but I cant seem to get it working, I tried making a svelte repl to show my progress but that isnt working either.

I think the source of the issue is not knowing how to handle the $ within the script tags of the svelte component.

Thanks for your time.

CodePudding user response:

The $ here, is from jquery (a library which used to be very popular a long time ago).

You don't need $(function () { and $('body').addClass('loaded'); because svelte will handle that for you (that basically waits for your page to be loaded before executing the function and adds a loaded class on the body).

You can get a reference of your polygon elements using bind:this in svelte (instead of using $('.bg > polygon')), then you can trigger the animation on the onMount function for example. I don't know much about this TweenMax thingy, I think you should use animation helpers in svelte to re-create the animation.

CodePudding user response:

In general you should avoid querying the DOM which is what jQuery (the $ utility) is for. To get a reference to elements in Svelte you can either use bind:this or apply an action via use:.

If you really have to query the DOM, you also do not necessarily need jQuery, as browsers now support querying anyway.

But if you need jQuery, e.g. to use some of its many plugins, you can usually import it directly from its NPM package and thus avoid using its globally defined shortcut ($).

import jQuery from 'jquery'; // jQuery == $

In this specific example, jQuery is completely unnecessary, though, and could be replaced with querySelectorAll.

For the animation, you can also import gsap directly. The code appears to use a very old version. In newer versions you would do it slightly differently.

When querying the DOM, I would recommend to at the very least use bind:this or an action on the root element, so selections become relative and do not accidentally affect anything outside the component. (When using bind:this you can only access the bound value after onMount.)

Full example using an action:

<script>
    import jQuery from 'jquery';
    import gsap from 'gsap'
    
    function animate(node) {
        const polygons = jQuery(node).find('polygon');
        const ANIM = {
            duration: 0.6,
            stagger: 0.005,
            from: {
                opacity: 0,
                scale: 0,
                transformOrigin: 'center center',
                force3D: true
            },
            to: {
                opacity: 1,
                scale: 1,
                ease: 'elastic',
                force3D: true
            }
        };

        const timeline = gsap.timeline({
            delay: 0,
            repeat: 0,
        });

        timeline.staggerFromTo(polygons, ANIM.duration, ANIM.from, ANIM.to, ANIM.stagger, 0);
    }
</script>

<svg xmlns="http://www.w3.org/2000/svg" version="1.1"
     use:animate
     width="100%" height="100%">
  ...
</svg>

REPL

Added a viewBox to scale down the SVG contents. And as noted, jQuery could just be replaced:

const polygons = node.querySelectorAll('polygon');
  • Related