├── src ├── img │ └── demo.gif ├── css │ └── img-enable-show.css └── js │ ├── img-service.js │ └── img-directive.js ├── package.json ├── LICENSE ├── example └── controller.js └── README.md /src/img/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bingcool/ionic-img-enable-show/HEAD/src/img/demo.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IonicImgEnableShow", 3 | "version": "0.1.0", 4 | "description": "An add-on directive and add-on service for the ion-slide-box, that adds tabs to the slide box, known from the Android Material Design specification", 5 | "main": "index.js", 6 | "directories": { 7 | "example": "example" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "author": "bingcool", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "jquery": "^1.8.0" 16 | } 17 | } -------------------------------------------------------------------------------- /src/css/img-enable-show.css: -------------------------------------------------------------------------------- 1 | /* Empty. Add your own CSS if you like */ 2 | .action-img-backdrop.active { 3 | background-color: rgba(5, 5, 5, 5.96); 4 | } 5 | 6 | .action-img-backdrop { 7 | -webkit-transition: background-color 150ms ease-in-out; 8 | transition: background-color 150ms ease-in-out; 9 | position: fixed; 10 | top: 0; 11 | left: 0; 12 | z-index: 11; 13 | width: 100%; 14 | height: 100%; 15 | } 16 | 17 | .action-img-backdrop .large-img-group { 18 | -webkit-transform: translate3d(0, 0, 0); 19 | transform: translate3d(0, 0,0); 20 | -webkit-transition: all cubic-bezier(0.36, 0.66, 0.1, 1) 400ms; 21 | transition: all cubic-bezier(0.36, 0.66, 0.1, 1) 400ms; 22 | left: 0; 23 | right:0; 24 | width:100%; 25 | height:100%; 26 | } 27 | .large-img-group img { 28 | position: absolute; 29 | top:10%; 30 | width:100%; 31 | height:70%; 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 BingCool 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /example/controller.js: -------------------------------------------------------------------------------- 1 | /** 2 | 仅是测试即演示用例 3 | */ 4 | .controller('SlideCtrl', function($scope, $rootScope,actionImgShow) 5 | // 现在定义一些图片数组 6 | var allimgs = [ 7 | { 8 | imgsrc: '/img/mike.png' 9 | }, 10 | { 11 | imgsrc: '/img/ben.png' 12 | }, 13 | { 14 | imgsrc: '/img/adam.jpg' 15 | }, 16 | { 17 | imgsrc: '/img/perry.png' 18 | } 19 | 20 | ]; 21 | 22 | //绑定至前端的初始显示,点击之后将会触发下面的onDoubleTap事件。 23 | $scope.imgs = allimgs; 24 | 25 | /** 26 | *图片预加载 27 | */ 28 | var arrImgs = new Array(); 29 | for(var i=0; i 15 | 16 | 17 | 18 | ``` 19 | (2)在app.js的控制器中,加入依赖的'ng-img','starter.imgservices'两个模块 20 | ``` 21 | angular.module('starter', ['ionic', 'starter.controllers', 'starter.services','ngResource','ngCordova','ng-mfb','ng-img','starter.imgservices']) 22 | 23 | ``` 24 | 25 | (3)那么在controller中,引入actionImgShow服务。 26 | ``` 27 | .controller('SlideCtrl', function($scope, $rootScope,actionImgShow) 28 | // 现在定义一些图片数组 29 | var allimgs = [ 30 | { 31 | imgsrc: '/img/mike.png' 32 | }, 33 | { 34 | imgsrc: '/img/ben.png' 35 | }, 36 | { 37 | imgsrc: '/img/adam.jpg' 38 | }, 39 | { 40 | imgsrc: '/img/perry.png' 41 | } 42 | 43 | ]; 44 | 45 | //绑定至前端的初始显示,点击之后将会触发下面的onDoubleTap事件。 46 | $scope.imgs = allimgs; 47 | 48 | /** 49 | *图片预加载 50 | */ 51 | var arrImgs = new Array(); 52 | for(var i=0; i')(scope); 35 | 36 | $ionicBody.append(element); 37 | 38 | actionImgShow.imgIsShow = true; 39 | 40 | obj.element = element; 41 | obj.scope = scope; 42 | /** 43 | *自定义一个硬件返回按钮的注册事件,事件的优先级为102,可以优先关闭图片放大层 44 | *返回一个注销该后退按钮动作的函数backbuttonRegistration并赋值全局obj变量 45 | */ 46 | obj.backbuttonRegistration = $ionicPlatform.registerBackButtonAction(function(e) { 47 | e.preventDefault(); 48 | if(actionImgShow.imgIsShow) { 49 | actionImgShow.close(); 50 | }else { 51 | if($ionicHistory.backView()) { 52 | $ionicHistory.goBack(); 53 | } 54 | } 55 | },102); 56 | }, 57 | 58 | /** 59 | *关闭图片放大层 60 | */ 61 | closeLargeImg: function() { 62 | this.imgIsShow = false; 63 | // 销毁作用域 64 | obj.scope.$destroy(); 65 | 66 | obj.element.remove(); 67 | // 执行该注销该后退按钮动作的函数 68 | if(obj.backbuttonRegistration) { 69 | obj.backbuttonRegistration(); 70 | } 71 | 72 | obj = { 73 | element: null, 74 | backbuttonRegistration: angular.noop, 75 | scope: null 76 | }; 77 | }, 78 | 79 | }; 80 | 81 | /** 82 | *返回的服务对象 83 | */ 84 | var actionImgShow = { 85 | // 图片放大服务的活动状态,true表示已弹出图片放大层,false表示关闭状态 86 | imgIsShow: false, 87 | // 图片放大层的弹出展示函数 88 | show: fns.showLargeImg, 89 | // 图片放大层的关闭函数 90 | close: fns.closeLargeImg 91 | }; 92 | 93 | return actionImgShow; 94 | }); 95 | })(); -------------------------------------------------------------------------------- /src/js/img-directive.js: -------------------------------------------------------------------------------- 1 | ;(function(window, angular, undefined) { 2 | 'use strict'; 3 | var img = angular.module('ng-img', []); 4 | 5 | img.run(['$templateCache', function($templateCache) { 6 | $templateCache.put('ng-img-slide-large.html', 7 | '
'+ 8 | '
'+ 9 | ''+ 10 | ''+ 11 | ''+ 12 | ''+ 13 | '
'+ 14 | ''+ 22 | '
' 23 | ); 24 | 25 | }]); 26 | 27 | img.directive('imgShow',['$compile','$timeout','$ionicGesture',function($compile, $timeout, $ionicGesture) { 28 | return { 29 | restrict: 'EA', 30 | transclude: true, 31 | replace: false, 32 | scope:false, 33 | link:function($scope,$element,$attrs) { 34 | if($scope.largeImg.imgsrc != undefined) { 35 | angular.element($element).append('').css({ 36 | "background-color":"rgba(5, 5, 5, 5.96)" 37 | }); 38 | }else { 39 | angular.element($element).append($scope.largeImg).css({ 40 | "background-color":"rgba(5, 5, 5, 5.96)" 41 | }); 42 | } 43 | 44 | var this_img = angular.element($element).find('img').css({ 45 | "transform-origin":"50% 50%", 46 | "-webkit-transform": "scale(1,1)", 47 | "transform":"scale(1,1)", 48 | "transition": "all 100ms linear", 49 | }); 50 | 51 | var this_imgbar = angular.element(document.querySelector('div.img-bar-footer')).css({ 52 | 'height':"20%", 53 | 'background-color':"rgb(5, 5, 5)", 54 | "background-size":'100% 0' 55 | }); 56 | 57 | /** 58 | *创建一个hammer对象 59 | */ 60 | var hammer = new Hammer($element[0].querySelector('img')); 61 | hammer.get('pinch').set({ enable: true }); 62 | hammer.add(new Hammer.Pinch()); 63 | /** 64 | *捏开点监听 65 | */ 66 | var initScale = 1, 67 | // 缩放中心点 68 | pinchX = 0, 69 | pinchY = 0; 70 | 71 | hammer.on("pinchstart",function (e) { 72 | // 缩放中心点 73 | pinchX = e.center.x; 74 | pinchY = e.center.y; 75 | 76 | this_img.css({ 77 | "transform-origin": +pinchX+'px'+' '+pinchY+'px', 78 | }); 79 | 80 | }); 81 | 82 | hammer.on("pinchout", function (e) { 83 | var scale = e.scale.toFixed(2) * initScale; 84 | /** 85 | *放大动画 86 | */ 87 | this_img.css({ 88 | "-webkit-transform": "scale("+scale+","+scale+")", 89 | "transform": "scale("+scale+","+scale+")", 90 | "transition": "all 100ms linear", 91 | }); 92 | 93 | // 设置footer透明度等于0.2 94 | this_imgbar.css({ 95 | "opacity": "0.2", 96 | }); 97 | 98 | }); 99 | 100 | hammer.on("pinchend", function (e) { 101 | initScale = e.scale.toFixed(2) * initScale; 102 | 103 | }); 104 | 105 | /** 106 | *捏合缩小,回弹原来大小 107 | */ 108 | hammer.on("pinchin", function (e) { 109 | 110 | var scale = e.scale.toFixed(2) * initScale; 111 | 112 | if(scale <= 0.8) { 113 | this_img.css({ 114 | "transform-origin": "50% 50%", 115 | "-webkit-transform": "scale(0.8,0.8)", 116 | "transform": "scale(0.8,0.8)", 117 | "transition": "all 200ms linear", 118 | }); 119 | 120 | initScale = 0.8; 121 | 122 | }else { 123 | this_img.css({ 124 | "transform-origin": "50% 50%", 125 | "-webkit-transform": "scale("+scale+","+scale+")", 126 | "transform": "scale("+scale+","+scale+")", 127 | "transition": "all 200ms linear", 128 | }); 129 | 130 | initScale = scale; 131 | } 132 | // 设置footer不透明 133 | this_imgbar.css({ 134 | "opacity":"1", 135 | }); 136 | }); 137 | 138 | 139 | /** 140 | *左滑动事件 141 | *图片恢复缩放 142 | */ 143 | var swipeleftFn = function() { 144 | if(initScale >1) { 145 | this_img.css({ 146 | "transform-origin":"50% 50%", 147 | "-webkit-transform": "scale(1,1)", 148 | "transform": "scale(1,1)", 149 | "transition": "all 100ms linear", 150 | }); 151 | initScale = 1; 152 | } 153 | 154 | }; 155 | var swipeleft = $ionicGesture.on('swipeleft', swipeleftFn, this_img); 156 | 157 | /** 158 | *右滑动事件 159 | *图片恢复缩放 160 | */ 161 | var swiperightFn = function() { 162 | if(initScale >1) { 163 | this_img.css({ 164 | "transform-origin":"50% 50%", 165 | "-webkit-transform": "scale(1,1)", 166 | "transform":"scale(1,1)", 167 | "transition": "all 100ms linear", 168 | }); 169 | initScale = 1; 170 | } 171 | }; 172 | 173 | var swiperight = $ionicGesture.on('swiperight', swiperightFn, this_img); 174 | 175 | // 销毁作用域时解绑手势事件 176 | $scope.$on("$destroy", function() { 177 | $ionicGesture.off(swipeleft, 'swipeleft', swipeleftFn); 178 | $ionicGesture.off(swiperight, 'swiperight', swiperightFn); 179 | $scope.$destroy(); 180 | }); 181 | 182 | } 183 | } 184 | }); 185 | 186 | img.directive('imgSlideLarge', ['$rootScope','$timeout', function($rootScope, $timeout) { 187 | return { 188 | restrict: 'EA', 189 | transclude: true, 190 | replace: true, 191 | scope: { 192 | larImgs: '=', 193 | currentImg: '@', 194 | imgClose: '&', 195 | }, 196 | templateUrl: function(element, attrs) { 197 | return attrs.templateUrl || 'ng-img-slide-large.html'; 198 | }, 199 | controller: ['$scope', '$attrs','$timeout','$ionicPlatform', function($scope, $attrs, $timeout, $ionicPlatform) { 200 | if($scope.currentImg != undefined) { 201 | $scope.imgActiveSlide = $scope.currentImg; 202 | $scope.currentLargeImg = parseInt($scope.currentImg) + 1; 203 | } 204 | 205 | // slide的总个数 206 | $scope.imgsNum = $scope.larImgs.length; 207 | 208 | $scope.slideImgChange = function($index) { 209 | $scope.currentLargeImg = $index+1; 210 | } 211 | 212 | }], 213 | }; 214 | }]); 215 | 216 | })(window, angular); 217 | --------------------------------------------------------------------------------