Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular + jQuery, trigger scroll when src of image changes

I am trying to use jQuery to scroll to a particular thumbnail (inside a modal) when right/left arrows have been pressed (modal should pop up when user clicks on a image). I was able to make the scroll working when user clicks on a thumbnail but I could not trigger a click when variable current2 changes. Any help would be appreciated.

I am new in Angular.js so if there are other suggestions to improve the code, it would be appreciated.

jsbin link

<body ng-app="mediaGallery" class="ng-cloak" ng-controller="mediaGalleryCtrl">

    <div class="row">
        <div class="small-8 columns">
            <div class="small-3 columns">
                <div ng-repeat="obj in array">
                    <div ng-if="$index < 4">
                        <img ng-click="changeMainMedia($index, 'current1')" class="thumbnail" ng-src="{{obj.src}}" />
                    </div>
                    <div ng-if="$index == 4">
                        <div class="thumbnail" data-open="media-gallery">
                            <label class="text-right success label">{{array.length - 3}} +</label>
                        </div>
                    </div>
                </div>

            </div>

            <div class="small-9 columns">
                <img data-open="media-gallery" class="main-gallery" ng-src="{{array[current1].src}}" />
            </div>
        </div>
    </div>



    <div ng-keydown="key($event)" id="media-gallery" class="small reveal text-center media-gallery" data-reveal>
        <div class="modal-body">
            <div class="main-media">
                <img class="main-gallery media-gallery-main" ng-src="{{array[current2].src}}" />
                <hr>

                <div class="nested-media" scroll-thumbnail>
                    <img ng-click="changeMainMedia($index, 'current2')" ng-repeat="obj in array" class="thumbnail media-gallery-thumbnail" ng-src="{{obj.src}}" />
                </div>
            </div>

            <button class="close-button" data-close aria-label="Close reveal" type="button">
           <span aria-hidden="true">x</span>
        </button>
        </div>
    </div>

    <script>
        var app = angular.module("mediaGallery", []);
        app.controller("mediaGalleryCtrl", ['$scope', function(scope) {
            var array = [{
                src: "https://placeimg.com/640/480/any"
            }, {
                src: "https://placeimg.com/640/480/tech"
            }, {
                src: "https://placeimg.com/640/480/animals"
            }, {
                src: "https://placeimg.com/640/480/nature"
            }, {
                src: "https://placeimg.com/640/480/arch"
            }, {
                src: "https://placeimg.com/640/480/people"
            }];

            scope.array = array;
            scope.current1 = 0
            scope.current2 = 0;

            scope.changeMainMedia = function(index, key) {
                scope[key] = index;
            }

            scope.key = function($event) {
                var previous = -1;
                var current = scope.current2;

                if ($event.keyCode == "39") {
                    previous = current;
                    current = (current + 1) % array.length;
                } else if ($event.keyCode == "37") {
                    previous = current;
                    current = (current - 1) % array.length;
                }
                current = current < 0 ? (array.length + current) : current;

                scope.current2 = current;
            }
        }]);

        app.directive('scrollThumbnail', function() {
            return {
                link: function(scope, elem, attrs) {
                    elem.on("click", function(event) {
                        $(this).animate({
                            scrollLeft: $(event.target).position().left
                        }, "slow");
                    });
                }
            };
        });

        $(document).foundation()
    </script>

</body>
like image 863
Node.JS Avatar asked Jan 06 '17 20:01

Node.JS


1 Answers

This is a solution which does not need jQuery. I commented the changes that I have made to your code.

<!DOCTYPE HTML>

<html>

<head>
    <title>index</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="description" />
    <meta name="author">

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/css/foundation.css" />

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.0/js/foundation.js"></script>

    <style>
        .media-gallery .media-gallery-thumbnail {
            max-height: 5em;
            display: inline-block
        }

        .media-gallery .media-gallery-main {
            height: auto;
            width: auto;
            max-height: 20em;
        }

        .media-gallery .nested-media {
            overflow-x: scroll;
            white-space: nowrap;
        }

        .media-gallery .media-gallery-main {
            max-width: 100%;
            -moz-transition: all 0.3s;
            -webkit-transition: all 0.3s;
            transition: all 0.3s;
        }

        .media-gallery .media-gallery-main:hover {
            -moz-transform: scale(1.5);
            -webkit-transform: scale(1.5);
            transform: scale(1.5);
        }

        [ng\:cloak],
        [ng-cloak],
        [data-ng-cloak],
        [x-ng-cloak],
        .ng-cloak,
        .x-ng-cloak {
            display: none !important;
        }
    </style>
</head>

<body ng-app="mediaGallery" class="ng-cloak" ng-controller="mediaGalleryCtrl">

    <div class="row">
        <div class="small-8 columns">
            <div class="small-3 columns">
                <div ng-repeat="obj in array">
                    <div ng-if="$index < 4">
                        <img ng-click="changeMainMedia($index, 'current1', $event)" class="thumbnail" ng-src="{{obj.src}}" />
                    </div>
                    <div ng-if="$index == 4">
                        <div class="thumbnail" data-open="media-gallery">
                            <label class="text-right success label">{{array.length - 3}} +</label>
                        </div>
                    </div> 
                </div>

            </div>

            <div class="small-9 columns">
                <img data-open="media-gallery" class="main-gallery" ng-src="{{array[current1].src}}" />
            </div>
        </div>
    </div>



    <div ng-keydown="key($event)" id="media-gallery" class="small reveal text-center media-gallery" data-reveal>
        <div class="modal-body">
            <div class="main-media">
                <img class="main-gallery media-gallery-main" ng-src="{{array[current2].src}}" />
                <hr>

                <div class="nested-media" scroll-thumbnail>
                    <img ng-click="changeMainMedia($index, 'current2', $event)" ng-repeat="obj in array" class="thumbnail media-gallery-thumbnail" ng-src="{{obj.src}}" />
                </div>
            </div>

            <button class="close-button" data-close aria-label="Close reveal" type="button">
           <span aria-hidden="true">x</span>
        </button>
        </div>
    </div>

    <script>
      var app = angular.module("mediaGallery", []);

      app.controller("mediaGalleryCtrl", ['$scope', function (scope) {
                  var array = [{
                          src : "https://placeimg.com/640/480/any"
                      }, {
                          src : "https://placeimg.com/640/480/tech"
                      }, {
                          src : "https://placeimg.com/640/480/animals"
                      }, {
                          src : "https://placeimg.com/640/480/nature"
                      }, {
                          src : "https://placeimg.com/640/480/arch"
                      }, {
                          src : "https://placeimg.com/640/480/people"
                      }
                  ];

                  scope.array = array;
                  scope.current1 = 0
                      scope.current2 = 0;

                  scope.changeMainMedia = function (index, key, $event) {
                      scope[key] = index;

                     // Use scroll function to scroll to element after click
                     // $event parameter is added to retrieve the node value
                     scope.scroll($event.target);
                  }

                  // Animate scrolling
                  // Midified from: http://stackoverflow.com/a/8918062/529024
                  scope.scrollTo = function (element, to, duration) {

                      if (duration <= 0)
                          return;
                      var difference = to - element.scrollLeft;
                      var perTick = difference / duration * 10;

                      setTimeout(function () {
                          element.scrollLeft = element.scrollLeft + perTick;
                          if (element.scrollLeft === to)
                              return;
                          scope.scrollTo(element, to, duration - 10);
                      }, 10);
                  }

                  // calculate scroll position and starting scroll animation
                  scope.scroll = function (element) {
                      // Get center of parent
                      var left = element.offsetLeft;

                      var scroll = left - element.parentElement.scrollLeft;

                      // Start scroll
                      scope.scrollTo(element.parentElement, scroll, 300);

                  }

                  scope.key = function ($event) {
                      var previous = -1;
                      var current = scope.current2;

                      if ($event.keyCode == "39") {
                          previous = current;
                          current = (current + 1) % array.length;
                      } else if ($event.keyCode == "37") {
                          previous = current;
                          current = (current - 1) % array.length;
                      }
                      current = current < 0 ? (array.length + current) : current;

                      scope.current2 = current;

                    // Scroll to element
                      scope.scroll(scope.getElement());
                  }

                  // get the element that is matching current2 value
                  scope.getElement = function () {
                      var parent = scope.parentElement;
                      var children = parent.children();

                      return children.eq(scope.current2)[0];
                  }

                  // This function is used by directive scrollThumbnail to set the parent element
                  // and use it to get element sibilings
                  scope.setElement = function (element) {
                      scope.parentElement = element;
                  }
              }
          ]);

      app.directive('scrollThumbnail', function () {
          return {
              scope : true,
              link : function (scope, elem, attrs) {
                // set element to scope.parentElement.
                  scope.setElement(elem);
              }
          };
      });

      $(document).foundation()
    </script>
</body>
</html>

And this a JSBin link: https://jsbin.com/ruzikilexe/1/edit?html,output

like image 132
Kalimah Avatar answered Nov 15 '22 19:11

Kalimah