html lang="ja" 
  head
    meta charset="UTF-8" /
    meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=4.0"
    title 画像分割配置
  body ng-app="materializeApp" ng-controller="BodyController"
    
    section.fixed
      .row.fileSelectForm.whiteSpace
        form action="#"
          .file-field.input-field
            .btn#getfileBtn.waves-effect.waves-teal.white-text.blue.darken-3
              span.fa.fa-fw.fa-camera-retro
              |  
              span File
              input#getfile multiple="" type="file" accept="image/*"
            .file-path-wrapper
              input#getfile-path.file-path.validate placeholder="ファイルを選択" type="text"


      .row.whiteSpace
        .col.s12
          select class="browser-default" ng-model="selectedColumn" 
            option ng-repeat="value in select"
              | {{value.label}}
        
      .row#preloader.center.hide
        .preloader-wrapper.big.active
          .spinner-layer.spinner-blue
            .circle-clipper.left
              .circle
            .gap-patch
              .circle
            .circle-clipper.right
              .circle
          .spinner-layer.spinner-red
            .circle-clipper.left
              .circle
            .gap-patch
              .circle
            .circle-clipper.right
              .circle
          .spinner-layer.spinner-yellow
            .circle-clipper.left
              .circle
            .gap-patch
              .circle
            .circle-clipper.right
              .circle
          .spinner-layer.spinner-green
            .circle-clipper.left
              .circle
            .gap-patch
              .circle
            .circle-clipper.right
              .circle

      .row.whiteSpace.center
            
        .col.s12
          a#trash.waves-effect.waves-light.btn.btn-large.red.disabled ng-click="deleteAction();"
            span.fa.fa-2x.fa-fw.fa-trash
            |  
            | clear
            
          
      
      .row#genImgWrapper.whiteSpace.hide
        h2.header generated image
        .col.s12
          img#genImg.responsive-img src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        
    #absoluteContainer.hide
      .row#imgWrapper.masonry-grid
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview0 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview1 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview2 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview3 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview4 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview5 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview6 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
        .col.masonry-grid-item ng-class="getGrid(gridNum)"
          img.responsive-img.imgBox#preview7 src="https://placehold.jp/ffffff/ffffff/100x1.png" /
View Compiled
.row .col{
  margin:0;
  padding:0;
  line-height:0;
}
img{
  width:100%;
  height:auto;
}
.whiteSpace{
  margin:5%;
}

.header{
    color: #ee6e73;
    font-weight: 300;
    font-size: 1.56rem;
    line-height: 110%;
    margin: 1.78rem 0 1.424rem 0;
}
#absoluteContainer{
  position:absolute;
  left:0;
  top:3000px;
}
#imgWrapper{
    width:2000px;
    background-color: #FFF;
}
var app = angular.module('materializeApp', ['ui.materialize'])
    .controller('BodyController', ["$scope", function ($scope) {
    	
    	$scope.gridNum = 6;
    	$scope.select = [
			{"label":"カラム数 : 2列", "col":2},
			{"label":"カラム数 : 3列", "col":3},
			{"label":"カラム数 : 4列", "col":4},
			{"label":"カラム数 : 6列", "col":6}
    	];
    	$scope.selectedColumn = $scope.select[0].label;
    	$scope.getCol = function(){
		    return  $scope.selectedColumn;
		}
    	$scope.$watch("getCol()", function(newValue, oldValue){
    		for(var i=0; i<$scope.select.length; i++){
    			if(newValue.indexOf($scope.select[i].label) != -1 )$scope.gridNum = 12 / $scope.select[i].col;
    		}
		});
		
		$scope.getGrid = function(gridNo) {
		    return 's'+gridNo;
		};
		
    	
	    var setFileCount  	= 0;
		var reader;
		var imgBoxLength  	= getImgBoxLength();
		var inputFileElm  	= document.querySelector('#getfile');
		var blankPNG		= "https://placehold.jp/ffffff/ffffff/100x1.png";
		var masonryOption = {
		  	itemSelector: '.masonry-grid-item',
	        isResizable: true,
	        isAnimated: false,
	        transitionDuration: 0,
	        isFitWidth: true,
	        isRTL: false,
	        gutter: 0 ,
	        containerStyle: { position: 'relative' }
		};
    	
    	function setOnChangeEvent(){
			$("#getfile").on('change',function (){
				var fileArray = [];
				for(var i=0; i< this.files.length; i++){
					fileArray.push( this.files[i]);
				}
				checkFileLsit(fileArray);
			});
		}
		setOnChangeEvent();
		
		
		function checkFileLsit( inFileList ){
			if(inFileList && inFileList.length == 0){
				
				$(".fileSelectForm").attr("style","width:"+$(".fixed").innerWidth()+"px;");
				$("#absoluteContainer").removeClass('hide');
				$("#genImgWrapper").attr("style","display:none;");
				
				//整列
				setTimeout(function(){
					$('.masonry-grid').masonry(masonryOption);
				},1000);
				
				setTimeout(function(){
					createImg();
				},2000);
			}
			if(!inFileList || inFileList.length <= 0)return;
			setImgBox( inFileList );
		}

		
    	
    	function setImgBox( inFileList ){
			var file = inFileList.shift()
			reader = new FileReader(file);
			reader.readAsDataURL( file );
			reader.onload = function  () {
				
				
				if(setFileCount < imgBoxLength){
					
					//Exifを取得して回転を補正する
					EXIF.getData(file, function(){
				        var orientation = file.exifdata.Orientation;
				        var mpImg = new MegaPixImage(file);
				        mpImg.render( $('#preview'+setFileCount)[0] , { orientation: orientation });
				        
				  		setFileCount++;
				  		if(setFileCount >= imgBoxLength){
				  			disabledInputForm();
				  		}
				  		
				  		$("#preloader").removeClass('hide');
						$("#trash").removeClass('disabled');
						$("#genImg").attr("src",blankPNG);
						$("#genImgWrapper").addClass('hide');
				        
				    });
					
					// シンプルにurlを挿入する
					// $('#preview'+setFileCount).attr("src",reader.result);
					// setFileCount++;
					// if(setFileCount >= imgBoxLength){
					// 	disabledInputForm();
					// }
					// $("#preloader").removeClass('hide');
					// $("#trash").removeClass('disabled');
					// $("#genImg").attr("src",blankPNG);
					// $("#genImgWrapper").addClass('hide');
					
			  	}
			  	checkFileLsit( inFileList );
			};
		}



		$scope.deleteAction = function(){
			for(var i=0; i<imgBoxLength; i++){
				$('#preview'+i).attr("src",blankPNG);
				
			}
			setFileCount = 0;
			$("#trash").addClass('disabled');
			$("#genImg").attr("src",blankPNG);
			$("#genImgWrapper").addClass('hide');
			$("#absoluteContainer").addClass('hide');
			$("#getfile-path").val("");
			enabledInputForm();
			
		}

		function getImgBoxLength(){
			var imgBox = document.querySelectorAll("img.imgBox");
			return imgBox.length;
		}

		function disabledInputForm(){
			inputFileElm.setAttribute('disabled','');
			$("#getfile-path").attr('disabled','');
			$("#getfileBtn").addClass('disabled');
		}

		function enabledInputForm(){
			inputFileElm.removeAttribute('disabled','');
			$("#getfile-path").removeAttr('disabled','');
			$("#getfileBtn").removeClass('disabled');
		}

		function createImg(){
			html2canvas( $("#imgWrapper") , {
				  onrendered: function(canvas) {
				  	
				  	var ctx = canvas.getContext('2d');
		            ctx.mozImageSmoothingEnabled = false;
		            ctx.imageSmoothingEnabled = false;
				  	
					var dataURI = canvas.toDataURL('image/jpeg');
					$("#genImg").attr("src",dataURI);
				    $("#absoluteContainer").addClass('hide');
				    $("#genImgWrapper").removeClass('hide');
				    $("#genImgWrapper").attr("style","height:"+$("#genImg").innerHeight() + "px;");
				    $("#genImgWrapper").fadeIn(1000);
				    $("#preloader").addClass('hide');
				    
				    
				    //input [type=file]のイベントを削除し、複製削除する
				    //同じファイルパスでもonChangeが走る
				    $("#getfile").off('change');
				    $("#getfile").replaceWith($("#getfile").clone());
				    setOnChangeEvent();
				    
				    setTimeout(function(){ $(".fileSelectForm").removeAttr("style"); } , 5000);
				}
			});
		}
    	
    }]);

External CSS

  1. https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css
  2. https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js
  4. https://cdnjs.cloudflare.com/ajax/libs/masonry/3.3.2/masonry.pkgd.min.js
  5. https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js
  6. https://codepen.io/tea0828/pen/JGvVGp