Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Service for programmatic use #13

Open
JumpLink opened this issue Mar 28, 2014 · 5 comments
Open

Add Service for programmatic use #13

JumpLink opened this issue Mar 28, 2014 · 5 comments

Comments

@JumpLink
Copy link

I've create a Service of your directive in my project to use the scroll functionality in my Controllers.

My changes:

  • Split the smoothScroll function to smoothScrollPosition and smoothScroll for the possibility to scroll directly to a position, useful for a "Back to top" button/link.
  • Added new parameter to activate / deactivate the smoth animation
  • new function called autoPosition to replace angular's $anchorScroll with your angular-smoothscroll.
jumplink.cms.service("WindowService", function(RowService, $rootScope, $window, $timeout, $location, $log) {

  var tigger = function (event) {
    $timeout(function() {
      // anything you want can go here and will safely be run on the next digest.
      angular.element($window).triggerHandler(event);
    })
  }

  /*
   * Retrieve the current vertical position
   * @returns Current vertical position
   */
  var currentYPosition = function() {
    if ($window.pageYOffset) {
      return $window.pageYOffset;
    }
    if ($window.document.documentElement && $window.document.documentElement.scrollTop) {
      return $window.document.documentElement.scrollTop;
    }
    if ($window.document.body.scrollTop) {
      return $window.document.body.scrollTop;
    }
    return 0;
  };

  /*
   * Get the vertical position of a DOM element
   * @param eID The DOM element id
   * @returns The vertical position of element with id eID
   */
  var elmYPosition = function(eID) {
    var elm, node, y;
    elm = document.getElementById(eID);
    if (elm) {
      y = elm.offsetTop;
      node = elm;
      while (node.offsetParent && node.offsetParent !== document.body) {
        node = node.offsetParent;
        y += node.offsetTop;
      }
      return y;
    }
    return 0;
  };

  // FORK of https://github.com/arnaudbreton/angular-smoothscroll
  var smoothScrollPosition = function(stopY, animation) {
    if(!animation) {
      $window.scrollTo(0,stopY);
    }

    var distance, i, leapY, speed, startY, step, stopY, timer, _results;
    startY = currentYPosition();
    distance = (stopY > startY ? stopY - startY : startY - stopY);
    if (distance < 100) {
      scrollTo(0, stopY);
      return;
    }
    speed = Math.round(distance / 100);
    if (speed >= 20) {
      speed = 20;
    }
    step = Math.round(distance / 25);
    leapY = (stopY > startY ? startY + step : startY - step);
    timer = 0;
    if (stopY > startY) {
      i = startY;
      while (i < stopY) {
        setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed);
        leapY += step;
        if (leapY > stopY) {
          leapY = stopY;
        }
        timer++;
        i += step;
      }
      return;
    }
    i = startY;
    _results = [];
    while (i > stopY) {
      setTimeout('window.scrollTo(0, ' + leapY + ')', timer * speed);
      leapY -= step;
      if (leapY < stopY) {
        leapY = stopY;
      }
      timer++;
      _results.push(i -= step);
    }
    return _results;
  };

  var smoothScroll = function(eID, offSet, animation) {
    var stopY = elmYPosition(eID) - offSet;
    return smoothScrollPosition (stopY, animation);
  }

  var autoPosition = function () {
    var hash = $location.hash();
    if(angular.isDefined(hash) && hash !== '') {
      console.log(hash);
      smoothScroll(hash, 60, true);
    } else {
      smoothScrollPosition(0, false);
    }

  }


  return {
    tigger: tigger
    , smoothScrollPosition: smoothScrollPosition
    , smoothScroll: smoothScroll
    , autoPosition: autoPosition
  }

});

Source: https://github.com/JumpLink/cms/blob/0f95a035bc7bed117393b1685b1fdab3f2aee35d/src/assets/general/js/angular/services.js#L721

If you want to use the autoPosition function you need to inject an empty $anchorScroll that does nothing, so you can use angularSmoothscroll for thinks like that.

angular.module("services",[]).value('$anchorScroll', angular.noop).

Source: https://github.com/JumpLink/cms/blob/0f95a035bc7bed117393b1685b1fdab3f2aee35d/src/assets/general/js/angular/config.js#L29

Example for autoPosition:

  angular.element($window).bind('resize', function () {
    $log.debug('resize tiggered');
    WindowService.autoPosition();
  });

Source: https://github.com/JumpLink/cms/blob/0f95a035bc7bed117393b1685b1fdab3f2aee35d/src/assets/general/js/angular/controllers.js#L100

Do you interested to merge my changes? I would need to rewrite this stuff in CoffeeScript (I have no experience with CoffeeScript yet) and would make it compatible with your directive.

@arnaudbreton
Copy link
Owner

Awesome, thanks for sharing your contribution. Do you think you could make a PR from it, to add your service in the module ?

@JumpLink
Copy link
Author

:) yes, I think I can do that in the next days.

@arnaudbreton
Copy link
Owner

Awesome, happy to review it!

What is your exact use-case to use this feature directly in a controller ?

@JumpLink
Copy link
Author

I use it for a smoth "scroll back to top" (scroll to position 0 not to an element) button and my app scrolls automatically to the element when the corresponding hash of the element-id is setted in the url. In addition, I scroll smoothly back to the element when the page size changes because this can also change the the position of the elements.

@JumpLink
Copy link
Author

I've created a video that shows for what I need it exactly: https://drive.google.com/file/d/0B5r20MKWjT9YN1JXVE1sWDByY0E
I hope I can show you a real usable demo soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants