简体   繁体   中英

How to port JS code with dollar sign to svelte

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.

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.

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, eg 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');

Thanks a lot for the responses. With @httpete's insights, I rebuilt the logic in a way that makes more sense for svelte.

https://svelte.dev/repl/28905c0b02fa43278e77d9adc9b76d44?version=3.50.1

First I rebuilt the definition of the polygons into a json file then used an each loop to construct the svg. Then I used a svelte transition to animate it. The animation isnt perfect but works, feel free to comment on how to make it look better. Once again thanks for the assistance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM