jQuery Nature Cards with Click on Icon Effect

jQuery Nature Cards with Click on Icon Effect
Project: Environment Impact Cards (GSAP)
Author: Anton Mudrenok
Edit Online: View on CodePen
License: MIT

This code snippet helps you to create a nature card with a click effect. It defines and invokes animation functions for different elements on a webpage. The newWaveAnimation function creates an animation sequence using the TimelineMax class, defining how the wave element will rotate and move over time using different easing functions. Similar functions are defined for the treeAnimation and oilAnimation. setTimeout is used to start and then stop the treeAnimation after a certain time delay.

Lastly, jQuery event listeners are defined to start and stop animations for different cards based on whether the user clicks or hovers over them. When a user clicks on a card, the corresponding animation starts, and when the user leaves the card, all animations are stopped.

How to Create jQuery Nature Cards with Click on Icon Effect

First of all, load the following assets into the head tag of your HTML document.

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Raleway:300,700,900" rel="stylesheet"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">

Create the HTML structure for the nature card as follows:

<section class="title">
    <p>One Year of</p>
    <p>Receipts Takes</p>
</section>

<section class="cards">
    <div class="card card--oil">
        <div class="card__svg-container">
            <div class="card__svg-wrapper">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
                    <filter id="goo">
                        <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
                        <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9" result="goo" />
                        <feBlend in="SourceGraphic" in2="goo" />
                    </filter>
                    <circle cx="40" cy="40" r="39" fill="#6a7a87"/>
                    <g filter="url(#goo)">
                        <path id="myTeardrop" fill="#FFFFFF" d="M48.9,43.6c0,4.9-4,8.9-8.9,8.9s-8.9-4-8.9-8.9S40,27.5,40,27.5S48.9,38.7,48.9,43.6z"/>
                        <path id="TopInit"  fill="#FFFFFF" d="M13,10.8c5-5.3,10.7-8.5,18.3-9.8c11.2-1.8,9.2-1.4,17.6,0C58.3,2.7,66,6,69,13.1V-2.7L13-2.8V10.8z"/>
                        <path id="TopBulb" fill="#FFFFFF" d="M13,10.8c5-5.3,14.8-4,18.3,2.3c4.3,7.7,13.8,7.6,17.6,0c3.4-7,17.1-7.1,20.1,0V-2.7L13-2.8V10.8z" style="visibility: hidden"/>
                        <path id="TopBulbSm" fill="#FFFFFF" d="M13,10.8c5-5.3,18.5-14,23.3-8.8c3.6,3.9,3.9,4.5,7.6,0c5-6,22.1,3.9,25.1,11V-2.7L13-2.8V10.8z" style="visibility: hidden"/>
                        <path id="TopRound" fill="#FFFFFF" d="M13,10.8c5-5.3,10.6-6,18.3-6.8c6.5-0.7,10.5-0.8,17.6,0C58.4,5.1,66,6,69,13.1V-2.7L13-2.8V10.8z" style="visibility: hidden"/>
                    </g>
                </svg>
            </div>
        </div>
        <div class="card__count-container">
            <div class="card__count-text">
                <span class="card__count-text--big">250</span> Million
            </div>
        </div>
        <div class="card__stuff-container">
            <div class="card__stuff-icon">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13">
                    <path fill="#6a7a87" d="M9.4,2L9.2,2.3v0.4v7.6v0.4L9.4,11H3.6l0.3-0.3v-0.4V2.7V2.3L3.6,2H9.4 M12,1H1l1.8,1.7v7.6L1,12h11l-1.8-1.7V2.7L12,1L12,1z"/>
                    <line fill="none" stroke="#6a7a87" class="st0" x1="3" y1="6.5" x2="10" y2="6.5"/>
                </svg>
            </div>
            <div class="card__stuff-text"> Gallons of oil</div>
        </div>
    </div>
    <div class="card card--tree">
        <div class="card__svg-container">
            <div class="card__svg-wrapper">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
                    <circle cx="40" cy="40" r="39" fill="#6abf60"/>
                    <g id="Branches">
                        <polygon id="topBranches" fill="#FFFFFF" points="40.1,19.8 51.2,43.1 29,43.1"/>
                        <polygon id="botBranches" fill="#FFFFFF" points="40,28 52,54.3 28,54.3"/>
                    </g>
                    <rect id="Trunk" x="37.7" y="53.8" fill="#FFFFFF" width="4.7" height="6"/>
                    <rect id="Particle" x="37.9" y="54.3" fill="#FFFFFF" width="2" height="2"/>
                    <polygon id="Axe" fill="#FFFFFF" points="0.7,5.3 7.3,5.3 7.3,10.2 4,20.3 0.7,10.2"/>
                </svg>
            </div>
        </div>
        <div class="card__count-container">
            <div class="card__count-text">
                <span class="card__count-text--big">10</span> Million
            </div>
        </div>
        <div class="card__stuff-container">
            <div class="card__stuff-icon">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13">
                    <polygon fill="none" stroke="#6a7a87" points="3.5,1.5 5.5,1.5 5.5,5 9.5,1.5 9.5,9 11,11.5 2,11.5 3.5,9 "/>
                </svg>
            </div>
            <div class="card__stuff-text"> Trees cut </div>
        </div>
    </div>
    <div class="card card--water">
        <div class="card__svg-container">
            <div class="card__svg-wrapper">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
                    <circle cx="40" cy="40" r="39" fill="#60cbe7"/>
                    <g id="waveGroup">
                        <path id="waveTop" fill="#FFFFFF" d="M93,34.1c-3.5,0-5.8-1.1-8.1-4.1h0c-1.6,3-4.9,4.3-8.4,4.3c-3.5,0-6.1-1.3-8.4-4.3h0c-1.6,3-5.1,4.1-8.6,4.1
	c-3.5,0-6.6-2-8.6-4.6v0c-2,2.6-4.5,4.3-8,4.3c-3.5,0-6-1.7-8-4.3v0c-2,2.6-5.1,4.5-8.6,4.5c-3.5,0-6.3-1.1-8.5-4.1h0
	c-1.6,3-4.9,4.3-8.4,4.3C6,34.3,3.3,33,1.1,30h0c-1.6,3-4.5,4.1-8,4.1c-3.5,0-6-2-8-4.6v0c-2,2.6-5.5,4.3-9,4.3c-3.5,0-6-1.7-9-4.3
	v6.6c3,1.5,5.6,2.3,8.6,2.3s6.2-0.9,8.5-2.3c2.2,1.5,5.4,2.3,8.5,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5.4,2.3,8.4,2.3s6.1-0.9,8.4-2.3
	c2.2,1.5,5.4,2.3,8.4,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5.3,2.3,8.4,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5.3,2.3,8.4,2.3s6.1-0.9,8.4-2.3
	c2.2,1.5,5.3,2.3,8.4,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5,2.3,8,2.3s6-0.9,8-2.3v-6.6C100,32.1,96.5,34.1,93,34.1z"/>
                        <path id="waveBot" fill="#FFFFFF" d="M98,46.1c-3.5,0-5.8-1.1-8.1-4.1h0c-1.6,3-4.9,4.3-8.4,4.3c-3.5,0-6.1-1.3-8.4-4.3h0c-1.6,3-5.1,4.1-8.6,4.1
	c-3.5,0-6.6-2-8.6-4.6v0c-2,2.6-4.5,4.3-8,4.3c-3.5,0-6-1.7-8-4.3v0c-2,2.6-5.1,4.5-8.6,4.5c-3.5,0-6.3-1.1-8.5-4.1h0
	c-1.6,3-4.9,4.3-8.4,4.3C11,46.3,8.3,45,6.1,42h0c-1.6,3-4.5,4.1-8,4.1c-3.5,0-6-2-8-4.6v0c-2,2.6-5.5,4.3-9,4.3c-3.5,0-6-1.7-9-4.3
	v6.6c3,1.5,5.6,2.3,8.6,2.3s6.2-0.9,8.5-2.3c2.2,1.5,5.4,2.3,8.5,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5.4,2.3,8.4,2.3s6.1-0.9,8.4-2.3
	c2.2,1.5,5.4,2.3,8.4,2.3c3,0,6.1-0.9,8.4-2.3c2.2,1.5,5.3,2.3,8.4,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5.3,2.3,8.4,2.3
	c3,0,6.1-0.9,8.4-2.3c2.2,1.5,5.3,2.3,8.4,2.3s6.1-0.9,8.4-2.3c2.2,1.5,5,2.3,8,2.3s6-0.9,8-2.3v-6.6C105,44.1,101.5,46.1,98,46.1z"
                        />
                    </g>
                </svg>
            </div>
        </div>
        <div class="card__count-container">
            <div class="card__count-text">
                <span class="card__count-text--big">One</span> Billion
            </div>
        </div>
        <div class="card__stuff-container">
            <div class="card__stuff-icon">
                <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 13 13">
                    <path fill="none" stroke="#6a7a87" d="M1,1.5c0.9,0,0.9,2,1.8,2c0.9,0,0.9-2,1.8-2c0.9,0,0.9,2,1.8,2c0.9,0,0.9-2,1.8-2c0.9,0,0.9,2,1.8,2s0.9-2,1.8-2"/>
                    <path fill="none" stroke="#6a7a87" d="M1,5.5c0.9,0,0.9,2,1.8,2c0.9,0,0.9-2,1.8-2c0.9,0,0.9,2,1.8,2c0.9,0,0.9-2,1.8-2c0.9,0,0.9,2,1.8,2s0.9-2,1.8-2"/>
                    <path fill="none" stroke="#6a7a87" d="M1,9.5c0.9,0,0.9,2,1.8,2c0.9,0,0.9-2,1.8-2c0.9,0,0.9,2,1.8,2c0.9,0,0.9-2,1.8-2c0.9,0,0.9,2,1.8,2s0.9-2,1.8-2"/>
                </svg>
            </div>
            <div class="card__stuff-text"> Gallons of water</div>
        </div>
    </div>
