Facebook / Twitter风格照片网格样式布局

时间:2016-05-02 17:28:07

标签: css angularjs facebook twitter-bootstrap grid

我正在尝试实现facebook风格的照片网格布局。我正在使用angularjs和bootstrap。我遇到过像angular-masonry这样的某些插件,我认为可以用于此。以下是我实际尝试遵循可能布局的一些快照:

enter image description here

enter image description here

enter image description here

enter image description here

知道如何实现这一目标?还有其他插件可以让生活变得轻松吗?

3 个答案:

答案 0 :(得分:7)

所有这些都是你的可能性:

  1. ngPhotoGrid

  2. Seamless Responsive Photo Grid

  3. freewall - 使用jQuery

  4. Bootstrap Responsive Image Gallery by mobirise

  5. Gamma Gallery

  6. 同时阅读 - An AngularJS directive for Masonry

    ngPhotoGrid示例:

    //ngPhotoGrid.js
    angular.module("ngPhotoGrid", [])
    angular.module("ngPhotoGrid")
      .filter("photoUrlSafe", [
        "$sce", function($sce) {
          return function(text) {
            return $sce.trustAsResourceUrl(text);
          };
        }
      ])
      .directive('endRepeat', function() {
        return {
          restrict: 'A',
          require: "^ngPhotoGrid",
          link: function(scope, element, attrs, gridController) {
            if (scope.$last) {
              gridController.notifyDOMReady(element)
            }
          }
        };
      })
      .directive("ngPhotoGrid", ["$templateCache", function($templateCache){
    
        $templateCache.put("photo_grid.html",
          "<ul class='photo-grid-wrapper' ng-style = 'parentStyle'><li class='grid-cell' ng-repeat= 'image in loadedImages track by $index' ng-style = 'image.cellStyle' ng-click='cellClicked(image)' end-repeat='' ng-attr-data-src='{{image[defaultOptions.urlKey] | photoUrlSafe}}'><img class='grid-cell-image' ng-style = 'image.imageStyle' ng-src='{{image[defaultOptions.urlKey]}}' alt='#'/></li></ul>");
    
        function linker(scope, element, attrs) {
          scope.loadedImages      = [];
          scope.loadedTakenImages = [];
          scope.takenImages       = [];
    
          // ###OPTIONS
          scope.defaultOptions =  {
                                    urlKey          :     "original_url",
                                    sortByKey       :     "nth",
                                    onClicked       :     function() {},
                                    onBuilded       :     function() {},
                                    onDOMReady      :     function() {},
                                    margin          :     2,
                                    maxLength       :     5,
                                    isSquare        :     false,
                                    buildOnLoading  :     true
                                  }
    
          angular.extend(scope.defaultOptions, scope.gridOptions);
    
          var IS_SQUARE    = scope.defaultOptions.isSquare;
          var GRID_WIDTH   = element.prop('offsetWidth');
          var MARGIN       = scope.defaultOptions.margin;
    
          if (!GRID_WIDTH) { // set the default width of parent
            GRID_WIDTH = 250
          }
    
          scope.parentStyle = { width: GRID_WIDTH + "px", overflow: "hidden", position: "relative", margin: 0, padding: 0 }
    
          if(IS_SQUARE) {
            scope.parentStyle.height = GRID_WIDTH + "px";
          }
    
          var commonStyle = {
                          display:        'block',
                          overflow:       'hidden',
                          cssFloat:       'left',
                          cursor:         'pointer',
                          position:       'relative'
                        };
    
          //callback handler
          scope.cellClicked = function(image) {
            scope.defaultOptions.onClicked(image);
          }
    
          /**
          * choose images from the url source to build grid
          * take maximum 7 images for best looking
          *------------------------------------------------*/
          scope.chooseImages = function(images) {
            angular.forEach(images, function(image, index) {
              var randNumber; //set the id and nth value for image if does not have
              randNumber                = randomNumber();
              image.id                  = image.id || randNumber;
              image[scope.defaultOptions.sortByKey]  = image[scope.defaultOptions.sortByKey] || randNumber;
            });
    
            var sortedImages = images.sort(function(a, b) {
              return a[scope.defaultOptions.sortByKey] - b[scope.defaultOptions.sortByKey]
            })
    
            return sortedImages.slice(0, scope.defaultOptions.maxLength)
          }
    
          randomNumber = function(max) {
            max = max || 999;
            return Math.floor(Math.random()*max);
          }
    
          scope.preloadImages = function(images) {
            scope.takenImages = scope.chooseImages(images)
    
            angular.forEach(scope.takenImages, function(image, index) {
              var img;
              img                     = new Image();
              img.id                  = image.id ;
              img[scope.defaultOptions.sortByKey]  = image[scope.defaultOptions.sortByKey];
    
              img.onload              = function(loadedImage) {
                scope.loadedTakenImages.push(loadedImage);
    
                // store the original dimesion of image
                image.naturalWidth    = loadedImage.target.naturalWidth
                image.naturalHeight   = loadedImage.target.naturalHeight
    
                // build the grid immediatly after the image was loaded
                // building while images loading
                if(scope.defaultOptions.buildOnLoading) {
                  scope.buildPhotoGrid();
                  setTimeout(function() {
                    scope.$apply()
                  }, 10)
                }
                
                if(scope.loadedTakenImages.length == scope.takenImages.length) {   
                  //trigger build completed handler
                  scope.defaultOptions.onBuilded(element)
       
                  //grid also can be build after all image loaded
                  //all image would be shown correctly, loading time cause poor UX
                  if(!scope.defaultOptions.buildOnLoading) {
                    scope.buildPhotoGrid()
                    setTimeout(function() {
                      scope.$apply()
                    }, 15)
                  }
                }
                
              };
              img.src = image[scope.defaultOptions.urlKey];
            });
          };
    
          scope.buildPhotoGrid = function() {
            var firstImage, imageStyle, smallCellHeight,
            smallCellWidth, bigCellWidth, bigCellHeight, cellCount, is2First;
    
            // get cell style & builded options
            styles          = scope.getCellStyles();
            smallCellHeight = styles.options.smallCellHeight;
            smallCellWidth  = styles.options.smallCellWidth;
            bigCellWidth    = styles.options.bigCellWidth;
            bigCellHeight   = styles.options.bigCellHeight;
            cellCount       = styles.options.cellCount;
            is2First        = styles.options.is2First;
    
            scope.loadedImages = []
            angular.forEach(scope.takenImages, function(image, index) {
              if (is2First) { //case the grid has 2 image big first
                var bigCellStyle, smallCellStyle;
                bigCellStyle          = angular.copy(styles.big);
                smallCellStyle        = angular.copy(styles.small);
                if (index == 0) {
                  bigCellStyle.top    = "0";
                  image.cellStyle     = bigCellStyle;
                  image.imageStyle = getImageStyle(bigCellWidth, bigCellHeight, image);
                } else if (index  == 1) {
                  bigCellStyle.top    = bigCellHeight + MARGIN + "px";
                  image.cellStyle     = bigCellStyle;
                  image.imageStyle = getImageStyle(bigCellWidth, bigCellHeight, image);
                } else {
                  var margin, smallCellIndex;
    
                  // fix the last cell of 2 first was not fit the grid height
                  if(index == scope.takenImages.length - 1) {
                    smallCellStyle.height = smallCellHeight + MARGIN + "px"
                  }
    
                  smallCellIndex      = index - 2;
                  margin              = smallCellIndex == 0 ? 0 : MARGIN;
                  smallCellStyle.top  = smallCellIndex * smallCellHeight + (margin * smallCellIndex) + "px";
                  image.cellStyle     = smallCellStyle;
                  image.imageStyle    = getImageStyle(smallCellWidth, smallCellHeight, image);
    
    
                }
              } else if (index == 0) { //big cell style
                image.cellStyle = styles.big;
                image.imageStyle = getImageStyle(bigCellWidth, bigCellHeight, image);
              } else if (index != cellCount - 1 || cellCount == 2){ //small cells
                image.cellStyle = styles.small;
                image.imageStyle = getImageStyle(smallCellWidth, smallCellHeight, image);
              } else { //last small cell style (remove redundant margin right or bottom)
                image.imageStyle = getImageStyle(smallCellWidth, smallCellHeight, image);
                image.cellStyle = styles.last;
              }
            })
            scope.loadedImages = scope.takenImages;
          }
    
          function getImageStyle(cellWidth, cellHeight, image) {
            var imageWidth, imageHeight, curImageWidth, curImageHeight, imgRatio, cellRatio;
    
            cellWidth  = Math.round(cellWidth);
            cellHeight = Math.round(cellHeight);
            imageWidth  = image.naturalWidth;
            imageHeight = image.naturalHeight;
            imgRatio  = imageWidth / imageHeight;
            cellRatio = cellWidth / cellHeight;
    
            // when the any image's dimension greater than cell's dimension
            if(cellWidth > imageWidth || cellHeight > imageHeight) {
              if (cellWidth >= imageWidth) {
                return getSmallImagePortraitStyle(cellHeight, cellWidth, imgRatio);
              } else {
                return getSmallImageLandscapeStyle(cellHeight, cellWidth, imgRatio);
              }
            } else { // when the image smaller than the cell in both dimension
              if(imgRatio >= 1) {
                return getSmallImageLandscapeStyle(cellHeight, cellWidth, imgRatio);
              } else {
                return getSmallImagePortraitStyle(cellHeight, cellWidth, imgRatio);
              }
            }
          }
    
          function getSmallImageLandscapeStyle(cellHeight, cellWidth, imgRatio) {
            var curImageWidth = cellWidth;
            var curImageHeight = Math.round(curImageWidth  / imgRatio);
            if(curImageHeight >= cellHeight) {
              var top = (-1) * Math.round((cellWidth / imgRatio - cellHeight) / 2);
              if(curImageWidth < cellWidth) {
                return { width: "100%", position: "relative", top: top + "px"}
              } else {
                return { maxWidth: "100%", position: "relative", top: top + "px"}
              }
            } else {
              var left = (-1) * Math.round((cellHeight * imgRatio - cellWidth) / 2);
              return { maxHeight: "100%", height: "100%", position: "relative", left: left + "px"}
            }
          }
              
          function getSmallImagePortraitStyle(cellHeight, cellWidth, imgRatio) {
            var curImageHeight = cellHeight;
            var curImageWidth = Math.round(curImageHeight  * imgRatio);
            var top = (-1) * Math.round((cellWidth / imgRatio - cellHeight) / 2);
            var left = (-1) * Math.round((cellHeight * imgRatio - cellWidth) / 2);
            if(curImageWidth <= cellWidth) {
              return { width: "100%", position: "relative", top: top + "px"}
            } else {
              return { maxHeight: "100%", height: "100%", position: "relative", left: left + "px"} 
            }
          }
    
          /**
          * build cell style for grid
          * @firstRatio   : ratio of the first image in list
          * @secondRatio  : ratio of the second image in list
          * @cellCount    : total cells in grid
          *------------------------------------------------*/
          buildCellStyle      = function (firstImage, secondImage, cellCount) {
            var firstRatio, secondRatio, bigCellStyle, smallCellStyle, lastCellStyle,
                WIDTH_RATE, bigCellWidth, bigCellHeight, smallCellHeight, smallCellWidth, is2First, 
                case2BigImage1, case2BigImage2;
    
            firstRatio              = firstImage.naturalWidth / firstImage.naturalHeight;
    
            if (secondImage)
              secondRatio           = secondImage.naturalWidth / secondImage.naturalHeight;
            else
              secondRatio           = 1.5 //fail all cases below
    
            bigCellStyle            = angular.copy(commonStyle);
            smallCellStyle          = angular.copy(commonStyle);
            lastCellStyle           = angular.copy(commonStyle);
            WIDTH_RATE              = getWidthRate(firstRatio, cellCount);
            case2BigImage1          = firstRatio  > 0.8 && firstRatio  < 1.2 &&
                                      secondRatio > 0.8 && secondRatio < 1.2
            case2BigImage2          = firstRatio >= 2 && secondRatio >= 2
    
            if(cellCount == 2) { //build style for grid has 2 images and first image has firstRatio > 1
    
              if(firstRatio >= 1) {
                bigCellStyle.marginBottom = MARGIN;
                bigCellStyle.width    = GRID_WIDTH;
                bigCellStyle.height   = GRID_WIDTH / 2;
                smallCellStyle.width  = GRID_WIDTH;
                smallCellStyle.height = GRID_WIDTH / 2 - MARGIN;
              } else {
                var marginSize              = MARGIN / cellCount;
                bigCellStyle.marginRight    = marginSize;
                smallCellStyle.marginLeft   = marginSize;
    
                if(IS_SQUARE) {
                  bigCellWidth          = Math.floor(GRID_WIDTH / 2) - MARGIN;
                  bigCellStyle.width    = bigCellWidth;
                  bigCellStyle.height   = GRID_WIDTH;
    
                  smallCellWidth        = Math.floor(GRID_WIDTH / 2) - MARGIN;
                  smallCellStyle.width  = smallCellWidth;
                  smallCellStyle.height = GRID_WIDTH;
                } else {
                  bigCellWidth          = Math.floor(GRID_WIDTH * WIDTH_RATE) - MARGIN;
                  bigCellStyle.width    = bigCellWidth;
                  bigCellStyle.height   = bigCellWidth;
    
                  smallCellWidth        = GRID_WIDTH - bigCellWidth - MARGIN;
                  smallCellHeight       = bigCellWidth;
                  smallCellStyle.width  = smallCellWidth;
                  smallCellStyle.height = smallCellHeight;
                }
              }
            }
    
            // add style for first column contain 2 big images, only support for grid has more than 5 cells
            //NOTE: need check when 2 first were same size!!!
            else if (cellCount >= 5 && (case2BigImage1 || case2BigImage2)) {
              var GRID_HEIGHT;
              WIDTH_RATE            = case2BigImage1 ? 1/2 : 2/3;
              scope.parentStyle.position = "relative";
              bigCellStyle.cssFloat = smallCellStyle.cssFloat = lastCellStyle.cssFloat = null;
              bigCellStyle.position = smallCellStyle.position = lastCellStyle.position = "absolute";
    
              //determine the height of the big cell
              //height == width / 2 if the grid in case2BigImage1
              if(case2BigImage1) {
                bigCellHeight = GRID_WIDTH / 2;
              } else {
                bigCellHeight  = WIDTH_RATE * GRID_WIDTH / firstRatio;
              }
    
              GRID_HEIGHT               = bigCellHeight * 2 + MARGIN; //margin bottom the first big image
              scope.parentStyle.height  = GRID_HEIGHT + "px";
    
              bigCellStyle.width        = GRID_WIDTH * WIDTH_RATE - MARGIN;
              bigCellStyle.height       = bigCellHeight;
              bigCellStyle.left         = 0;
    
              smallCellStyle.width      = GRID_WIDTH - bigCellStyle.width - MARGIN;
              smallCellStyle.height     = Math.floor((GRID_HEIGHT / (cellCount - 2))) - MARGIN;
              smallCellStyle.right      = 0;
    
              is2First                  = true; //flag this style is has 2 big image style
              lastCellStyle.height      = smallCellStyle.height + MARGIN;
    
            } else if(firstRatio >= 1) { //build style for grid more than 2 images and first image has firstRatio > 1
    
              bigCellStyle.marginBottom  = MARGIN;
              smallCellStyle.marginRight = MARGIN;
              var smallCellCount         = cellCount - 1;
              
              if (IS_SQUARE) {
                bigCellStyle.height   = GRID_WIDTH * 2 / 3;
                bigCellStyle.width    = GRID_WIDTH;
                smallCellStyle.height = GRID_WIDTH * 1 / 3 - MARGIN;
              } else {
                bigCellStyle.width    = GRID_WIDTH ;
                bigCellStyle.height   = GRID_WIDTH * 2 / 3;
              }
              smallCellStyle.width  = ( GRID_WIDTH - smallCellCount * MARGIN ) / smallCellCount;
              // determine the height of smallCell below
              if (IS_SQUARE) {
                smallCellStyle.height = GRID_WIDTH - bigCellStyle.height - MARGIN;
              } else if (firstRatio > 1.3 && firstRatio < 1.5) { // 4:3 < firstRatio < 5:3
                smallCellStyle.height     = smallCellStyle.width / firstRatio;
              } else if (firstRatio > 1.5) {
                smallCellStyle.height     = smallCellStyle.width / 1.5;
              } else {
                smallCellStyle.height     = smallCellStyle.width;
              }
              lastCellStyle.height = smallCellStyle.height;
              lastCellStyle.width  = smallCellStyle.width;
            } else { //build style for grid more than 2 images and first image has firstRatio <= 1
              bigCellStyle.marginRight       = MARGIN;
              smallCellStyle.marginBottom    = MARGIN;
    
              if (IS_SQUARE) {
                bigCellHeight   = GRID_WIDTH;
                bigCellWidth    = GRID_WIDTH * WIDTH_RATE;
              } else {
                bigCellWidth    = Math.floor(GRID_WIDTH * WIDTH_RATE);
                bigCellHeight   = bigCellWidth / firstRatio;
              }
    
              bigCellStyle.width    = bigCellWidth;
              bigCellStyle.height   = bigCellHeight;
    
              smallCellCount        = cellCount - 1;
              smallCellWidth        = GRID_WIDTH - bigCellWidth - MARGIN;
              smallCellHeight       = bigCellHeight / smallCellCount - MARGIN
    
              smallCellStyle.width  = GRID_WIDTH - bigCellWidth - MARGIN;
              smallCellStyle.height = smallCellHeight;
              lastCellStyle.width   = smallCellWidth;
              lastCellStyle.height  = smallCellHeight;
            }
    
            return {
              big:    bigCellStyle,
              small:  smallCellStyle,
              last:   lastCellStyle,
              options:  {
                firstRatio:       firstRatio,
                // keep these value because ng style need add measured suffix
                smallCellWidth:   smallCellStyle.width,
                smallCellHeight:  smallCellStyle.height,
                bigCellWidth:     bigCellStyle.width,
                bigCellHeight:    bigCellStyle.height,
                cellCount:        cellCount,
                is2First:         is2First
              } //keep these values to style cell image after building style for cell link
            }
          }
    
          getWidthRate = function(firstRatio, cellCount) {
            if (cellCount == 2) { //build style for 2 images
              if(firstRatio > 1) {
                return 2/3;
              } else {
                return 1/2;
              }
            } else if(firstRatio > 1) { //build style for >= 3 images, first image has firstRatio > 1
              return 1
            } else { //build style for >= 3 images, first image has firstRatio < 1
              return 2/3
            }
          }
    
          scope.getCellStyles     = function() {
            var firstImage, secondImage, cellCount, buildedStyle;
    
            firstImage            = scope.takenImages[0];
            secondImage           = scope.takenImages[1];
            cellCount             = scope.takenImages.length;
    
            if (cellCount == 1) { //build style for only one image
              //@todo need implement!
            } else { //build style for >=2 images
              buildedStyle        = buildCellStyle(firstImage, secondImage, cellCount);
            }
    
            // remove margin right of last small cell in the bottom
            if(buildedStyle.small.marginRight) {
              buildedStyle.last.marginRight     = 0;
              buildedStyle.last.width           = buildedStyle.small.width + MARGIN;
            }
    
            // remove margin bottom of last small cell in the right
            if(buildedStyle.small.marginBottom) {
              buildedStyle.last.marginBottom    = 0;
              buildedStyle.last.height          = buildedStyle.small.height + MARGIN;
            }
    
            // add suffix px for margin and size for ng-style working
            var attrs = ["width", "height", "marginRight", "marginLeft", "marginBottom", "left", "right"];
            angular.forEach(attrs, function(attr, index) {
              if(buildedStyle.big[attr]) {
                buildedStyle.big[attr]   += "px";
              }
              if(buildedStyle.small[attr]) {
                buildedStyle.small[attr] += "px";
              }
              if(buildedStyle.last[attr]) {
                buildedStyle.last[attr]  += "px";
              }
            })
    
            return buildedStyle;
          }
    
          //trigger build grid
          scope.$watch("images", function(images) {
            if(images && images.length > 0) {
              scope.preloadImages(images);
            }
          })
        }
    
        return {
          restrict:       "A",
          templateUrl:    "photo_grid.html",
          scope: {
            images:       "=",
            gridOptions:  "="
          },
          controller: ["$scope", "$element", function($scope, $element) {
            this.notifyDOMReady = function() {
              $scope.defaultOptions.onDOMReady($element)
            }
          }],
          link: linker
        }
    
      }])
    
    
    
    
    
    angular.module("ngApp", ["ngPhotoGrid"])
    angular.module("ngApp").controller("indexCtrl", ["$scope", function($scope){
    
      //show loading mark while grid is building
      $scope.isBuildingGrid = true;
    
      // production test
      img1 = {original_url: "http://lorempixel.com/1366/768"};
      img2 = {original_url: "http://lorempixel.com/316/316"};
      img3 = {original_url: "http://lorempixel.com/400/200"};
      img4 = {original_url: "http://lorempixel.com/600/1000"};
      img5 = {original_url: "http://lorempixel.com/600/800"};
      img6 = {original_url: "http://lorempixel.com/800/600"};
      img7 = {original_url: "http://lorempixel.com/800/800"};
      img8 = {original_url: "http://lorempixel.com/900/1000"};
    
      // // local dev
      // img1 = {original_url: "images/1366x768.jpg"};
      // img2 = {original_url: "images/316x316.jpg"};
      // img3 = {original_url: "images/600x1000.jpg"};
      // img4 = {original_url: "images/900x1000.jpg"};
      // img5 = {original_url: "images/600x800.jpg"};
      // img6 = {original_url: "images/800x600.jpg"};
      // img7 = {original_url: "images/800x800.jpg"};
      // img8 = {original_url: "images/900x1000.jpg"};
    
      var sources             = [img1, img2, img3, img4, img5, img6, img7, img8]
    
      var sources2big            = [{original_url: "http://lorempixel.com/316/316", nth: 1}, {original_url: "http://lorempixel.com/800/800", nth: 2}, img3, img4, img5, img6]
    
      $scope.rand             = function(min, max) {
        return Math.floor(Math.random() * (max - min)) + min;
      }
    
      $scope.clickHandler     = function(image) {
        alert(JSON.stringify(image))
      }
    
      $scope.buildCompletedHandler = function() {
        console.log ("built completed!")
        $scope.isBuildingGrid = false;
        
      }
    
      getSelectedSeeds = function() {
        var photoNumbers      = $scope.rand(2, 7)
        var seeds             = []
        var arr               = []
        while(arr.length < photoNumbers){
          var randomnumber    = $scope.rand(1, 8);
          var found           = false;
          for(var i = 0; i < arr.length; i++){
            if(arr[i] == randomnumber ){
              found           = true;
              break;
            }
          }
          if(!found) {
            arr[arr.length]   = randomnumber;
            seeds.push(sources[randomnumber])
          }
        }
        return seeds;
      }
    
      $scope.images              = getSelectedSeeds();
    
      $scope.images2big          = sources2big.slice(0, 7);
    
      /**
       * Options definitions
       *----------------------*/
      $scope.gridOptions = {
        urlKey      :     "original_url",
        sortKey     :     "nth",
        onClicked   :     function(image) {
                            alert(JSON.stringify(image))
                          },
        onBuilded   :     function() {
                            console.log ("built completed!")
                            $scope.isBuildingGrid = false;
                            
                          },
        margin      :     2,
        maxLength   :     5
      }
    
      /**
       * Options definitions for square example
       *----------------------------------------*/
      $scope.gridOptionsSquare = {
        urlKey      :     "original_url",
        sortKey     :     "nth",
        onClicked   :     function(image) {
                            alert(JSON.stringify(image))
                          },
        onBuilded   :     function() {
                            console.log ("built completed!")
                            $scope.isBuildingGrid = false;
                            
                          },
        margin      :     2,
        isSquare    :     true,
        maxLength   :     4
      }
        
      $scope.squareGridGroup = [];
    
      angular.forEach([1,2,3,4,5,6], function() {
        $scope.squareGridGroup.push(angular.copy(getSelectedSeeds()))
      })
    
    
    }])
    /**
    * All these styles are not a part of angular module.
    */
    .center {
      text-align: center;
    }
    .small {
      font-size:12px;
      font-weight: normal;
      margin-left: 10px;
    }
    
    .wrapper {
      text-align: center;
    }
    .content {
      width: 400px;
      margin: 0 auto;
    }
    .feed-item{
      overflow: hidden;
    }
    
    .feed-photos {
      position: relative;
      min-height: 100px;
    }
    
    .feed-photos.loading::after {
      content: "";
      height: 100%;
      width: 100%;
      background: rgba(0,0,0,.6) url("loader.gif") center center no-repeat;
      left:0;
      top:0;
      position: absolute;
    
    }
    .feed-photos.loading .grid-cell-image{
      width: 100%;
    }
    
    /**
    * It's the part of module
    * used to style the border of grid
    * included this style if you want to border the grid cell
    */
    .grid-cell:after {  
      content: '';
      position: absolute;
      border: 1px solid rgba(0, 0, 0, 0.2); /*change this color if you want*/
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
        <style>
          body { text-align: center; }
          .links a { padding: 0 5px ;}
          .active { color: red;}
        </style>
      </head>
      <body ng-app='ngApp'>
        <div class='wrapper' ng-controller="indexCtrl">
          <div class="header">
            <h1>ngPhotoGrid Example - 2 bigs first</h1>
          </div>
          <div class='content'>
            <div class="feed-item">
              <div  ng-photo-grid =   ""
                    images        =   "images2big"
                    grid-options  =   "gridOptions"
                    ng-class      =   "{'loading': isBuildingGrid}"
                    class         =   "feed-photos">
              </div>
            </div>
            <p class='small'><i>click on image or turn on firebug to see the callback.</i></p>
          </div>
    
          <div class='footer'>
            <p><a href="https://github.com/jerryc-nguyen/ng-photo-grid" target="_blank">source on github</a></p>
          </div>
        </div>

答案 1 :(得分:2)

您是否尝试过 ngPhotoGrid https://github.com/jerryc-nguyen/ng-photo-grid

  

简单的紧凑型照片网格,如AngularJS中的Facebook,没有依赖关系。

Examples查看它看起来就像你要找的那样。

答案 2 :(得分:2)

使用纯css有一种更简单的方法:ng-messagescolumn-count

这是一个小提琴(https://jsfiddle.net/3z73obt0/1/

以下是代码:

&#13;
&#13;
column-width
&#13;
#wrapper {
  -moz-column-count: 2;
  -webkit-column-count: 2;
  column-count: 2;
  -moz-column-gap: 10px;
  -webkit-column-gap: 10px;
  column-gap: 10px;
}
#wrapper > div:nth-child(n+2) {
  margin-top:10px;
}
#wrapper > div:nth-child(1) {
  height: 150px;
  width:100%;
  background-color:#8ebce5;
}
#wrapper > div:nth-child(2) {
  height: 150px;
  width:100%;
  background-color:#3a2313;
}
#wrapper > div:nth-child(3) {
  height: 100px;
  width:100%;
  background-color:peru;
}
#wrapper > div:nth-child(4) {
  height: 100px;
  width:100%;
  background-color:#BB3579;
}
#wrapper > div:nth-child(5) {
  height: 100px;
  width:100%;
  background-color:#EAC243;
}
&#13;
&#13;
&#13;

如果您仍然喜欢使用库,我建议您查看同位素库来实现这一目标。 (http://isotope.metafizzy.co/)。

这是一个使用同位素制作的漂亮砖石布局的编码:http://codepen.io/desandro/pen/mIkhq