-4

Right, so with my website I'm currently designing I'm using the plugin Fullpage.js. I have an animation on http://carrotcrunchpvp.comule.com/#horizontal/1 as you can see. The animation itself is done by the percentagecircles.js file and does not use CSS. Here is the animation.

This is what is in the percentagecircles.js file

var dark = document.getElementsByClassName('dark');
var svg = document.getElementsByClassName('svg')[0];
var radius = svg.getBBox().width / 2;
var t = 0.5,
  x = 0,
  y = 0;
var theta = {
  0: 0,
  1: 0,
  2: 0
};
var anims = {}
var maxTheta = calcTheta(document.getElementsByClassName('perc'));
for (i = 0; i < dark.length; i++) {
  dark[i].setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
}

function calcTheta(el) {
  var jbo = {};
  for (i = 0; i < el.length; i++) {
    jbo[i] = (180 * parseInt(el[i].innerHTML.slice(0, -1), 10)) / 50;
  }
  return jbo;
}
var animOne = setInterval(function() {
  theta[0] += 0.5;
  var x = Math.sin(theta[0] * Math.PI / 180) * radius;
  var y = Math.cos(theta[0] * Math.PI / 180) * -radius;
  var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[0] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
  dark[0].setAttribute('d', d);
  if (theta[0] > maxTheta[0]) {
    clearInterval(animOne);
  }
}, t);
var animTwo = setInterval(function() {
  theta[1] += 0.5;
  var x = Math.sin(theta[1] * Math.PI / 180) * radius;
  var y = Math.cos(theta[1] * Math.PI / 180) * -radius;
  var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[1] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
  dark[1].setAttribute('d', d);
  if (theta[1] > maxTheta[1]) {
    clearInterval(animTwo);
  }
}, t);
var animThree = setInterval(function() {
  theta[2] += 0.5;
  var x = Math.sin(theta[2] * Math.PI / 180) * radius;
  var y = Math.cos(theta[2] * Math.PI / 180) * -radius;
  var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[2] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
  dark[2].setAttribute('d', d);
  if (theta[2] > maxTheta[2]) {
    clearInterval(animThree);
  }
}, t);
<div id="container">
    
  <svg class="svg" width="33%" height="33%" viewBox="0 0 141 141" shape-rendering="geometricPrecision">
    <path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#ffb467" />
   <path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#5ab8d4" stroke-colour="#5ab8d4" />
   <path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
   <text class="perc" x="70" y="79" font-size="2em" text-anchor="middle">75%</text>
    </svg>
    
    
      <svg class="svg" width="33%" height="33%" viewBox="0 0 141 141" shape-rendering="geometricPrecision">
    <path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#ffb467" />
   <path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#5ab8d4" stroke-colour="#5ab8d4" />
   <path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
   <text class="perc" x="70" y="79" font-size="2em" text-anchor="middle">9%</text>
  </svg>
    
    <svg class="svg" width="33%" height="33%" viewBox="0 0 141 141" shape-rendering="geometricPrecision">
    <path class="light" d="M70,70 v-70 a70,70 0 0,1 0,140 a70,70 0 1,1 0,-140" fill="#ffb467" />
   <path class="dark" d="M70,70 v-70 a70,70 0 0,1 0,0" fill="#5ab8d4" stroke-colour="#5ab8d4" />
   <path d="M20,70 a50,50 0 0,1 100,0 a50,50 0 0,1 -100,0" fill="white" />
   <text class="perc" x="70" y="79" font-size="2em" text-anchor="middle">95%</text>
  </svg>
</div>

However if you navigate to my website - carroutcrunchpvp.comule.com you will see its a horizontal scrolling website. Which means all the html is all in the index.html. So this means that the above script runs when index.html loads. So you don't actually see the animation occurring because it is on another 'slide'. So I needed to find a solution which ran the animation only when I was on the 'Our Ethos' page...