</section>

Now, style the nature card using the following CSS styles:

*, *:before, *:after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  font-size: 62.5%;
  font-family: "Raleway", sans-serif;
}
@media screen and (max-width : 620px) {
  html, body {
    font-size: 45%;
  }
}
@media screen and (max-width : 480px) {
  html, body {
    font-size: 70%;
  }
}

.forhtml {
  background: radial-gradient(circle at bottom, #aac1c7, #f7fbfb 80%) no-repeat center center fixed;
  background-size: cover;
}

body {
  color: #686e74;
  overflow-x: hidden;
  min-height: 100vh;
}

section {
  width: 80vw;
  max-width: 64rem;
  min-width: 58.9rem;
  margin: 0 auto;
}
@media screen and (max-width : 480px) {
  section {
    min-width: 19rem;
  }
}

.title {
  font-size: 4rem;
  font-weight: 900;
  padding-top: 10vh;
}
@media screen and (max-width : 480px) {
  .title {
    font-size: 3rem;
    text-align: center;
    position: relative;
    padding-top: 6vh;
  }
}
.title:after {
  content: "";
  display: block;
  height: 0.3rem;
  width: 5.4rem;
  background-color: #fbcd8a;
  transform: translate(0.3rem, 2rem);
}
@media screen and (max-width : 480px) {
  .title:after {
    left: 50%;
    position: absolute;
    transform: translate(-50%, 2rem);
  }
}

.cards {
  padding-top: 6rem;
  display: flex;
  justify-content: space-between;
}
@media screen and (max-width : 480px) {
  .cards {
    flex-direction: column;
    align-items: center;
  }
}

.card {
  width: 19rem;
  height: 22.5rem;
  background-color: #f9fbfb;
  border-radius: 6px;
  position: relative;
  display: flex;
  flex-direction: column;
  color: #5a6c7a;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.05rem;
  box-shadow: 0 1rem 3rem #aac1c7;
}
@media screen and (max-width : 480px) {
  .card {
    margin-bottom: 2rem;
  }
}
.card__svg-container {
  height: 50%;
  display: flex;
  justify-content: center;
  align-items: flex-end;
}
.card__svg-wrapper {
  width: 8rem;
}
.card__count-container {
  flex-grow: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.card__count-text {
  transform: translate(0, -0.5rem);
}
.card__count-text--big {
  text-transform: uppercase;
  font-size: 5rem;
  font-weight: 300;
}
.card__stuff-container {
  margin: 0 auto;
  width: 90%;
  height: 15%;
  border-top: 2px solid #e7edef;
  display: flex;
  justify-content: center;
  align-items: center;
}
.card__stuff-icon, .card__stuff-text {
  display: inline-block;
}
.card__stuff-icon {
  width: 1.3rem;
  height: 1.3rem;
  transform: translate(0, -0.3rem);
}
.card__stuff-text {
  text-transform: uppercase;
  margin-left: 0.4rem;
  transform: translate(0, -0.2rem);
}
.card:after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 16rem;
  height: 5.625rem;
  transform: translate(1.5rem, 22.5rem);
  pointer-events: none;
}
.card--oil:after {
  background-image: radial-gradient(ellipse at top, rgba(106, 122, 135, 0.5), transparent 70%);
}
.card--tree:after {
  background-image: radial-gradient(ellipse at top, rgba(106, 191, 96, 0.5), transparent 70%);
}
.card--water:after {
  background-image: radial-gradient(ellipse at top, rgba(96, 203, 231, 0.5), transparent 70%);
}

Load the following scripts before closing the body tag:

<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js'></script>
<script src='//s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.min.js'></script>

Finally, add the following JavaScript function for its functionality:

function newAnimationObj(timeline = new TimelineMax()) {
  let obj = {};
  obj.last = false;
  obj.start = () => {
    obj.last = false;
    timeline.resume();
  };
  obj.stop = () => {obj.last = true;};
  return obj;
}

let newOilAnimation = () => {
  let oilTL = new TimelineMax({ repeat: -1, repeatDelay: 0.3 });
  let oilObj = newAnimationObj(oilTL);
  oilTL.
  to("#myTeardrop", 0.3, {
    y: 55,
    ease: Power3.easeIn }).

  set("#myTeardrop", {
    y: -53 }).

  to("#myTeardrop", 0.8, {
    y: -24,
    ease: Power4.easeIn }).

  to("#TopInit", 0.8, {
    morphSVG: { shape: "#TopBulb" },
    ease: Power4.easeIn },
  "-=0.8").
  to("#TopInit", 0.17, {
    morphSVG: { shape: "#TopBulbSm" },
    ease: Power0.easeOut }).

  to("#TopInit", 0.03, {
    morphSVG: { shape: "#TopInit" },
    ease: Power0.easeOut }).

  to("#TopInit", 0.05, {
    morphSVG: { shape: "#TopRound" },
    ease: Power0.easeNone }).

  to("#TopInit", 0.3, {
    morphSVG: { shape: "#TopInit" },
    ease: Bounce.easeOut }).

  to("#myTeardrop", 1.2, {
    y: 0,
    ease: Elastic.easeOut.config(1.2, 0.3),
    onComplete: () => {
      if (oilObj.last == true) oilTL.pause();
    } },
  "-=0.55").
  invalidate();
  oilTL.pause();
  return oilObj;
};

let newTreeAnimation = () => {
  let treeTL = new TimelineMax({ repeat: -1, repeatDelay: 0.3 });
  let treeObj = newAnimationObj(treeTL);
  TweenMax.set("#Axe", { transformOrigin: '50% 50%' });
  TweenMax.set(["#Branches", "#Trunk", "#topBranches", "#botBranches"],
  { transformOrigin: '50% 100%' });
  treeTL.
  to("#Axe", 0.3, {
    bezier: {
      values: [{ x: 0, y: 0 }, { x: 5, y: 37 }, { x: 30, y: 43 }],
      autoRotate: -90 },

    ease: Power1.easeIn }).

  to("#Axe", 0.2, {
    x: -10,
    ease: Power0.easeNone }).

  to("#Particle", 0.2, {
    x: -10,
    y: 4,
    ease: Power1.easeIn },
  "-=0.2").
  to("#Branches", 0.05, {
    rotation: 5,
    ease: Power0.easeNone },
  "-=0.25").
  to("#Branches", 0.05, {
    rotation: 0,
    ease: Power0.easeNone },
  "-=0.20").
  set("#Particle", { autoAlpha: 0 }).
  set("#Branches", { transformOrigin: '100% 100%' }).
  to("#Branches", 0.3, {
    rotation: 90,
    y: 7,
    ease: Bounce.easeOut },
  "+=0.05").
  to("#Branches", 0.5, {
    x: 28,
    ease: SlowMo.ease.config(0.5, 0.8, false) },
  "+=0.1").
  to("#Trunk", 0.2, {
    scaleY: 0,
    ease: SlowMo.ease.config(0.1, 0.7, true) },
  "+=0.1").
  set("#Branches", {
    x: 0,
    y: 0,
    rotation: 0 }).

  set("#topBranches", {
    scale: 0.1,
    y: 10 }).

  set("#botBranches", { scale: 0.1 }).
  to("#botBranches", 0.2, {
    scale: 1,
    ease: Power2.easeOut }).

  to("#topBranches", 0.2, {
    scale: 1,
    ease: Power2.easeOut },
  "-=0.15").
  to("#topBranches", 0.25, {
    y: 0,
    ease: Back.easeOut.config(3),
    onComplete: () => {
      if (treeObj.last == true) treeTL.pause();
    } },
  "-=0.15").invalidate();
  treeTL.pause();
  return treeObj;
};

let newWaveAnimation = () => {
  let waveTL = new TimelineMax({ repeat: -1, repeatDelay: 0.3 });
  let waveObj = newAnimationObj(waveTL);
  let xDur = 2;
  let dx = 16.5;
  TweenMax.set("#waveGroup", { transformOrigin: '50% 50%' });
  waveTL.
  to("#waveGroup", 0.25, {
    rotation: -3,
    ease: Power2.easeOut }).

  to("#waveGroup", 1.5, {
    rotation: 0,
    ease: Elastic.easeOut.config(2, 0.2) }).

  to("#waveTop", xDur, {
    x: dx,
    ease: Power0.easeNone },
  "0").
  to("#waveBot", xDur, {
    x: -dx,
    ease: Power0.easeNone,
    onComplete: () => {
      if (waveObj.last == true) waveTL.pause();
    } },
  "0").invalidate();
  waveTL.pause();
  return waveObj;
};

let waveAnimation = newWaveAnimation();
let treeAnimation = newTreeAnimation();
let oilAnimation = newOilAnimation();

setTimeout(() => {
  treeAnimation.start();
  treeAnimation.stop();
}, 300);

//TweenMax.globalTimeScale(0.5);

$(document).on("mousedown touchstart", ".card", e => {
  if (e.currentTarget.classList[1] == "card--water") {
    waveAnimation.start();
  }
  if (e.currentTarget.classList[1] == "card--tree") {
    treeAnimation.start();
  }
  if (e.currentTarget.classList[1] == "card--oil") {
    oilAnimation.start();
  }
});

$(document).on("mouseleave touchend", ".card", e => {
  e.preventDefault();
  [waveAnimation, treeAnimation, oilAnimation].forEach(obj => {obj.stop();});
});

That’s all! hopefully, you have successfully created jQuery nature cards with click on icon effect. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply