diff --git a/ionic/components/scroll/scroll.ts b/ionic/components/scroll/scroll.ts index d030a91a2c..97c974d168 100644 --- a/ionic/components/scroll/scroll.ts +++ b/ionic/components/scroll/scroll.ts @@ -16,7 +16,7 @@ import * as util from 'ionic/util'; @IonicComponent({ selector: 'ion-scroll', properties: [ - 'scrollX', 'scrollY', 'zoom', 'maxZoom' + 'scrollX', 'scrollY' ], host: { '[class.scroll-x]': 'scrollX', @@ -34,208 +34,10 @@ export class Scroll extends Ion { */ constructor(elementRef: ElementRef, ionicConfig: IonicConfig) { super(elementRef, ionicConfig); - - this.maxScale = 3; - this.zoomDuration = 250; } onInit() { this.scrollElement = this.getNativeElement().children[0]; - - if(util.isTrueProperty(this.zoom)) { - this.initZoomScrolling(); - } - } - - resetZoom() { - - if(this.zoomElement) { - - this.zoomElement.parentElement.style[CSS.transform] = ''; - this.zoomElement.style[CSS.transform] = 'scale(1)'; - } - - this.scale = 1; - this.zoomLastPosX = 0; - this.zoomLastPosY = 0; - } - - initZoomScrolling() { - this.zoomElement = this.scrollElement.children[0].children[0]; - - this.zoomElement && this.zoomElement.classList.add('ion-scroll-zoom'); - - this.scrollElement.addEventListener('scroll', (e) => { - console.log("Scrolling", e); - }); - - this.zoomGesture = new Gesture(this.scrollElement); - this.zoomGesture.listen(); - - this.scale = 1; - - this.zoomLastPosX = 0; - this.zoomLastPosY = 0; - - - let last_scale, deltaX, deltaY, startX, startY, posX = 0, posY = 0, zoomRect, viewportWidth, viewportHeight; - - viewportWidth = this.scrollElement.offsetWidth; - viewportHeight = this.scrollElement.offsetWidth; - - this.zoomElement.addEventListener('touchstart', (e) => { - startX = e.touches[0].clientX; - startY = e.touches[0].clientY; - }); - - this.zoomElement.addEventListener('touchmove', (e) => { - deltaX = e.touches[0].clientX - startX; - deltaY = e.touches[0].clientY - startY; - - if(this.scale > 1) { - console.log('PAN', e); - - // Move image - posX = deltaX + this.zoomLastPosX; - posY = deltaY + this.zoomLastPosY; - - console.log(posX, posY); - - - if(posX > viewportWidth) { - // Too far on the left side, let the event bubble up (to enable slider on edges, for example) - } else if(-posX > viewportWidth) { - // Too far on the right side, let the event bubble up (to enable slider on edges, for example) - } else { - console.log('TRANSFORM', posX); - this.zoomElement.parentElement.style[CSS.transform] = 'translateX(' + posX + 'px) translateY(' + posY + 'px)'; - e.preventDefault(); - e.stopPropagation(); - return false; - } - - } - }); - - this.zoomElement.addEventListener('touchend', (e) => { - console.log('PANEND', e); - - if(this.scale > 1) { - - if(Math.abs(posX) > viewportWidth) { - posX = posX > 0 ? viewportWidth - 1 : -(viewportWidth - 1); - console.log('Setting on posx', posX); - } - - if(posY > viewportHeight/2) { - let z = new Animation(this.zoomElement.parentElement); - z.fromTo('translateY', posY + 'px', Math.min(viewportHeight/2 + 30, posY)); - z.play(); - } else { - let z = new Animation(this.zoomElement.parentElement); - z.fromTo('translateY', posY + 'px', Math.max(viewportHeight/2 - 30, posY)); - z.play(); - } - - this.zoomLastPosX = posX; - this.zoomLastPosY = posY; - } - }); - - this.zoomGesture.on('pinchstart', (e) => { - last_scale = this.scale; - console.log('Last scale', e.scale); - }); - - this.zoomGesture.on('pinch', (e) => { - this.scale = Math.max(1, Math.min(last_scale * e.scale, 10)); - console.log('Scaling', this.scale); - this.zoomElement.style[CSS.transform] = 'scale(' + this.scale + ')' - - zoomRect = this.zoomElement.getBoundingClientRect(); - }); - - this.zoomGesture.on('pinchend', (e) => { - //last_scale = Math.max(1, Math.min(last_scale * e.scale, 10)); - if(this.scale > this.maxScale) { - let za = new Animation(this.zoomElement) - .duration(this.zoomDuration) - .easing('linear') - .from('scale', this.scale) - .to('scale', this.maxScale); - za.play(); - - this.scale = this.maxScale; - } - }); - - this.zoomGesture.on('doubletap', (e) => { - console.log('Double'); - - let x = e.pointers[0].clientX; - let y = e.pointers[0].clientY; - - let mx = viewportWidth / 2; - let my = viewportHeight / 2; - - let tx, ty; - - if(x > mx) { - // Greater than half - tx = -x; - } else { - // Less than or equal to half - tx = (viewportWidth - x); - } - if(y > my) { - ty = -y; - } else { - ty = y-my; - } - - console.log(y); - - let zi = new Animation(this.zoomElement) - .duration(this.zoomDuration) - .easing('linear'); - let zw = new Animation(this.zoomElement.parentElement) - .duration(this.zoomDuration) - .easing('linear'); - - let za = new Animation(); - za.add(zi);//, zw); - - if(this.scale > 1) { - // Zoom out - - //zw.fromTo('translateX', posX + 'px', '0px'); - //zw.fromTo('translateY', posY + 'px', '0px'); - - zi.from('scale', this.scale); - zi.to('scale', 1); - za.play(); - - posX = 0; - posY = 0; - - this.scale = 1; - } else { - // Zoom in - - //zw.fromTo('translateX', posX + 'px', tx + 'px'); - //zw.fromTo('translateY', posY + 'px', ty + 'px'); - - zi.from('scale', this.scale); - zi.to('scale', this.maxScale); - za.play(); - - posX = tx; - posY = ty; - - this.scale = this.maxScale; - } - //this.zoomElement.style[CSS.transform] = 'scale(3)'; - }); } /** diff --git a/ionic/components/slides/slides.ts b/ionic/components/slides/slides.ts index d25f2debea..2301105876 100644 --- a/ionic/components/slides/slides.ts +++ b/ionic/components/slides/slides.ts @@ -37,7 +37,9 @@ import {Scroll} from '../scroll/scroll'; 'bounce', 'showPager', 'options', - 'zoom' + 'zoom', + 'zoomDuration', + 'zoomMax' ] }) @View({ @@ -59,11 +61,6 @@ export class Slides extends Ion { super(elementRef, config); } onInit() { - - if(util.isTrueProperty(this.zoom)) { - this.enableZoom = true; - } - var options = util.defaults({ pagination: '.swiper-pagination', paginationClickable: true, @@ -75,6 +72,10 @@ export class Slides extends Ion { this.onTap(swiper, e); return this.options.onTap && this.options.onTap(swiper, e); }; + options.onClick = (swiper, e) => { + this.onClick(swiper, e); + return this.options.onClick && this.options.onClick(swiper, e); + }; options.onDoubleTap = (swiper, e) => { this.onDoubleTap(swiper, e); return this.options.onDoubleTap && this.options.onDoubleTap(swiper, e); @@ -105,19 +106,24 @@ export class Slides extends Ion { var swiper = new Swiper(this.getNativeElement().children[0], options); this.swiper = swiper; + + if(util.isTrueProperty(this.zoom)) { + this.enableZoom = true; + this.initZoom(); + } + } onTap(swiper, e) { console.log('Slide tap', swiper, e); } + onClick(swiper, e) { + console.log('Slide click', swiper, e); + } onDoubleTap(swiper, e) { console.log('Slide double tap', swiper, e); - } - onTransitionStart(swiper) { - console.log('Slide transition start', swiper); - } - onTransitionEnd(swiper) { - console.log('Slide transition end', swiper); + + this.toggleZoom(swiper, e); } onLazyImageLoad(swiper, slide, img) { console.log('Slide lazy load', swiper, slide, img); @@ -138,9 +144,209 @@ export class Slides extends Ion { } */ - initZoomScrolling() { + initZoom() { + this.zoomDuration = this.zoomDuration || 230; + this.maxScale = this.zoomMax || 3; + + this.zoomElement = this.getNativeElement().children[0].children[0]; + console.log('Zooming', this.zoomElement); + + this.zoomElement && this.zoomElement.classList.add('ion-scroll-zoom'); + + console.log(this.swiper.slides); + + this.zoomGesture = new Gesture(this.zoomElement); + this.zoomGesture.listen(); + + this.scale = 1; + + this.zoomLastPosX = 0; + this.zoomLastPosY = 0; + + + let last_scale, deltaX, deltaY, startX, startY, posX = 0, posY = 0, zoomRect; + + this.viewportWidth = this.getNativeElement().offsetWidth; + this.viewportHeight = this.getNativeElement().offsetHeight; + + this.zoomElement.addEventListener('touchstart', (e) => { + startX = e.touches[0].clientX; + startY = e.touches[0].clientY; + }); + + this.zoomElement.addEventListener('touchmove', (e) => { + deltaX = e.touches[0].clientX - startX; + deltaY = e.touches[0].clientY - startY; + + if(this.scale > 1) { + console.log('PAN', e); + + // Move image + posX = deltaX + this.zoomLastPosX; + posY = deltaY + this.zoomLastPosY; + + console.log(posX, posY); + + + if(posX > this.viewportWidth) { + // Too far on the left side, let the event bubble up (to enable slider on edges, for example) + } else if(-posX > this.viewportWidth) { + // Too far on the right side, let the event bubble up (to enable slider on edges, for example) + } else { + console.log('TRANSFORM', posX); + this.zoomElement.parentElement.style[CSS.transform] = 'translateX(' + posX + 'px) translateY(' + posY + 'px)'; + e.preventDefault(); + e.stopPropagation(); + return false; + } + + } + }); + + this.zoomElement.addEventListener('touchend', (e) => { + console.log('PANEND', e); + + if(this.scale > 1) { + + if(Math.abs(posX) > this.viewportWidth) { + posX = posX > 0 ? this.viewportWidth - 1 : -(this.viewportWidth - 1); + console.log('Setting on posx', posX); + } + + if(posY > this.viewportHeight/2) { + let z = new Animation(this.zoomElement.parentElement); + z.fromTo('translateY', posY + 'px', Math.min(this.viewportHeight/2 + 30, posY)); + z.play(); + } else { + let z = new Animation(this.zoomElement.parentElement); + z.fromTo('translateY', posY + 'px', Math.max(this.viewportHeight/2 - 30, posY)); + z.play(); + } + + this.zoomLastPosX = posX; + this.zoomLastPosY = posY; + } + }); + + this.zoomGesture.on('pinchstart', (e) => { + last_scale = this.scale; + console.log('Last scale', e.scale); + }); + + this.zoomGesture.on('pinch', (e) => { + this.scale = Math.max(1, Math.min(last_scale * e.scale, 10)); + console.log('Scaling', this.scale); + this.zoomElement.style[CSS.transform] = 'scale(' + this.scale + ')' + + zoomRect = this.zoomElement.getBoundingClientRect(); + }); + + this.zoomGesture.on('pinchend', (e) => { + //last_scale = Math.max(1, Math.min(last_scale * e.scale, 10)); + if(this.scale > this.maxScale) { + let za = new Animation(this.zoomElement) + .duration(this.zoomDuration) + .easing('linear') + .from('scale', this.scale) + .to('scale', this.maxScale); + za.play(); + + this.scale = this.maxScale; + } + }); } + resetZoom() { + + if(this.zoomElement) { + + this.zoomElement.parentElement.style[CSS.transform] = ''; + this.zoomElement.style[CSS.transform] = 'scale(1)'; + } + + this.scale = 1; + this.zoomLastPosX = 0; + this.zoomLastPosY = 0; + } + + toggleZoom(swiper, e) { + if(!this.enableZoom) { return; } + + console.log('Toggling zoom', e); + + /* + let x = e.pointers[0].clientX; + let y = e.pointers[0].clientY; + + let mx = this.viewportWidth / 2; + let my = this.viewportHeight / 2; + + let tx, ty; + + if(x > mx) { + // Greater than half + tx = -x; + } else { + // Less than or equal to half + tx = (this.viewportWidth - x); + } + if(y > my) { + ty = -y; + } else { + ty = y-my; + } + + console.log(y); + */ + + let zi = new Animation(this.zoomElement) + .duration(this.zoomDuration) + .easing('linear'); + let zw = new Animation(this.zoomElement.parentElement) + .duration(this.zoomDuration) + .easing('linear'); + + let za = new Animation(); + za.add(zi);//, zw); + + if(this.scale > 1) { + // Zoom out + + //zw.fromTo('translateX', posX + 'px', '0px'); + //zw.fromTo('translateY', posY + 'px', '0px'); + + zi.from('scale', this.scale); + zi.to('scale', 1); + za.play(); + + //posX = 0; + //posY = 0; + + this.scale = 1; + } else { + // Zoom in + + //zw.fromTo('translateX', posX + 'px', tx + 'px'); + //zw.fromTo('translateY', posY + 'px', ty + 'px'); + + zi.from('scale', this.scale); + zi.to('scale', this.maxScale); + za.play(); + + //posX = tx; + //posY = ty; + + this.scale = this.maxScale; + } + } + onTransitionStart(swiper) { + console.log('Slide transition start', swiper); + } + onTransitionEnd(swiper) { + console.log('Slide transition end', swiper); + } + + /** * Update the underlying slider implementation. Call this if you've added or removed * child slides.