Now just as an aside, for this plugin - a 'slide' is a landscape scroller and a section is a vertical scroller. For reference (code won't work):

<div class="section">
    <div class="slide"> Slide 1 </div>
    <div class="slide"> Slide 2 </div>
    <div class="slide"> Slide 3 </div>
    <div class="slide"> Slide 4 </div>
</div>

This page would be a horizontal scrolling website with 4 landscape viewports. 1 section, 4 slides = 1 vertical, 4 horizontal... Tu comprends?

As mentioned earlier, I'm using fullpage.js. To sort of fix my problem I looked through the documentation for fullpage.js (found here: https://github.com/alvarotrigo/fullPage.js/ ) and realised there were built in functions to do what I needed... Great! (https://github.com/alvarotrigo/fullPage.js#callbacks).

In my initialisation.js script for literally initialising all the fullpage plugin settings I needed/wanted, I added the relevant code at the bottom to fix my problem.

*Note - this is a section of the whole script, the whole script can be found at http://carrotcrunchpvp.comule.com/intialisation.js, yes I know I spelt initialisation wrong...

afterSlideLoad: function(anchorLink, index, slideAnchor, slideIndex){
        
        if(slideIndex == 1 ) {
            
            $.getScript("http://carrotcrunchpvp.comule.com/percentagecircles.js")
        }
            else {
                return false;
            }
        }

If confused about this, go to https://github.com/alvarotrigo/fullPage.js#afterslideload-anchorlink-index-slideanchor-slideindex for the documentation explanation.

The slide index for the 'Our Ethos' page is 1. So when I load the 'Our Ethos' page, it retrieves and runs the script located at that url. Now we're done explaining... my problem

The above solution works, sort of. If I go from the homepage to the Our Ethos page, it works great. However if I then go to another page and come back to the 'Our Ethos' page, it re-runs this script (as expected) and the formatting screws up... I can't show this in code - you will just have to go to the website and see it for yourself (I'm trying to make most of it SO based here - sorry.)

I just need a way for the script to be only run once when on the Our Ethos page, but then afterwards left alone as I don't want it running a second time. I'm not sure how I would go about that...

Any ideas are appreciated, Chris

Alvaro
  • 37,936
  • 23
  • 138
  • 304
  • Questions on StackOverflow need to be self-contained. Please edit your question and add a [MCVE](http://stackoverflow.com/help/mcve) to your question. – Sumurai8 Jan 13 '15 at 14:16
  • 2
    so we have to debug your whole website or will you provide relevant code in question?! – A. Wolff Jan 13 '15 at 14:16
  • If I must, I will - it's going to be bloody long if I describe the entirety. It seemed much easier for all of us if I just linked the website in question? – Chris Connolly Jan 13 '15 at 20:38
  • No, isolate the code relevant, and only the code relevant to the question, and put it here. – Etheryte Jan 13 '15 at 21:10
  • I've edited it. Hope you enjoy this convoluted explanation. I would rather you understand what I'm working with and then explain what Im stuck on as opposed to saying 'I need a way for a script to be only run once'... – Chris Connolly Jan 13 '15 at 21:12
  • @ChrisConnolly Why don't you just remove the `afterSlideLoad` handler once executed once. – plalx Jan 13 '15 at 21:19

1 Answers1

0

I fixed it, had to essentially do the reverse of my percentagecircles.js file. Instead of adding attributes I needed to remove them on slide leave, so when it goes back to the 'Our Ethos' slide it just re-does the animation without any problems.

Just for reference:

onSlideLeave: function(anchorLink, index, slideIndex, direction) {


  if (slideIndex == 1) {

    var dark = document.getElementsByClassName('dark');
    var svg = document.getElementsByClassName('svg')[0];
    var radius = svg.getBBox().width / 2;
    var t = 0.5,
      x = 0,
      y = 0;
    var theta = {
      0: 0,
      1: 0,
      2: 0
    };
    var anims = {}
    var maxTheta = calcTheta(document.getElementsByClassName('perc'));
    for (i = 0; i < dark.length; i++) {
      dark[i].setAttribute('transform', 'translate(' + radius + ',' + radius + ')');
    }

    function calcTheta(el) {
      var jbo = {};
      for (i = 0; i < el.length; i++) {
        jbo[i] = (180 * parseInt(el[i].innerHTML.slice(0, -1), 10)) / 50;
      }
      return jbo;
    }
    var animOne = setInterval(function() {
      theta[0] += 0.5;
      var x = Math.sin(theta[0] * Math.PI / 180) * radius;
      var y = Math.cos(theta[0] * Math.PI / 180) * -radius;
      var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[0] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
      dark[0].removeAttribute('d', d);
      if (theta[0] > maxTheta[0]) {
        clearInterval(animOne);
      }
    }, t);
    var animTwo = setInterval(function() {
      theta[1] += 0.5;
      var x = Math.sin(theta[1] * Math.PI / 180) * radius;
      var y = Math.cos(theta[1] * Math.PI / 180) * -radius;
      var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[1] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
      dark[1].removeAttribute('d', d);
      if (theta[1] > maxTheta[1]) {
        clearInterval(animTwo);
      }
    }, t);
    var animThree = setInterval(function() {
      theta[2] += 0.5;
      var x = Math.sin(theta[2] * Math.PI / 180) * radius;
      var y = Math.cos(theta[2] * Math.PI / 180) * -radius;
      var d = 'M0,0 v' + -radius + 'A' + radius + ',' + radius + ' 1 ' + ((theta[2] > 180) ? 1 : 0) + ',1 ' + x + ',' + y + 'z';
      dark[2].removeAttribute('d', d);
      if (theta[2] > maxTheta[2]) {
        clearInterval(animThree);
      }
    }, t);


  }

},