From 50a2b235e69f00334ea7a82290441392eb35427b Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Sun, 15 Dec 2013 12:17:48 -0600 Subject: [PATCH 1/8] Initial move to slide box with scroll --- dist/css/ionic.css | 8 ++++-- dist/js/ionic-angular.js | 25 ++++++++--------- js/ext/angular/src/directive/ionicScroll.js | 23 ++++++++------- js/ext/angular/src/directive/ionicSlideBox.js | 2 +- js/ext/angular/test/slideBox.html | 28 +++++++++---------- scss/_scaffolding.scss | 4 +++ scss/_slide-box.scss | 2 +- 7 files changed, 48 insertions(+), 44 deletions(-) diff --git a/dist/css/ionic.css b/dist/css/ionic.css index 2e7ba283ba6..0fa271a59dc 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -3,7 +3,7 @@ * Copyright 2013 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.17 + * Ionic, v0.9.14 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -2601,6 +2601,8 @@ body, .ionic-body { -moz-transform-origin: left top; transform-origin: left top; -webkit-backface-visibility: hidden; } + .scroll.paging { + white-space: nowrap; } .scroll-bar { position: absolute; @@ -4423,12 +4425,12 @@ button.item-button-right:after { -moz-transition-duration: 0.2s; transition-duration: 0.2s; } -.slide-box-slide { +.slide { display: inline-block; width: 100%; height: 100%; vertical-align: top; } - .slide-box-slide img { + .slide img { width: 100%; } .slide-box-pager { diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index 6afac7eb85e..0f90a19739b 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -1514,6 +1514,7 @@ angular.module('ionic.ui.scroll', []) transclude: true, scope: { direction: '@', + paging: '@', onRefresh: '&', onScroll: '&', refreshComplete: '=', @@ -1522,41 +1523,39 @@ angular.module('ionic.ui.scroll', []) scrollbarY: '@', }, + controller: function() {}, + compile: function(element, attr, transclude) { return function($scope, $element, $attr) { var clone, sv, sc = document.createElement('div'); + // Create the internal scroll div sc.className = 'scroll'; if(attr.padding == "true") { - sc.className += ' padding'; + sc.classList.add('padding'); addedPadding = true; } + if($scope.$eval($scope.paging) === true) { + sc.classList.add('paging'); + } $element.append(sc); // Pass the parent scope down to the child clone = transclude($scope.$parent); angular.element($element[0].firstElementChild).append(clone); + // Get refresher size var refresher = $element[0].querySelector('.scroll-refresher'); var refresherHeight = refresher && refresher.clientHeight || 0; - if(attr.refreshComplete) { - $scope.refreshComplete = function() { - if($scope.scrollView) { - refresher && refresher.classList.remove('active'); - $scope.scrollView.finishPullToRefresh(); - $scope.$parent.$broadcast('scroll.onRefreshComplete'); - } - }; - } - - + if(!$scope.direction) { $scope.direction = 'y'; } var hasScrollingX = $scope.direction.indexOf('x') >= 0; var hasScrollingY = $scope.direction.indexOf('y') >= 0; $timeout(function() { sv = new ionic.views.Scroll({ el: $element[0], + paging: $scope.$eval($scope.paging) === true, scrollbarX: $scope.$eval($scope.scrollbarX) !== false, scrollbarY: $scope.$eval($scope.scrollbarY) !== false, scrollingX: hasScrollingX, @@ -1849,7 +1848,7 @@ angular.module('ionic.ui.slideBox', []) return { restrict: 'E', replace: true, - require: '^slideBox', + require: '^scroll', transclude: true, template: '
', compile: function(element, attr, transclude) { diff --git a/js/ext/angular/src/directive/ionicScroll.js b/js/ext/angular/src/directive/ionicScroll.js index 497d20adad1..0aaa733ebc8 100644 --- a/js/ext/angular/src/directive/ionicScroll.js +++ b/js/ext/angular/src/directive/ionicScroll.js @@ -11,6 +11,7 @@ angular.module('ionic.ui.scroll', []) transclude: true, scope: { direction: '@', + paging: '@', onRefresh: '&', onScroll: '&', refreshComplete: '=', @@ -19,41 +20,39 @@ angular.module('ionic.ui.scroll', []) scrollbarY: '@', }, + controller: function() {}, + compile: function(element, attr, transclude) { return function($scope, $element, $attr) { var clone, sv, sc = document.createElement('div'); + // Create the internal scroll div sc.className = 'scroll'; if(attr.padding == "true") { - sc.className += ' padding'; + sc.classList.add('padding'); addedPadding = true; } + if($scope.$eval($scope.paging) === true) { + sc.classList.add('paging'); + } $element.append(sc); // Pass the parent scope down to the child clone = transclude($scope.$parent); angular.element($element[0].firstElementChild).append(clone); + // Get refresher size var refresher = $element[0].querySelector('.scroll-refresher'); var refresherHeight = refresher && refresher.clientHeight || 0; - if(attr.refreshComplete) { - $scope.refreshComplete = function() { - if($scope.scrollView) { - refresher && refresher.classList.remove('active'); - $scope.scrollView.finishPullToRefresh(); - $scope.$parent.$broadcast('scroll.onRefreshComplete'); - } - }; - } - - + if(!$scope.direction) { $scope.direction = 'y'; } var hasScrollingX = $scope.direction.indexOf('x') >= 0; var hasScrollingY = $scope.direction.indexOf('y') >= 0; $timeout(function() { sv = new ionic.views.Scroll({ el: $element[0], + paging: $scope.$eval($scope.paging) === true, scrollbarX: $scope.$eval($scope.scrollbarX) !== false, scrollbarY: $scope.$eval($scope.scrollbarY) !== false, scrollingX: hasScrollingX, diff --git a/js/ext/angular/src/directive/ionicSlideBox.js b/js/ext/angular/src/directive/ionicSlideBox.js index 616879c39b5..74526ab1d07 100644 --- a/js/ext/angular/src/directive/ionicSlideBox.js +++ b/js/ext/angular/src/directive/ionicSlideBox.js @@ -59,7 +59,7 @@ angular.module('ionic.ui.slideBox', []) return { restrict: 'E', replace: true, - require: '^slideBox', + require: '^scroll', transclude: true, template: '
', compile: function(element, attr, transclude) { diff --git a/js/ext/angular/test/slideBox.html b/js/ext/angular/test/slideBox.html index e08c4eb1a5f..d620e2d1abf 100644 --- a/js/ext/angular/test/slideBox.html +++ b/js/ext/angular/test/slideBox.html @@ -45,22 +45,22 @@
- - -
-

BLUE {{slideBox.slideIndex}}

+ +
+
+

BLUE {{slideBox.slideIndex}}

+
- - -
-

YELLOW {{slideBox.slideIndex}}

+
+
+

YELLOW {{slideBox.slideIndex}}

+
- - -

PINK {{slideBox.slideIndex}}

-
- -
+
+

PINK {{slideBox.slideIndex}}

+
+
+
+ + + + + + + + + + +
+ +
+
+

BLUE {{slideBox.slideIndex}}

+
+
+
+
+

YELLOW {{slideBox.slideIndex}}

+
+
+
+

PINK {{slideBox.slideIndex}}

+
+
+
+ + + + diff --git a/js/ext/angular/test/slideBox.html b/js/ext/angular/test/slideBox.html index d620e2d1abf..f8d0e9025ff 100644 --- a/js/ext/angular/test/slideBox.html +++ b/js/ext/angular/test/slideBox.html @@ -45,7 +45,7 @@
- +

BLUE {{slideBox.slideIndex}}

@@ -65,6 +65,9 @@

YELLOW {{slideBox.slideIndex}}

angular.module('slideBoxTest', ['ionic']) .controller('SlideCtrl', function($scope) { + $scope.onScroll = function(top, left) { + console.log('On scroll', top, left, $scope.scrollView.__maxScrollLeft); + }; $scope.$on('slideBox.slideChanged', function(e, index) { console.log('Slide changed', index); }); diff --git a/js/views/scrollView.js b/js/views/scrollView.js index 1834668fd23..f1cda2849e6 100644 --- a/js/views/scrollView.js +++ b/js/views/scrollView.js @@ -291,12 +291,12 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.options = { - /** Disable scrolling on x-axis by default */ - scrollingX: false, + /** Disable scrolling on x-axis by default */ + scrollingX: false, scrollbarX: true, - /** Enable scrolling on y-axis */ - scrollingY: true, + /** Enable scrolling on y-axis */ + scrollingY: true, scrollbarY: true, /** The minimum size the scrollbars scale to while scrolling */ @@ -309,42 +309,42 @@ ionic.views.Scroll = ionic.views.View.inherit({ /** The initial fade delay when the pane is resized or initialized */ scrollbarResizeFadeDelay: 1000, - /** Enable animations for deceleration, snap back, zooming and scrolling */ - animating: true, + /** Enable animations for deceleration, snap back, zooming and scrolling */ + animating: true, - /** duration for animations triggered by scrollTo/zoomTo */ - animationDuration: 250, + /** duration for animations triggered by scrollTo/zoomTo */ + animationDuration: 250, - /** Enable bouncing (content can be slowly moved outside and jumps back after releasing) */ - bouncing: true, + /** Enable bouncing (content can be slowly moved outside and jumps back after releasing) */ + bouncing: true, - /** Enable locking to the main axis if user moves only slightly on one of them at start */ - locking: true, + /** Enable locking to the main axis if user moves only slightly on one of them at start */ + locking: true, - /** Enable pagination mode (switching between full page content panes) */ - paging: false, + /** Enable pagination mode (switching between full page content panes) */ + paging: false, - /** Enable snapping of content to a configured pixel grid */ - snapping: false, + /** Enable snapping of content to a configured pixel grid */ + snapping: false, - /** Enable zooming of content via API, fingers and mouse wheel */ - zooming: false, + /** Enable zooming of content via API, fingers and mouse wheel */ + zooming: false, - /** Minimum zoom level */ - minZoom: 0.5, + /** Minimum zoom level */ + minZoom: 0.5, - /** Maximum zoom level */ - maxZoom: 3, + /** Maximum zoom level */ + maxZoom: 3, - /** Multiply or decrease scrolling speed **/ - speedMultiplier: 1, + /** Multiply or decrease scrolling speed **/ + speedMultiplier: 1, - /** Callback that is fired on the later of touch end or deceleration end, - provided that another scrolling action has not begun. Used to know - when to fade out a scrollbar. */ - scrollingComplete: NOOP, - - /** This configures the amount of change applied to deceleration when reaching boundaries **/ + /** Callback that is fired on the later of touch end or deceleration end, + provided that another scrolling action has not begun. Used to know + when to fade out a scrollbar. */ + scrollingComplete: NOOP, + + /** This configures the amount of change applied to deceleration when reaching boundaries **/ penetrationDeceleration : 0.03, /** This configures the amount of change applied to acceleration when reaching boundaries **/ @@ -1876,7 +1876,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ } // Animate to grid when snapping is active, otherwise just fix out-of-boundary positions - //self.scrollTo(self.__scrollLeft, self.__scrollTop, self.options.snapping); + if(self.options.paging) { + self.scrollTo(self.__scrollLeft, self.__scrollTop, self.options.snapping); + } }; // Start animation and switch on flag diff --git a/js/views/slideBoxView.js b/js/views/slideBoxView.js index 0d3d4e63d88..b1b0a70bb9a 100644 --- a/js/views/slideBoxView.js +++ b/js/views/slideBoxView.js @@ -3,7 +3,7 @@ * or iOS "dot" pager gallery, or maybe a carousel. * * Each screen fills the full width and height of the viewport, and screens can - * be swiped between, or set to automatically transition. + * be swiped between. */ (function(ionic) { 'use strict'; diff --git a/scss/_scaffolding.scss b/scss/_scaffolding.scss index c82d22e1a9f..26581cf98f4 100644 --- a/scss/_scaffolding.scss +++ b/scss/_scaffolding.scss @@ -101,8 +101,9 @@ body, .ionic-body { //-webkit-perspective: 1000; -webkit-backface-visibility: hidden; - &.paging { + &.scroll-paging { white-space: nowrap; + font-size: 0; } } From b9ebcd86a49875fd54c5b0ce38925b7c6705121c Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Sun, 15 Dec 2013 21:14:35 -0600 Subject: [PATCH 3/8] Much better slide box --- Gruntfile.js | 2 +- dist/css/ionic.css | 38 +- dist/js/ionic-angular.js | 62 +- dist/js/ionic.js | 751 ++++++++++++------ js/ext/angular/src/directive/ionicSlideBox.js | 60 +- js/ext/angular/test/infiniteScrollH.html | 78 -- js/ext/angular/test/slideBox.html | 18 +- js/views/sliderView.js | 581 ++++++++++++++ scss/_slide-box.scss | 25 +- 9 files changed, 1207 insertions(+), 408 deletions(-) delete mode 100644 js/ext/angular/test/infiniteScrollH.html create mode 100644 js/views/sliderView.js diff --git a/Gruntfile.js b/Gruntfile.js index 66754101dc7..ce7f4170d8f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -30,7 +30,7 @@ module.exports = function(grunt) { 'js/views/navBarView.js', 'js/views/popupView.js', 'js/views/sideMenuView.js', - 'js/views/slideBoxView.js', + 'js/views/sliderView.js', 'js/views/tabBarView.js', 'js/views/toggleView.js', diff --git a/dist/css/ionic.css b/dist/css/ionic.css index c8ed992174d..ca4f0e701d4 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -3,7 +3,7 @@ * Copyright 2013 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.14 + * Ionic, v0.9.17 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -4408,44 +4408,40 @@ button.item-button-right:after { * Slide Box * -------------------------------------------------- */ -.slide-box { +.slider { position: relative; overflow: hidden; + visibility: hidden; background-color: #000; } -.slide-box-slides { +.slider-slides { position: relative; white-space: nowrap; - font-size: 0; - -webkit-transition: -webkit-transform 0 ease-in-out; - -moz-transition: -moz-transform 0 ease-in-out; - transition: transform 0 ease-in-out; } - -.slide-box-animating { - -webkit-transition-duration: 0.2s; - -moz-transition-duration: 0.2s; - transition-duration: 0.2s; } + font-size: 0; } -.slide { - display: inline-block; +.slider-slide { + display: block; + position: relative; width: 100%; - height: 100%; + float: left; vertical-align: top; } - .slide img { + .slider-slide img { width: 100%; } -.slide-box-pager { +.slider-pager { position: absolute; bottom: 20px; width: 100%; - text-align: center; } - .slide-box-pager > * { + text-align: center; + z-index: 1; } + .slider-pager .slider-pager-page { display: inline-block; - margin: 0px 5px; + margin: 0px 3px; + width: 15px; color: #fff; text-decoration: none; opacity: 0.3; } - .slide-box-pager > *.active { + .slider-pager .slider-pager-page.active { opacity: 1; -webkit-transition: opacity 0.4s ease-in; -moz-transition: opacity 0.4s ease-in; diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index 485cc852718..0e6854c178b 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -2,7 +2,7 @@ * Copyright 2013 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.14 + * Ionic, v0.9.17 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -1811,32 +1811,38 @@ angular.module('ionic.ui.slideBox', []) * some side menu stuff on the current scope. */ -.directive('slideBox', ['$compile', function($compile) { +.directive('slideBox', ['$timeout', '$compile', function($timeout, $compile) { return { restrict: 'E', replace: true, transclude: true, scope: {}, controller: ['$scope', '$element', function($scope, $element) { - $scope.slides = []; - this.slideAdded = function() { - $scope.slides.push({}); - }; - - angular.extend(this, ionic.views.SlideBox.prototype); + var _this = this; - ionic.views.SlideBox.call(this, { + var slider = new ionic.views.Slider({ el: $element[0], - slideChanged: function(slideIndex) { + slidesChanged: function() { + $scope.currentSlide = slider.getPos(); + $timeout(function() {}); + }, + callback: function(slideIndex) { + $scope.currentSlide = slideIndex; $scope.$parent.$broadcast('slideBox.slideChanged', slideIndex); $scope.$apply(); } }); - $scope.$parent.slideBox = this; + slider.load(); + + $scope.slider = slider; + + $timeout(function() { + $scope.slider.setup(); + }); }], - template: '
\ -
\ + template: '
\ +
\
\
', @@ -1844,8 +1850,9 @@ angular.module('ionic.ui.slideBox', []) // If the pager should show, append it to the slide box if($attr.showPager !== "false") { var childScope = $scope.$new(); - var pager = $compile('')(childScope); + var pager = angular.element(''); $element.append(pager); + $compile(pager)(childScope); } } }; @@ -1857,10 +1864,9 @@ angular.module('ionic.ui.slideBox', []) replace: true, require: '^slideBox', transclude: true, - template: '
', + template: '
', compile: function(element, attr, transclude) { return function($scope, $element, $attr, slideBoxCtrl) { - slideBoxCtrl.slideAdded(); }; } }; @@ -1871,7 +1877,29 @@ angular.module('ionic.ui.slideBox', []) restrict: 'E', replace: true, require: '^slideBox', - template: '
' + template: '
', + link: function($scope, $element, $attr, slideBox) { + var selectPage = function(index) { + var children = $element[0].children; + var length = children.length; + for(var i = 0; i < length; i++) { + if(i == index) { + children[i].classList.add('active'); + } else { + children[i].classList.remove('active'); + } + } + }; + + $scope.numSlides = function() { + return new Array($scope.slider.getNumSlides()); + }; + + $scope.$watch('currentSlide', function(v) { + console.log('Current slide', v); + selectPage(v); + }); + } }; }); diff --git a/dist/js/ionic.js b/dist/js/ionic.js index 8e0517a684c..ef66e9b2bd2 100644 --- a/dist/js/ionic.js +++ b/dist/js/ionic.js @@ -2,7 +2,7 @@ * Copyright 2013 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.14 + * Ionic, v0.9.17 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -16,7 +16,7 @@ window.ionic = { controllers: {}, views: {}, - version: '0.9.14' + version: '0.9.17' };; (function(ionic) { @@ -4931,342 +4931,587 @@ ionic.views.Scroll = ionic.views.View.inherit({ })(ionic); ; -/** - * The SlideBox is a swipeable, slidable, slideshowable box. Think of any image gallery - * or iOS "dot" pager gallery, or maybe a carousel. +/* + * Adapted from Swipe.js 2.0 * - * Each screen fills the full width and height of the viewport, and screens can - * be swiped between. - */ + * Brad Birdsall + * Copyright 2013, MIT License + * +*/ + (function(ionic) { 'use strict'; - ionic.views.SlideBox = ionic.views.View.inherit({ - initialize: function(opts) { - var _this = this; +ionic.views.Slider = ionic.views.View.inherit({ + initialize: function (options) { + // utilities + var noop = function() {}; // simple no operation function + var offloadFn = function(fn) { setTimeout(fn || noop, 0) }; // offload a functions execution + + // check browser capabilities + var browser = { + addEventListener: !!window.addEventListener, + touch: ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, + transitions: (function(temp) { + var props = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition']; + for ( var i in props ) if (temp.style[ props[i] ] !== undefined) return true; + return false; + })(document.createElement('swipe')) + }; - this.slideChanged = opts.slideChanged || function() {}; - this.el = opts.el; - this.pager = this.el.querySelector('.slide-box-pager'); - // The drag threshold is the pixel delta that will trigger a drag (to - // avoid accidental dragging) - this.dragThresholdX = opts.dragThresholdX || 10; - // The velocity threshold is a velocity of drag that indicates a "swipe". This - // number is taken from hammer.js's calculations - this.velocityXThreshold = opts.velocityXThreshold || 0.3; + var container = options.el; - // Initialize the slide index to the first page and update the pager - this.slideIndex = 0; - this._updatePager(); + // quit if no root element + if (!container) return; + var element = container.children[0]; + var slides, slidePos, width, length; + options = options || {}; + var index = parseInt(options.startSlide, 10) || 0; + var speed = options.speed || 300; + options.continuous = options.continuous !== undefined ? options.continuous : true; - // Listen for drag and release events - window.ionic.onGesture('drag', function(e) { - _this._handleDrag(e); - e.gesture.srcEvent.preventDefault(); - }, this.el); - window.ionic.onGesture('release', function(e) { - _this._handleEndDrag(e); - }, this.el); - }, + function setup() { - /** - * Tell the pager to update itself if content is added or - * removed. - */ - update: function() { - this._updatePager(); - }, - - prependSlide: function(el) { - var content = this.el.firstElementChild; - if(!content) { return; } + // cache slides + slides = element.children; + length = slides.length; - var slideWidth = content.offsetWidth; - var offsetX = parseFloat(content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; - var newOffsetX = Math.min(0, offsetX - slideWidth); - - content.insertBefore(el, content.firstChild); + // set continuous to false if only one slide + if (slides.length < 2) options.continuous = false; - content.classList.remove('slide-box-animating'); - content.style.webkitTransform = 'translate3d(' + newOffsetX + 'px, 0, 0)'; + //special case if two slides + if (browser.transitions && options.continuous && slides.length < 3) { + element.appendChild(slides[0].cloneNode(true)); + element.appendChild(element.children[1].cloneNode(true)); + slides = element.children; + } - this._prependPagerIcon(); - this.slideIndex = (this.slideIndex + 1) % content.children.length; - this._updatePager(); - }, + // create an array to store current positions of each slide + slidePos = new Array(slides.length); - appendSlide: function(el) { - var content = this.el.firstElementChild; - if(!content) { return; } + // determine width of each slide + width = container.getBoundingClientRect().width || container.offsetWidth; - content.classList.remove('slide-box-animating'); - content.appendChild(el); + element.style.width = (slides.length * width) + 'px'; - this._appendPagerIcon(); - this._updatePager(); - }, + // stack elements + var pos = slides.length; + while(pos--) { - removeSlide: function(index) { - var content = this.el.firstElementChild; - if(!content) { return; } + var slide = slides[pos]; - var items = this.el.firstElementChild; - items.removeChild(items.firstElementChild); + slide.style.width = width + 'px'; + slide.setAttribute('data-index', pos); - var slideWidth = content.offsetWidth; - var offsetX = parseFloat(content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; - var newOffsetX = Math.min(0, offsetX + slideWidth); - - content.classList.remove('slide-box-animating'); - content.style.webkitTransform = 'translate3d(' + newOffsetX + 'px, 0, 0)'; + if (browser.transitions) { + slide.style.left = (pos * -width) + 'px'; + move(pos, index > pos ? -width : (index < pos ? width : 0), 0); + } - this._removePagerIcon(); - this.slideIndex = Math.max(0, (this.slideIndex - 1) % content.children.length); - this._updatePager(); - }, + } - /** - * Slide to the given slide index. - * - * @param {int} the index of the slide to animate to. - */ - slideToSlide: function(index) { - var content = this.el.firstElementChild; - if(!content) { - return; + // reposition elements before and after index + if (options.continuous && browser.transitions) { + move(circle(index-1), -width, 0); + move(circle(index+1), width, 0); } - // Get the width of one slide - var slideWidth = content.offsetWidth; + if (!browser.transitions) element.style.left = (index * -width) + 'px'; - // Calculate the new offsetX position which is just - // N slides to the left, where N is the given index - var offsetX = index * slideWidth; + container.style.visibility = 'visible'; - // Calculate the max X position we'd allow based on how many slides - // there are. - var maxX = Math.max(0, content.children.length - 1) * slideWidth; + options.slidesChanged && options.slidesChanged(); + } - // Bounds the offset X position in the range maxX >= offsetX >= 0 - offsetX = offsetX < 0 ? 0 : offsetX > maxX ? maxX : offsetX; + function prev() { - // Animate and slide the slides over - content.classList.add('slide-box-animating'); - content.style.webkitTransform = 'translate3d(' + -offsetX + 'px, 0, 0)'; + if (options.continuous) slide(index-1); + else if (index) slide(index-1); - var lastSlide = this.slideIndex; + } - // Update the slide index - this.slideIndex = Math.ceil(offsetX / slideWidth); + function next() { - if(lastSlide !== this.slideIndex) { - this.slideChanged && this.slideChanged(this.slideIndex); - } + if (options.continuous) slide(index+1); + else if (index < slides.length - 1) slide(index+1); - this._updatePager(); - }, + } - /** - * Get the currently set slide index. This method - * is updated before any transitions run, so the - * value could be early. - * - * @return {int} the current slide index - */ - getSlideIndex: function() { - return this.slideIndex; - }, + function circle(index) { - _appendPagerIcon: function() { - if(!this.pager || !this.pager.children.length) { return; } + // a simple positive modulo using slides.length + return (slides.length + (index % slides.length)) % slides.length; - var newPagerChild = this.pager.children[0].cloneNode(); - this.pager.appendChild(newPagerChild); - }, + } - _prependPagerIcon: function() { - if(!this.pager || !this.pager.children.length) { return; } + function slide(to, slideSpeed) { - var newPagerChild = this.pager.children[0].cloneNode(); - this.pager.insertBefore(newPagerChild, this.pager.firstChild); - }, + // do nothing if already on requested slide + if (index == to) return; - _removePagerIcon: function() { - if(!this.pager || !this.pager.children.length) { return; } + if (browser.transitions) { - this.pager.removeChild(this.pager.firstElementChild); - }, + var direction = Math.abs(index-to) / (index-to); // 1: backward, -1: forward - /** - * If we have a pager, update the active page when the current slide - * changes. - */ - _updatePager: function() { - if(!this.pager) { - return; + // get the actual position of the slide + if (options.continuous) { + var natural_direction = direction; + direction = -slidePos[circle(to)] / width; + + // if going forward but to < index, use to = slides.length + to + // if going backward but to > index, use to = -slides.length + to + if (direction !== natural_direction) to = -direction * slides.length + to; + + } + + var diff = Math.abs(index-to) - 1; + + // move all the slides between index and to in the right direction + while (diff--) move( circle((to > index ? to : index) - diff - 1), width * direction, 0); + + to = circle(to); + + move(index, width * direction, slideSpeed || speed); + move(to, 0, slideSpeed || speed); + + if (options.continuous) move(circle(to - direction), -(width * direction), 0); // we need to get the next in place + + } else { + + to = circle(to); + animate(index * -width, to * -width, slideSpeed || speed); + //no fallback for a circular continuous if the browser does not accept transitions } - var numPagerChildren = this.pager.children.length; - if(!numPagerChildren) { - // No children to update + index = to; + offloadFn(options.callback && options.callback(index, slides[index])); + } + + function move(index, dist, speed) { + + translate(index, dist, speed); + slidePos[index] = dist; + + } + + function translate(index, dist, speed) { + + var slide = slides[index]; + var style = slide && slide.style; + + if (!style) return; + + style.webkitTransitionDuration = + style.MozTransitionDuration = + style.msTransitionDuration = + style.OTransitionDuration = + style.transitionDuration = speed + 'ms'; + + style.webkitTransform = 'translate(' + dist + 'px,0)' + 'translateZ(0)'; + style.msTransform = + style.MozTransform = + style.OTransform = 'translateX(' + dist + 'px)'; + + } + + function animate(from, to, speed) { + + // if not an animation, just reposition + if (!speed) { + + element.style.left = to + 'px'; return; - } - // Update the active state of the pager icons - for(var i = 0, j = this.pager.children.length; i < j; i++) { - if(i == this.slideIndex) { - this.pager.children[i].classList.add('active'); - } else { - this.pager.children[i].classList.remove('active'); - } } - }, - _initDrag: function() { - this._isDragging = false; - this._drag = null; - }, + var start = +new Date; - _handleEndDrag: function(e) { - var _this = this, - finalOffsetX, content, ratio, slideWidth, totalWidth, offsetX; + var timer = setInterval(function() { - window.rAF(function() { - - // We didn't have a drag, so just init and leave - if(!_this._drag) { - _this._initDrag(); + var timeElap = +new Date - start; + + if (timeElap > speed) { + + element.style.left = to + 'px'; + + if (delay) begin(); + + options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); + + clearInterval(timer); return; + + } + + element.style.left = (( (to - from) * (Math.floor((timeElap / speed) * 100) / 100) ) + from) + 'px'; + + }, 4); + + } + + // setup auto slideshow + var delay = options.auto || 0; + var interval; + + function begin() { + + interval = setTimeout(next, delay); + + } + + function stop() { + + delay = 0; + clearTimeout(interval); + + } + + + // setup initial vars + var start = {}; + var delta = {}; + var isScrolling; + + // setup event capturing + var events = { + + handleEvent: function(event) { + if(event.type == 'mousedown' || event.type == 'mouseup' || event.type == 'mousemove') { + event.touches = [{ + pageX: event.pageX, + pageY: event.pageY + }]; + } + + switch (event.type) { + case 'mousedown': this.start(event); break; + case 'touchstart': this.start(event); break; + case 'touchmove': this.move(event); break; + case 'mousemove': this.move(event); break; + case 'touchend': offloadFn(this.end(event)); break; + case 'mouseup': offloadFn(this.end(event)); break; + case 'webkitTransitionEnd': + case 'msTransitionEnd': + case 'oTransitionEnd': + case 'otransitionend': + case 'transitionend': offloadFn(this.transitionEnd(event)); break; + case 'resize': offloadFn(setup); break; } - // We did have a drag, so we need to snap to the correct spot + if (options.stopPropagation) event.stopPropagation(); + + }, + start: function(event) { + + var touches = event.touches[0]; + + // measure start values + start = { - // Grab the content layer - content = _this._drag.content; + // get initial touch coords + x: touches.pageX, + y: touches.pageY, - // Enable transition duration - content.classList.add('slide-box-animating'); + // store time to determine touch duration + time: +new Date - // Grab the current offset X position - offsetX = parseFloat(content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; + }; - // Calculate how wide a single slide is, and their total width - slideWidth = content.offsetWidth; - totalWidth = content.offsetWidth * content.children.length; + // used for testing first move event + isScrolling = undefined; - // Calculate how far in this slide we've dragged - ratio = (offsetX % slideWidth) / slideWidth; + // reset delta and end measurements + delta = {}; - if(ratio >= 0) { - // Anything greater than zero is too far left, this is an extreme case - // TODO: Do we need this anymore? - finalOffsetX = 0; - } else if(ratio >= -0.5) { - // We are less than half-way through a drag - // Sliiide to the left - finalOffsetX = Math.max(0, Math.floor(Math.abs(offsetX) / slideWidth) * slideWidth); + // attach touchmove and touchend listeners + if(browser.touch) { + element.addEventListener('touchmove', this, false); + element.addEventListener('touchend', this, false); } else { - // We are more than half-way through a drag - // Sliiide to the right - finalOffsetX = Math.min(totalWidth - slideWidth, Math.ceil(Math.abs(offsetX) / slideWidth) * slideWidth); + element.addEventListener('mousemove', this, false); + element.addEventListener('mouseup', this, false); + } + }, + move: function(event) { + + // ensure swiping with one touch and not pinching + if ( event.touches.length > 1 || event.scale && event.scale !== 1) return + + if (options.disableScroll) event.preventDefault(); + + var touches = event.touches[0]; + + // measure change in x and y + delta = { + x: touches.pageX - start.x, + y: touches.pageY - start.y + } + + // determine if scrolling test has run - one time test + if ( typeof isScrolling == 'undefined') { + isScrolling = !!( isScrolling || Math.abs(delta.x) < Math.abs(delta.y) ); } + // if user is not trying to scroll vertically + if (!isScrolling) { - if(e.gesture.velocityX > _this.velocityXThreshold) { - if(e.gesture.direction == 'left') { - _this.slideToSlide(_this.slideIndex + 1); - } else if(e.gesture.direction == 'right') { - _this.slideToSlide(_this.slideIndex - 1); + // prevent native scrolling + event.preventDefault(); + + // stop slideshow + stop(); + + // increase resistance if first or last slide + if (options.continuous) { // we don't add resistance at the end + + translate(circle(index-1), delta.x + slidePos[circle(index-1)], 0); + translate(index, delta.x + slidePos[index], 0); + translate(circle(index+1), delta.x + slidePos[circle(index+1)], 0); + + } else { + + delta.x = + delta.x / + ( (!index && delta.x > 0 // if first slide and sliding left + || index == slides.length - 1 // or if last slide and sliding right + && delta.x < 0 // and if sliding at all + ) ? + ( Math.abs(delta.x) / width + 1 ) // determine resistance level + : 1 ); // no resistance if false + + // translate 1:1 + translate(index-1, delta.x + slidePos[index-1], 0); + translate(index, delta.x + slidePos[index], 0); + translate(index+1, delta.x + slidePos[index+1], 0); } - } else { - // Calculate the new slide index (or "page") - _this.slideIndex = Math.ceil(finalOffsetX / slideWidth); - // Negative offsetX to slide correctly - content.style.webkitTransform = 'translate3d(' + -finalOffsetX + 'px, 0, 0)'; } - _this._initDrag(); - }); - }, + }, + end: function(event) { - /** - * Initialize a drag by grabbing the content area to drag, and any other - * info we might need for the dragging. - */ - _startDrag: function(e) { - var offsetX, content; + // measure duration + var duration = +new Date - start.time; - this._initDrag(); + // determine if slide attempt triggers next/prev slide + var isValidSlide = + Number(duration) < 250 // if slide duration is less than 250ms + && Math.abs(delta.x) > 20 // and if slide amt is greater than 20px + || Math.abs(delta.x) > width/2; // or if slide amt is greater than half the width - // Make sure to grab the element we will slide as our target - content = ionic.DomUtil.getParentOrSelfWithClass(e.target, 'slide-box-slides'); - if(!content) { - return; - } + // determine if slide attempt is past start and end + var isPastBounds = + !index && delta.x > 0 // if first slide and slide amt is greater than 0 + || index == slides.length - 1 && delta.x < 0; // or if last slide and slide amt is less than 0 - // Disable transitions during drag - content.classList.remove('slide-box-animating'); + if (options.continuous) isPastBounds = false; - // Grab the starting X point for the item (for example, so we can tell whether it is open or closed to start) - offsetX = parseFloat(content.style.webkitTransform.replace('translate3d(', '').split(',')[0]) || 0; + // determine direction of swipe (true:right, false:left) + var direction = delta.x < 0; - this._drag = { - content: content, - startOffsetX: offsetX, - resist: 1 - }; - }, + // if not scrolling vertically + if (!isScrolling) { - /** - * Process the drag event to move the item to the left or right. - */ - _handleDrag: function(e) { - var _this = this; + if (isValidSlide && !isPastBounds) { - window.rAF(function() { - var content; + if (direction) { + + if (options.continuous) { // we need to get the next in this direction in place + + move(circle(index-1), -width, 0); + move(circle(index+2), width, 0); + + } else { + move(index-1, -width, 0); + } + + move(index, slidePos[index]-width, speed); + move(circle(index+1), slidePos[circle(index+1)]-width, speed); + index = circle(index+1); + + } else { + if (options.continuous) { // we need to get the next in this direction in place + + move(circle(index+1), width, 0); + move(circle(index-2), -width, 0); + + } else { + move(index+1, width, 0); + } + + move(index, slidePos[index]+width, speed); + move(circle(index-1), slidePos[circle(index-1)]+width, speed); + index = circle(index-1); + + } + + options.callback && options.callback(index, slides[index]); + + } else { + + if (options.continuous) { + + move(circle(index-1), -width, speed); + move(index, 0, speed); + move(circle(index+1), width, speed); + + } else { + + move(index-1, -width, speed); + move(index, 0, speed); + move(index+1, width, speed); + } + + } - // We really aren't dragging - if(!_this._drag) { - _this._startDrag(e); } - // Sanity - if(!_this._drag) { return; } + // kill touchmove and touchend event listeners until touchstart called again + if(browser.touch) { + element.removeEventListener('touchmove', events, false) + element.removeEventListener('touchend', events, false) + } else { + element.removeEventListener('mousemove', events, false) + element.removeEventListener('mouseup', events, false) + } - // Stop any default events during the drag - e.preventDefault(); + }, + transitionEnd: function(event) { + + if (parseInt(event.target.getAttribute('data-index'), 10) == index) { + + if (delay) begin(); + + options.transitionEnd && options.transitionEnd.call(event, index, slides[index]); - // Check if we should start dragging. Check if we've dragged past the threshold. - if(!_this._isDragging && (Math.abs(e.gesture.deltaX) > _this.dragThresholdX)) { - _this._isDragging = true; } - if(_this._isDragging) { - content = _this._drag.content; + } + + } - var newX = _this._drag.startOffsetX + (e.gesture.deltaX / _this._drag.resist); + // Public API + this.setup = function() { + setup(); + }; - var rightMostX = -(content.offsetWidth * Math.max(0, content.children.length - 1)); + this.slide = function(to, speed) { + // cancel slideshow + stop(); - if(newX > 0) { - // We are dragging past the leftmost pane, rubber band - _this._drag.resist = (newX / content.offsetWidth) + 1.4; - } else if(newX < rightMostX) { - // Dragging past the rightmost pane, rubber band - //newX = Math.min(rightMostX, + (((e.gesture.deltaX + buttonsWidth) * 0.4))); - _this._drag.resist = (Math.abs(newX) / content.offsetWidth) - 0.6; - } + slide(to, speed); + }; + + this.prev = function() { + // cancel slideshow + stop(); + + prev(); + }; + + this.next = function() { + // cancel slideshow + stop(); + + next(); + }; + + this.stop = function() { + // cancel slideshow + stop(); + }; + + this.getPos = function() { + // return current index position + return index; + }; + + this.getNumSlides = function() { + // return total number of slides + return length; + }; + + this.kill = function() { + // cancel slideshow + stop(); + + // reset element + element.style.width = ''; + element.style.left = ''; + + // reset slides + var pos = slides.length; + while(pos--) { + + var slide = slides[pos]; + slide.style.width = ''; + slide.style.left = ''; + + if (browser.transitions) translate(pos, 0, 0); + + } + + // removed event listeners + if (browser.addEventListener) { - _this._drag.content.style.webkitTransform = 'translate3d(' + newX + 'px, 0, 0)'; + // remove current event listeners + element.removeEventListener('touchstart', events, false); + element.removeEventListener('webkitTransitionEnd', events, false); + element.removeEventListener('msTransitionEnd', events, false); + element.removeEventListener('oTransitionEnd', events, false); + element.removeEventListener('otransitionend', events, false); + element.removeEventListener('transitionend', events, false); + window.removeEventListener('resize', events, false); + + } + else { + + window.onresize = null; + + } + }; + + this.load = function() { + // trigger setup + setup(); + + // start auto slideshow if applicable + if (delay) begin(); + + + // add event listeners + if (browser.addEventListener) { + + // set touchstart event on element + if (browser.touch) { + element.addEventListener('touchstart', events, false); + } else { + element.addEventListener('mousedown', events, false); } - }); + + if (browser.transitions) { + element.addEventListener('webkitTransitionEnd', events, false); + element.addEventListener('msTransitionEnd', events, false); + element.addEventListener('oTransitionEnd', events, false); + element.addEventListener('otransitionend', events, false); + element.addEventListener('transitionend', events, false); + } + + // set resize event on window + window.addEventListener('resize', events, false); + + } else { + + window.onresize = function () { setup() }; // to play nice with old IE + + } } - }); -})(window.ionic); + } +}); + +})(ionic); ; (function(ionic) { 'use strict'; diff --git a/js/ext/angular/src/directive/ionicSlideBox.js b/js/ext/angular/src/directive/ionicSlideBox.js index 616879c39b5..63730cdbbd3 100644 --- a/js/ext/angular/src/directive/ionicSlideBox.js +++ b/js/ext/angular/src/directive/ionicSlideBox.js @@ -15,32 +15,38 @@ angular.module('ionic.ui.slideBox', []) * some side menu stuff on the current scope. */ -.directive('slideBox', ['$compile', function($compile) { +.directive('slideBox', ['$timeout', '$compile', function($timeout, $compile) { return { restrict: 'E', replace: true, transclude: true, scope: {}, controller: ['$scope', '$element', function($scope, $element) { - $scope.slides = []; - this.slideAdded = function() { - $scope.slides.push({}); - }; - - angular.extend(this, ionic.views.SlideBox.prototype); + var _this = this; - ionic.views.SlideBox.call(this, { + var slider = new ionic.views.Slider({ el: $element[0], - slideChanged: function(slideIndex) { + slidesChanged: function() { + $scope.currentSlide = slider.getPos(); + $timeout(function() {}); + }, + callback: function(slideIndex) { + $scope.currentSlide = slideIndex; $scope.$parent.$broadcast('slideBox.slideChanged', slideIndex); $scope.$apply(); } }); - $scope.$parent.slideBox = this; + slider.load(); + + $scope.slider = slider; + + $timeout(function() { + $scope.slider.setup(); + }); }], - template: '
\ -
\ + template: '
\ +
\
\
', @@ -48,8 +54,9 @@ angular.module('ionic.ui.slideBox', []) // If the pager should show, append it to the slide box if($attr.showPager !== "false") { var childScope = $scope.$new(); - var pager = $compile('')(childScope); + var pager = angular.element(''); $element.append(pager); + $compile(pager)(childScope); } } }; @@ -61,10 +68,9 @@ angular.module('ionic.ui.slideBox', []) replace: true, require: '^slideBox', transclude: true, - template: '
', + template: '
', compile: function(element, attr, transclude) { return function($scope, $element, $attr, slideBoxCtrl) { - slideBoxCtrl.slideAdded(); }; } }; @@ -75,7 +81,29 @@ angular.module('ionic.ui.slideBox', []) restrict: 'E', replace: true, require: '^slideBox', - template: '
' + template: '
', + link: function($scope, $element, $attr, slideBox) { + var selectPage = function(index) { + var children = $element[0].children; + var length = children.length; + for(var i = 0; i < length; i++) { + if(i == index) { + children[i].classList.add('active'); + } else { + children[i].classList.remove('active'); + } + } + }; + + $scope.numSlides = function() { + return new Array($scope.slider.getNumSlides()); + }; + + $scope.$watch('currentSlide', function(v) { + console.log('Current slide', v); + selectPage(v); + }); + } }; }); diff --git a/js/ext/angular/test/infiniteScrollH.html b/js/ext/angular/test/infiniteScrollH.html deleted file mode 100644 index f8d0e9025ff..00000000000 --- a/js/ext/angular/test/infiniteScrollH.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - Sldie Box - - - - - - - - - - - - - - - -
- -
-
-

BLUE {{slideBox.slideIndex}}

-
-
-
-
-

YELLOW {{slideBox.slideIndex}}

-
-
-
-

PINK {{slideBox.slideIndex}}

-
-
-
- - - - diff --git a/js/ext/angular/test/slideBox.html b/js/ext/angular/test/slideBox.html index f8d0e9025ff..703fe0cca11 100644 --- a/js/ext/angular/test/slideBox.html +++ b/js/ext/angular/test/slideBox.html @@ -1,7 +1,7 @@ - Sldie Box + Slide Box @@ -45,21 +45,21 @@
- -
+ +

BLUE {{slideBox.slideIndex}}

-
-
+ +

YELLOW {{slideBox.slideIndex}}

-
-
+ +

PINK {{slideBox.slideIndex}}

-
-
+ +
+ + + + + +
- + + -
-

BLUE {{slideBox.slideIndex}}

+
+

Thank you for choosing my app!

+

+ We've worked super hard to make you happy. +

+

+ But if you are angry, please contact us at support@example.com +

-
-

YELLOW {{slideBox.slideIndex}}

+
-

PINK {{slideBox.slideIndex}}

+
+
@@ -65,12 +70,37 @@

YELLOW {{slideBox.slideIndex}}

angular.module('slideBoxTest', ['ionic']) .controller('SlideCtrl', function($scope) { - $scope.onScroll = function(top, left) { - console.log('On scroll', top, left, $scope.scrollView.__maxScrollLeft); - }; - $scope.$on('slideBox.slideChanged', function(e, index) { + $scope.leftButtons = [ + { + content: 'Skip', + type: 'button-positive button-clear', + onTap: function(e) { + } + } + ]; + $scope.slideChanged = function(index) { console.log('Slide changed', index); - }); + if(index == 2) { + $scope.rightButtons = [ + { + content: 'Start using MyApp', + type: 'button-positive button-clear', + onTap: function(e) { + } + } + ]; + } else { + $scope.rightButtons = [ + { + content: 'Next', + type: 'button-positive button-clear', + onTap: function(e) { + } + } + ]; + } + $scope.$apply(); + }; }); diff --git a/scss/_scaffolding.scss b/scss/_scaffolding.scss index 26581cf98f4..7743d8041b9 100644 --- a/scss/_scaffolding.scss +++ b/scss/_scaffolding.scss @@ -100,11 +100,6 @@ body, .ionic-body { @include transform-origin(left, top); //-webkit-perspective: 1000; -webkit-backface-visibility: hidden; - - &.scroll-paging { - white-space: nowrap; - font-size: 0; - } } // Scroll bar styles diff --git a/scss/_slide-box.scss b/scss/_slide-box.scss index 1b7675a127b..1c38f222e73 100644 --- a/scss/_slide-box.scss +++ b/scss/_slide-box.scss @@ -13,8 +13,6 @@ } .slider-slides { position: relative; - white-space: nowrap; - font-size: 0; // Remove the gaps between slide content items } .slider-slide { From 4de3403f79951749516892094566f04c1f7b7807 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Mon, 16 Dec 2013 13:20:38 -0600 Subject: [PATCH 6/8] Removing animation from header and stuff --- dist/css/ionic.css | 5 +++++ dist/js/ionic-angular.js | 2 +- js/ext/angular/src/directive/ionicBar.js | 2 +- js/ext/angular/test/slideBox.html | 11 +++++++++++ scss/_animations.scss | 5 +++++ 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/dist/css/ionic.css b/dist/css/ionic.css index 3b11d169ab0..24c398b7f42 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -5701,6 +5701,11 @@ a.button { 100% { transform: rotate(360deg); } } +.no-animation > .ng-enter, .no-animation.ng-enter, .no-animation > .ng-leave, .no-animation.ng-leave { + -webkit-transition: none; + -moz-transition: none; + transition: none; } + .noop-animation > .ng-enter, .noop-animation.ng-enter, .noop-animation > .ng-leave, .noop-animation.ng-leave { -webkit-transition: all cubic-bezier(0.25, 0.46, 0.45, 0.94) 250ms; -moz-transition: all cubic-bezier(0.25, 0.46, 0.45, 0.94) 250ms; diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index f70331865fb..7f9b15fc390 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -512,7 +512,7 @@ angular.module('ionic.ui.header', ['ngAnimate'])
\

\
\ - \
\ ', diff --git a/js/ext/angular/src/directive/ionicBar.js b/js/ext/angular/src/directive/ionicBar.js index cf63406b27e..9c78edfa46d 100644 --- a/js/ext/angular/src/directive/ionicBar.js +++ b/js/ext/angular/src/directive/ionicBar.js @@ -16,7 +16,7 @@ angular.module('ionic.ui.header', ['ngAnimate'])
\

\
\ - \
\ ', diff --git a/js/ext/angular/test/slideBox.html b/js/ext/angular/test/slideBox.html index a672e54237c..f7a3125f6f1 100644 --- a/js/ext/angular/test/slideBox.html +++ b/js/ext/angular/test/slideBox.html @@ -70,6 +70,17 @@

Thank you for choosing my app!

angular.module('slideBoxTest', ['ionic']) .controller('SlideCtrl', function($scope) { + $scope.next = function() { + }; + $scope.rightButtons = [ + { + content: 'Next', + type: 'button-positive button-clear', + onTap: function(e) { + $scope.next(); + } + } + ]; $scope.leftButtons = [ { content: 'Skip', diff --git a/scss/_animations.scss b/scss/_animations.scss index 9857e5322c1..089af2a81a4 100644 --- a/scss/_animations.scss +++ b/scss/_animations.scss @@ -151,6 +151,11 @@ $slide-in-up-function: cubic-bezier(.1, .7, .1, 1); 100% { transform: rotate(360deg); } } +.no-animation { + > .ng-enter, &.ng-enter, > .ng-leave, &.ng-leave { + @include transition(none); + } +} .noop-animation { > .ng-enter, &.ng-enter, > .ng-leave, &.ng-leave { @include transition(all cubic-bezier(0.250, 0.460, 0.450, 0.940) $transition-duration); From b996e9a8c7eb849fcc3fc4084a6b483a1dc30d3c Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Mon, 16 Dec 2013 15:36:14 -0600 Subject: [PATCH 7/8] SEXY --- dist/css/ionic.css | 8 +- dist/js/ionic-angular.js | 21 +++- js/ext/angular/src/directive/ionicBar.js | 2 +- js/ext/angular/src/directive/ionicSlideBox.js | 19 +++- js/ext/angular/test/app_icon.png | Bin 0 -> 12451 bytes js/ext/angular/test/slideBox.html | 105 ++++++++++++------ scss/_slide-box.scss | 6 +- 7 files changed, 115 insertions(+), 46 deletions(-) create mode 100644 js/ext/angular/test/app_icon.png diff --git a/dist/css/ionic.css b/dist/css/ionic.css index 24c398b7f42..312103f999d 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -4408,8 +4408,7 @@ button.item-button-right:after { .slider { position: relative; overflow: hidden; - visibility: hidden; - background-color: #000; } + visibility: hidden; } .slider-slides { position: relative; } @@ -4420,8 +4419,9 @@ button.item-button-right:after { width: 100%; float: left; vertical-align: top; } - .slider-slide img { - width: 100%; } + +.slider-slide-image > img { + width: 100%; } .slider-pager { position: absolute; diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index 7f9b15fc390..bda9b4ad779 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -507,7 +507,7 @@ angular.module('ionic.ui.header', ['ngAnimate']) transclude: true, template: '
\
\ - \
\

\ @@ -1818,6 +1818,7 @@ angular.module('ionic.ui.slideBox', []) replace: true, transclude: true, scope: { + doesContinue: '@', showPager: '@', onSlideChanged: '&' }, @@ -1826,20 +1827,34 @@ angular.module('ionic.ui.slideBox', []) var slider = new ionic.views.Slider({ el: $element[0], + continuous: $scope.$eval($scope.doesContinue) === true, slidesChanged: function() { $scope.currentSlide = slider.getPos(); - // Occasionally we need to trigger a digest + // Try to trigger a digest $timeout(function() {}); }, callback: function(slideIndex) { $scope.currentSlide = slideIndex; $scope.onSlideChanged({index:$scope.currentSlide}); $scope.$parent.$broadcast('slideBox.slideChanged', slideIndex); - $scope.$apply(); + + // Try to trigger a digest + $timeout(function() {}); } }); + $scope.$on('slideBox.nextSlide', function() { + slider.next(); + }); + + $scope.$on('slideBox.prevSlide', function() { + slider.prev(); + }); + + $scope.$on('slideBox.setSlide', function(e, index) { + slider.slide(index); + }); $scope.slider = slider; diff --git a/js/ext/angular/src/directive/ionicBar.js b/js/ext/angular/src/directive/ionicBar.js index 9c78edfa46d..bb47afeb5a6 100644 --- a/js/ext/angular/src/directive/ionicBar.js +++ b/js/ext/angular/src/directive/ionicBar.js @@ -11,7 +11,7 @@ angular.module('ionic.ui.header', ['ngAnimate']) transclude: true, template: '
\
\ - \
\

\ diff --git a/js/ext/angular/src/directive/ionicSlideBox.js b/js/ext/angular/src/directive/ionicSlideBox.js index acf98705a39..18a71f303ef 100644 --- a/js/ext/angular/src/directive/ionicSlideBox.js +++ b/js/ext/angular/src/directive/ionicSlideBox.js @@ -21,6 +21,7 @@ angular.module('ionic.ui.slideBox', []) replace: true, transclude: true, scope: { + doesContinue: '@', showPager: '@', onSlideChanged: '&' }, @@ -29,20 +30,34 @@ angular.module('ionic.ui.slideBox', []) var slider = new ionic.views.Slider({ el: $element[0], + continuous: $scope.$eval($scope.doesContinue) === true, slidesChanged: function() { $scope.currentSlide = slider.getPos(); - // Occasionally we need to trigger a digest + // Try to trigger a digest $timeout(function() {}); }, callback: function(slideIndex) { $scope.currentSlide = slideIndex; $scope.onSlideChanged({index:$scope.currentSlide}); $scope.$parent.$broadcast('slideBox.slideChanged', slideIndex); - $scope.$apply(); + + // Try to trigger a digest + $timeout(function() {}); } }); + $scope.$on('slideBox.nextSlide', function() { + slider.next(); + }); + + $scope.$on('slideBox.prevSlide', function() { + slider.prev(); + }); + + $scope.$on('slideBox.setSlide', function(e, index) { + slider.slide(index); + }); $scope.slider = slider; diff --git a/js/ext/angular/test/app_icon.png b/js/ext/angular/test/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..57c77bb4e8381bfd9905a77acf15b63ce8ec3d9a GIT binary patch literal 12451 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 literal 0 HcmV?d00001 diff --git a/js/ext/angular/test/slideBox.html b/js/ext/angular/test/slideBox.html index f7a3125f6f1..338e628ccbd 100644 --- a/js/ext/angular/test/slideBox.html +++ b/js/ext/angular/test/slideBox.html @@ -14,29 +14,37 @@ @@ -46,23 +54,34 @@ -
-

Thank you for choosing my app!

-

- We've worked super hard to make you happy. -

-

- But if you are angry, please contact us at support@example.com -

+

Thank you for choosing the Awesome App!

+ +

+ We've worked super hard to make you happy. +

+

+ But if you are angry, too bad. +

-
+

Using Awesome

+ +
+
Just three steps:
+
    +
  1. Be awesome
  2. +
  3. Stay awesome
  4. +
  5. There is no step 3
  6. +
-
-
+

Any questions?

+

+ Too bad! +

@@ -71,46 +90,64 @@

Thank you for choosing my app!

.controller('SlideCtrl', function($scope) { $scope.next = function() { + console.log('NEXT'); + $scope.$broadcast('slideBox.nextSlide'); }; - $scope.rightButtons = [ + + var rightButtons = [ { content: 'Next', type: 'button-positive button-clear', - onTap: function(e) { + tap: function(e) { + console.log('NEXT'); $scope.next(); } } ]; - $scope.leftButtons = [ + var leftButtons = [ { content: 'Skip', type: 'button-positive button-clear', - onTap: function(e) { + tap: function(e) { + alert('Skipping'); } } ]; + + $scope.leftButtons = leftButtons; + $scope.rightButtons = rightButtons; + + $scope.slideChanged = function(index) { console.log('Slide changed', index); - if(index == 2) { - $scope.rightButtons = [ + + if(index > 0) { + $scope.leftButtons = [ { - content: 'Start using MyApp', + content: 'Back', type: 'button-positive button-clear', - onTap: function(e) { + tap: function(e) { + $scope.$broadcast('slideBox.prevSlide'); } } ]; } else { + $scope.leftButtons = leftButtons; + } + + if(index == 2) { $scope.rightButtons = [ { - content: 'Next', + content: 'Start using MyApp', type: 'button-positive button-clear', - onTap: function(e) { + tap: function(e) { + alert('Done!'); } } ]; + } else { + $scope.rightButtons = rightButtons; } - $scope.$apply(); }; }); diff --git a/scss/_slide-box.scss b/scss/_slide-box.scss index 1c38f222e73..a13a24c4cda 100644 --- a/scss/_slide-box.scss +++ b/scss/_slide-box.scss @@ -9,7 +9,6 @@ // Make sure items don't scroll over ever overflow: hidden; visibility: hidden; - background-color: #000; } .slider-slides { position: relative; @@ -22,7 +21,10 @@ float: left; vertical-align: top; - img { +} + +.slider-slide-image { + > img { width: 100%; } } From 89a3b7538d94a31444f4992aff98455f25a53049 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Mon, 16 Dec 2013 18:21:41 -0600 Subject: [PATCH 8/8] Fixing up some tests --- dist/js/ionic-angular.js | 4 ++-- js/ext/angular/src/directive/ionicSlideBox.js | 4 ++-- js/ext/angular/test/directive/ionicSlideBox.unit.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index bda9b4ad779..ffc1280cbfe 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -1856,7 +1856,7 @@ angular.module('ionic.ui.slideBox', []) slider.slide(index); }); - $scope.slider = slider; + $scope.slideBox = slider; $timeout(function() { slider.load(); @@ -1913,7 +1913,7 @@ angular.module('ionic.ui.slideBox', []) }; $scope.numSlides = function() { - return new Array($scope.slider.getNumSlides()); + return new Array($scope.slideBox.getNumSlides()); }; $scope.$watch('currentSlide', function(v) { diff --git a/js/ext/angular/src/directive/ionicSlideBox.js b/js/ext/angular/src/directive/ionicSlideBox.js index 18a71f303ef..27ce71fe017 100644 --- a/js/ext/angular/src/directive/ionicSlideBox.js +++ b/js/ext/angular/src/directive/ionicSlideBox.js @@ -59,7 +59,7 @@ angular.module('ionic.ui.slideBox', []) slider.slide(index); }); - $scope.slider = slider; + $scope.slideBox = slider; $timeout(function() { slider.load(); @@ -116,7 +116,7 @@ angular.module('ionic.ui.slideBox', []) }; $scope.numSlides = function() { - return new Array($scope.slider.getNumSlides()); + return new Array($scope.slideBox.getNumSlides()); }; $scope.$watch('currentSlide', function(v) { diff --git a/js/ext/angular/test/directive/ionicSlideBox.unit.js b/js/ext/angular/test/directive/ionicSlideBox.unit.js index 41ce99c06f6..2d91125c20c 100644 --- a/js/ext/angular/test/directive/ionicSlideBox.unit.js +++ b/js/ext/angular/test/directive/ionicSlideBox.unit.js @@ -26,7 +26,7 @@ describe('Ionic Angular Slide Box', function() { })); it('Should init', function() { - var scope = el.scope(); + var scope = el.isolateScope(); expect(scope.slideBox).not.toBe(undefined); }); });