47 | ...`,
48 | })
49 | export class AwesomeComponent {
50 | }
51 | ```
52 |
53 |
54 | ## Attributes
55 |
56 | **scrollTo** *required*
57 |
58 | **scrollTargetSelector** *string* Element target for scroll.
59 |
60 | **href** *string* Element target for scroll.
61 |
62 | **scrollYTarget** *number* Y axis target for scroll.
63 |
64 | **scrollableElementSelector** *string* Scrollable element selector. Sometimes there are multiple scrollable elements in your page; through this attribute you may specify the element you want to scroll.
65 |
66 | **scrollOffSet** *number* Top offset to compensate for negative top margins.
67 |
--------------------------------------------------------------------------------
/compiled/index.ngfactory.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview This file is generated by the Angular 2 template compiler.
3 | * Do not edit.
4 | * @suppress {suspiciousCode,uselessCode,missingProperties}
5 | */
6 | /* tslint:disable */
7 |
8 | import * as import0 from '@angular/core/src/linker/ng_module_factory';
9 | import * as import1 from '../index';
10 | import * as import2 from '@angular/common/src/common_module';
11 | import * as import3 from '@angular/common/src/localization';
12 | import * as import4 from '@angular/core/src/di/injector';
13 | import * as import5 from '@angular/core/src/i18n/tokens';
14 | class ScrollToModuleInjector extends import0.NgModuleInjector
{
15 | _CommonModule_0:import2.CommonModule;
16 | _ScrollToModule_1:import1.ScrollToModule;
17 | __NgLocalization_2:import3.NgLocaleLocalization;
18 | constructor(parent:import4.Injector) {
19 | super(parent,([] as any[]),([] as any[]));
20 | }
21 | get _NgLocalization_2():import3.NgLocaleLocalization {
22 | if ((this.__NgLocalization_2 == null)) { (this.__NgLocalization_2 = new import3.NgLocaleLocalization(this.parent.get(import5.LOCALE_ID))); }
23 | return this.__NgLocalization_2;
24 | }
25 | createInternal():import1.ScrollToModule {
26 | this._CommonModule_0 = new import2.CommonModule();
27 | this._ScrollToModule_1 = new import1.ScrollToModule();
28 | return this._ScrollToModule_1;
29 | }
30 | getInternal(token:any,notFoundResult:any):any {
31 | if ((token === import2.CommonModule)) { return this._CommonModule_0; }
32 | if ((token === import1.ScrollToModule)) { return this._ScrollToModule_1; }
33 | if ((token === import3.NgLocalization)) { return this._NgLocalization_2; }
34 | return notFoundResult;
35 | }
36 | destroyInternal():void {
37 | }
38 | }
39 | export const ScrollToModuleNgFactory:import0.NgModuleFactory = new import0.NgModuleFactory(ScrollToModuleInjector,import1.ScrollToModule);
--------------------------------------------------------------------------------
/compiled/index.ngsummary.json:
--------------------------------------------------------------------------------
1 | {"summaries":[{"symbol":{"__symbol":0},"metadata":{"__symbolic":"class","statics":{"forRoot":{"__symbolic":"function","parameters":[],"value":{"ngModule":{"__symbol":0}}}}},"type":{"summaryKind":2,"type":{"reference":{"__symbol":0},"diDeps":[],"lifecycleHooks":[]},"entryComponents":[],"providers":[{"provider":{"token":{"identifier":{"reference":{"__symbol":3}}},"useClass":{"reference":{"__symbol":4},"diDeps":[{"isAttribute":false,"isHost":false,"isSelf":false,"isSkipSelf":false,"isOptional":false,"token":{"identifier":{"reference":{"__symbol":5}}}}],"lifecycleHooks":[]},"useFactory":null,"useExisting":null,"deps":[{"isAttribute":false,"isHost":false,"isSelf":false,"isSkipSelf":false,"isOptional":false,"token":{"identifier":{"reference":{"__symbol":5}}}}],"multi":false},"module":{"reference":{"__symbol":6},"diDeps":[],"lifecycleHooks":[]}}],"modules":[{"reference":{"__symbol":6},"diDeps":[],"lifecycleHooks":[]},{"reference":{"__symbol":0},"diDeps":[],"lifecycleHooks":[]}],"exportedDirectives":[{"reference":{"__symbol":2}}],"exportedPipes":[]}},{"symbol":{"__symbol":1},"metadata":{"__symbol":2}}],"symbols":[{"__symbol":0,"name":"ScrollToModule","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/index.d.ts"},{"__symbol":1,"name":"ScrollTo","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/index.d.ts"},{"__symbol":2,"name":"ScrollTo","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/src/scrollTo.d.ts"},{"__symbol":3,"name":"NgLocalization","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/node_modules/@angular/common/src/localization.d.ts"},{"__symbol":4,"name":"NgLocaleLocalization","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/node_modules/@angular/common/src/localization.d.ts"},{"__symbol":5,"name":"LOCALE_ID","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/node_modules/@angular/core/src/i18n/tokens.d.ts"},{"__symbol":6,"name":"CommonModule","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/node_modules/@angular/common/src/common_module.d.ts"}]}
--------------------------------------------------------------------------------
/compiled/src/scrollTo.ngfactory.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileoverview This file is generated by the Angular 2 template compiler.
3 | * Do not edit.
4 | * @suppress {suspiciousCode,uselessCode,missingProperties}
5 | */
6 | /* tslint:disable */
7 |
8 | import * as import0 from '../../src/scrollTo';
9 | import * as import1 from '@angular/core/src/change_detection/change_detection_util';
10 | import * as import2 from '@angular/core/src/linker/view';
11 | import * as import3 from '@angular/core/src/linker/view_utils';
12 | export class Wrapper_ScrollTo {
13 | /*private*/ _eventHandler:Function;
14 | context:import0.ScrollTo;
15 | /*private*/ _changed:boolean;
16 | /*private*/ _expr_0:any;
17 | /*private*/ _expr_1:any;
18 | /*private*/ _expr_2:any;
19 | constructor(p0:any) {
20 | this._changed = false;
21 | this.context = new import0.ScrollTo(p0);
22 | this._expr_0 = import1.UNINITIALIZED;
23 | this._expr_1 = import1.UNINITIALIZED;
24 | this._expr_2 = import1.UNINITIALIZED;
25 | }
26 | ngOnDetach(view:import2.AppView,componentView:import2.AppView,el:any):void {
27 | }
28 | ngOnDestroy():void {
29 | }
30 | check_scrollableElementSelector(currValue:any,throwOnChange:boolean,forceUpdate:boolean):void {
31 | if ((forceUpdate || import3.checkBinding(throwOnChange,this._expr_0,currValue))) {
32 | this._changed = true;
33 | this.context.scrollableElementSelector = currValue;
34 | this._expr_0 = currValue;
35 | }
36 | }
37 | check_scrollTargetSelector(currValue:any,throwOnChange:boolean,forceUpdate:boolean):void {
38 | if ((forceUpdate || import3.checkBinding(throwOnChange,this._expr_1,currValue))) {
39 | this._changed = true;
40 | this.context.scrollTargetSelector = currValue;
41 | this._expr_1 = currValue;
42 | }
43 | }
44 | check_scrollYTarget(currValue:any,throwOnChange:boolean,forceUpdate:boolean):void {
45 | if ((forceUpdate || import3.checkBinding(throwOnChange,this._expr_2,currValue))) {
46 | this._changed = true;
47 | this.context.scrollYTarget = currValue;
48 | this._expr_2 = currValue;
49 | }
50 | }
51 | ngDoCheck(view:import2.AppView,el:any,throwOnChange:boolean):boolean {
52 | var changed:any = this._changed;
53 | this._changed = false;
54 | return changed;
55 | }
56 | checkHost(view:import2.AppView,componentView:import2.AppView,el:any,throwOnChange:boolean):void {
57 | }
58 | handleEvent(eventName:string,$event:any):boolean {
59 | var result:boolean = true;
60 | if ((eventName == 'click')) {
61 | const pd_sub_0:any = ((this.context.onClick($event)) !== false);
62 | result = (pd_sub_0 && result);
63 | }
64 | return result;
65 | }
66 | subscribe(view:import2.AppView,_eventHandler:any):void {
67 | this._eventHandler = _eventHandler;
68 | }
69 | }
--------------------------------------------------------------------------------
/compiled/src/scrollTo.ngsummary.json:
--------------------------------------------------------------------------------
1 | {"summaries":[{"symbol":{"__symbol":0},"metadata":{"__symbolic":"class"},"type":{"summaryKind":1,"type":{"reference":{"__symbol":0},"diDeps":[{"isAttribute":false,"isHost":false,"isSelf":false,"isSkipSelf":false,"isOptional":false,"token":{"identifier":{"reference":{"__symbol":1}}}}],"lifecycleHooks":[]},"isComponent":false,"selector":"[scrollTo]","inputs":{"scrollableElementSelector":"scrollableElementSelector","scrollTargetSelector":"scrollTargetSelector","scrollYTarget":"scrollYTarget"},"outputs":{},"hostListeners":{"click":"onClick($event)"},"hostProperties":{},"hostAttributes":{},"providers":[],"viewProviders":[],"queries":[],"entryComponents":[],"changeDetection":null,"template":null}}],"symbols":[{"__symbol":0,"name":"ScrollTo","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/src/scrollTo.d.ts"},{"__symbol":1,"name":"ElementRef","filePath":"/home/drusso/ts_workspace/ng2-scroll-to/node_modules/@angular/core/src/linker/element_ref.d.ts"}]}
--------------------------------------------------------------------------------
/index.metadata.json:
--------------------------------------------------------------------------------
1 | [{"__symbolic":"module","version":3,"metadata":{"ScrollToModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule"},"arguments":[{"imports":[{"__symbolic":"reference","module":"@angular/common","name":"CommonModule"}],"declarations":[{"__symbolic":"reference","module":"./src/scrollTo","name":"ScrollTo"}],"exports":[{"__symbolic":"reference","module":"./src/scrollTo","name":"ScrollTo"}]}]}],"statics":{"forRoot":{"__symbolic":"function","parameters":[],"value":{"ngModule":{"__symbolic":"reference","name":"ScrollToModule"}}}}}},"exports":[{"from":"./src/scrollTo","export":["ScrollTo"]},{"from":"./src/scrollTo"}]},{"__symbolic":"module","version":1,"metadata":{"ScrollToModule":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"NgModule"},"arguments":[{"imports":[{"__symbolic":"reference","module":"@angular/common","name":"CommonModule"}],"declarations":[{"__symbolic":"reference","module":"./src/scrollTo","name":"ScrollTo"}],"exports":[{"__symbolic":"reference","module":"./src/scrollTo","name":"ScrollTo"}]}]}],"statics":{"forRoot":{"__symbolic":"function","parameters":[],"value":{"ngModule":{"__symbolic":"reference","name":"ScrollToModule"}}}}}},"exports":[{"from":"./src/scrollTo","export":["ScrollTo"]},{"from":"./src/scrollTo"}]}]
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | export {ScrollTo} from './src/scrollTo';
2 |
3 | import { NgModule, ModuleWithProviders } from '@angular/core';
4 | import { CommonModule } from '@angular/common';
5 | // import { SampleComponent } from './src/sample.component';
6 | // import { SampleDirective } from './src/sample.directive';
7 | // import { SamplePipe } from './src/sample.pipe';
8 | import { ScrollTo } from './src/scrollTo';
9 |
10 | // export * from './src/sample.component';
11 | // export * from './src/sample.directive';
12 | // export * from './src/sample.pipe';
13 | export * from './src/scrollTo';
14 |
15 | @NgModule({
16 | imports: [
17 | CommonModule
18 | ],
19 | declarations: [
20 | ScrollTo,
21 | ],
22 | exports: [
23 | ScrollTo,
24 | ]
25 | })
26 | export class ScrollToModule {
27 | static forRoot(): ModuleWithProviders {
28 | return {
29 | ngModule: ScrollToModule
30 | };
31 | }
32 | }
--------------------------------------------------------------------------------
/package.bk.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng2-scroll-to",
3 | "version": "1.0.3",
4 | "description": "angular 2 library to animate scrolling.",
5 | "main": "./dist/ng2-scroll-to.js",
6 | "module": "./ng2-scroll-to.js",
7 | "scripts": {
8 | "build": "ngc -p tsconfig.json",
9 | "lint": "tslint --type-check --project tsconfig.json src/**/*.ts",
10 | "test": "tsc && karma start",
11 | "prepublish": "npm run build",
12 | "tsc": "tsc"
13 | },
14 | "typings": "./ng2-scroll-to.d.ts",
15 | "keywords": [
16 | "smooth",
17 | "scroll",
18 | "smoothScroll",
19 | "angular 2",
20 | "angular2",
21 | "scrollTo",
22 | "scrollTop"
23 | ],
24 | "author": "drusso85",
25 | "license": "MIT",
26 | "dependencies": {},
27 | "devDependencies": {
28 | "@angular/core": "^2.4.0",
29 | "@angular/common": "^2.4.0",
30 | "@types/core-js": "^0.9.34",
31 | "rxjs": "^5.0.0-beta.12",
32 | "typescript": "^2.0.9",
33 | "zone.js": "0.7.2",
34 | "@angular/compiler": "^2.4.5",
35 | "@angular/compiler-cli": "^2.4.5",
36 | "@angular/platform-browser": "^2.4.5",
37 | "@angular/platform-server": "^2.4.5",
38 | "codelyzer": "^3.0.0-beta.0",
39 | "tslint": "^4.5.1",
40 | "@types/es6-shim": "^0.31.32",
41 | "@types/jasmine": "^2.5.40",
42 | "@types/selenium-webdriver": "^2.53.39"
43 | },
44 | "repository": {
45 | "type": "git",
46 | "url": "git+https://github.com/drusso85/ng2-scroll-to"
47 | }
48 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng2-scroll-to",
3 | "version": "1.0.7",
4 | "description": "angular 2 library to animate scrolling.",
5 | "scripts": {
6 | "build": "ngc -p tsconfig.json",
7 | "lint": "tslint --type-check --project tsconfig.json src/**/*.ts",
8 | "test": "tsc && karma start",
9 | "prepublish": "npm run clean && npm run build",
10 | "cleanRoot":"rm -f ./*js ./*.js.map ./*.d.ts ./*.metadata.json 2> /dev/null",
11 | "cleanSrc":"rm -f ./src/*js ./src/*.js.map ./src/*.d.ts ./src/*.metadata.json 2> /dev/null",
12 | "clean":"npm run cleanRoot && npm run cleanSrc",
13 | "tsc": "tsc"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/drusso85/ng2-scroll-to"
18 | },
19 | "author": "drusso85",
20 | "keywords": [
21 | "smooth",
22 | "scroll",
23 | "smoothScroll",
24 | "angular 2",
25 | "angular2",
26 | "scrollTo",
27 | "scrollTop"
28 | ],
29 | "license": "MIT",
30 | "main": "./index.js",
31 | "dependencies": {},
32 | "peerDependencies": {
33 | "@angular/core": "^2.4.0",
34 | "@angular/common": "^2.4.0",
35 | "@angular/compiler": "^2.4.5",
36 | "@angular/platform-browser": "^2.4.5",
37 | "@angular/router": "^3.2.0",
38 | "rxjs": "^5.0.1",
39 | "zone.js": "^0.7.2"
40 | },
41 | "devDependencies": {
42 | "@angular/core": "^2.4.0",
43 | "@angular/common": "^2.4.0",
44 | "@angular/compiler": "^2.4.5",
45 | "@angular/compiler-cli": "^2.4.5",
46 | "@angular/platform-browser": "^2.4.5",
47 | "@angular/platform-server": "^2.4.5",
48 | "codelyzer": "^3.0.0-beta.0",
49 | "rxjs": "^5.0.1",
50 | "tslint": "^4.5.1",
51 | "typescript": "^2.0.2",
52 | "zone.js": "0.7.2",
53 | "@types/es6-shim": "^0.31.32",
54 | "@types/jasmine": "^2.5.40",
55 | "@types/selenium-webdriver": "^2.53.39"
56 | },
57 | "engines": {
58 | "node": ">=0.8.0"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/scrollTo.metadata.json:
--------------------------------------------------------------------------------
1 | [{"__symbolic":"module","version":3,"metadata":{"ScrollTo":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Directive"},"arguments":[{"selector":"[scrollTo]"}]}],"members":{"scrollableElementSelector":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"scrollTargetSelector":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"scrollYTarget":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef"}]}],"onClick":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["click",["$event"]]}]}],"getScrollableElement":[{"__symbolic":"method"}],"getTarget":[{"__symbolic":"method"}],"smoothScroll":[{"__symbolic":"method"}],"easeInOutCubic":[{"__symbolic":"method"}],"position":[{"__symbolic":"method"}],"findScrollableParent":[{"__symbolic":"method"}],"findMainScrollableElement":[{"__symbolic":"method"}],"isScrollable":[{"__symbolic":"method"}],"isScriptTag":[{"__symbolic":"method"}],"findScrollableChild":[{"__symbolic":"method"}]}}}},{"__symbolic":"module","version":1,"metadata":{"ScrollTo":{"__symbolic":"class","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Directive"},"arguments":[{"selector":"[scrollTo]"}]}],"members":{"scrollableElementSelector":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"scrollTargetSelector":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"scrollYTarget":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Input"}}]}],"__ctor__":[{"__symbolic":"constructor","parameters":[{"__symbolic":"reference","module":"@angular/core","name":"ElementRef"}]}],"onClick":[{"__symbolic":"method","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"HostListener"},"arguments":["click",["$event"]]}]}],"getScrollableElement":[{"__symbolic":"method"}],"getTarget":[{"__symbolic":"method"}],"smoothScroll":[{"__symbolic":"method"}],"easeInOutCubic":[{"__symbolic":"method"}],"position":[{"__symbolic":"method"}],"findScrollableParent":[{"__symbolic":"method"}],"findMainScrollableElement":[{"__symbolic":"method"}],"isScrollable":[{"__symbolic":"method"}],"isScriptTag":[{"__symbolic":"method"}],"findScrollableChild":[{"__symbolic":"method"}]}}}}]
--------------------------------------------------------------------------------
/src/scrollTo.ts:
--------------------------------------------------------------------------------
1 | import { Directive, ElementRef, Input, HostListener } from '@angular/core';
2 | @Directive({
3 | selector: '[scrollTo]'
4 | })
5 | export class ScrollTo {
6 | @Input() scrollableElementSelector: string;
7 | @Input() scrollTargetSelector: string;
8 | @Input() scrollYTarget: number;
9 | @Input() scrollOffSet: number;
10 |
11 | constructor(private el: ElementRef) { }
12 | @HostListener('click', ['$event']) onClick(event: MouseEvent) {
13 | event.preventDefault();
14 | let scrollEnd: number;
15 | if (this.scrollYTarget) {
16 | if (isNaN(Number(this.scrollYTarget))) {
17 | throw 'scrollYTarget must have numerical values';
18 | }
19 | scrollEnd = this.scrollYTarget;
20 | }
21 | let target: HTMLElement;
22 | if (scrollEnd == null) {
23 | target = this.getTarget();
24 | if (!target) {
25 | console.warn('target element do not exist');
26 | return;
27 | }
28 | scrollEnd = target.offsetTop;
29 | }
30 | let scrollingElement: HTMLElement = this.getScrollableElement(target);
31 | try {
32 | if (scrollingElement === document.body) {
33 | this.smoothScroll(document.documentElement, scrollEnd);
34 | }
35 | } catch (e) { console.warn(e) }
36 |
37 | this.smoothScroll(scrollingElement, scrollEnd);
38 | }
39 |
40 | private getScrollableElement(target: HTMLElement): HTMLElement {
41 | let scrollableElement: HTMLElement;
42 | if (this.scrollableElementSelector) {
43 | scrollableElement = document.querySelector(this.scrollableElementSelector);
44 | } else if (target != null) {
45 | scrollableElement = this.findScrollableParent(target);
46 | } else {
47 | scrollableElement = this.findMainScrollableElement();
48 | }
49 | return scrollableElement;
50 | }
51 |
52 | private getTarget(): HTMLElement {
53 | let target: HTMLElement;
54 | if (this.scrollTargetSelector) {
55 | target = document.querySelector(this.scrollTargetSelector);
56 | } else if (this.el.nativeElement.href) {
57 | let href: string = '#' + this.el.nativeElement.href.split('#')[1];
58 | target = document.querySelector(href);
59 | }
60 | return target;
61 | }
62 |
63 | private smoothScroll(element: HTMLElement, end: number): void {
64 | const duration = 500;
65 | const clock: number = Date.now();
66 | const requestAnimationFrame = window.requestAnimationFrame || function (fn) {
67 | window.setTimeout(fn, 15);
68 | };
69 | let offset:number = 0;
70 | if (this.scrollOffSet) {
71 | if (isNaN(Number(this.scrollOffSet))) {
72 | throw 'scrollOffSet must have numerical values';
73 | }
74 | end -= this.scrollOffSet;
75 | }
76 | const start: number = element.scrollTop;
77 | let step = () => {
78 | let elapsed = Date.now() - clock;
79 | let position = this.position(start, end, elapsed, duration);
80 | element.scrollTop = position;
81 | if (elapsed > duration) {
82 | } else {
83 | requestAnimationFrame(step);
84 | }
85 | };
86 | step();
87 | }
88 |
89 | // ease in out function thanks to:
90 | // http://blog.greweb.fr/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation/
91 | easeInOutCubic(t: number): number {
92 | return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
93 | }
94 | /**
95 | * calculate the scroll position we should be in
96 | * given the start and end point of the scroll
97 | * the time elapsed from the beginning of the scroll
98 | * and the total duration of the scroll (default 500ms)
99 | */
100 | private position(start: number, end: number, elapsed: number, duration: number): number {
101 | if (elapsed > duration) {
102 | return end;
103 | };
104 | return start + (end - start) * this.easeInOutCubic(elapsed / duration); // <-- you can change the easing funtion there
105 | // return start + (end - start) * (elapsed / duration); // <-- this would give a linear scroll
106 | }
107 |
108 |
109 | /**
110 | * finds scrollable parent of an element
111 | * @method findScrollableParent
112 | * @param {HTMLElement} element
113 | * @returns {HTMLElement} element
114 | */
115 | private findScrollableParent(element: HTMLElement): HTMLElement {
116 | let isBody: boolean,
117 | hasScrollableSpace: boolean,
118 | hasVisibleOverflow: boolean;
119 | do {
120 | element = element.parentElement;
121 | // set condition variables
122 | isBody = element === document.body;
123 | hasScrollableSpace = element.clientHeight < element.scrollHeight;
124 | hasVisibleOverflow = getComputedStyle(element, null).overflow === 'visible';
125 | } while (!isBody && !(hasScrollableSpace && !hasVisibleOverflow));
126 | return element;
127 | }
128 |
129 |
130 | /**
131 | * finds scrollable parent of an element
132 | * @method findMainScrollableElement
133 | * @returns {HTMLElement} element
134 | */
135 | private findMainScrollableElement(): HTMLElement {
136 | let element: HTMLElement = this.findScrollableChild(document.body);
137 | if (element != null) {
138 | return element;
139 | }
140 | return document.body;
141 | }
142 |
143 | private isScrollable(element: HTMLElement): boolean {
144 | let hasScrollableSpace = element.clientHeight < element.scrollHeight;
145 | let hasVisibleOverflow = getComputedStyle(element, null).overflow === 'visible';
146 | return hasScrollableSpace && !hasVisibleOverflow;
147 | }
148 |
149 | private isScriptTag(element: HTMLElement): boolean {
150 | return element.nodeName === 'SCRIPT';
151 | }
152 |
153 | private findScrollableChild(inputElement: HTMLElement): HTMLElement {
154 | let scrollableElement: HTMLElement;
155 | let i = 0;
156 | if (this.isScriptTag(inputElement)) {
157 | return null;
158 | }
159 | while (scrollableElement == null && i < inputElement.childElementCount) {
160 | let element = inputElement.children[i];
161 | if (this.isScrollable(element)) {
162 | scrollableElement = element;
163 | return element;
164 | }
165 | scrollableElement = this.findScrollableChild(element);
166 | i++;
167 | }
168 | return scrollableElement;
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "noImplicitAny": true,
4 | "module": "commonjs",
5 | "target": "ES5",
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowUnusedLabels": false,
9 | "noImplicitReturns": true,
10 | "sourceMap": true,
11 | "declaration": true,
12 | "typeRoots": [
13 | "node_modules/@types"
14 | ]
15 | },
16 | "exclude": [
17 | "node_modules",
18 | "dist",
19 | "**/*.spec.ts"
20 | ],
21 | "angularCompilerOptions": {
22 | "strictMetadataEmit": true,
23 | "genDir": "compiled"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "class-name": true,
7 | "comment-format": [
8 | true,
9 | "check-space"
10 | ],
11 | "curly": true,
12 | "eofline": true,
13 | "forin": true,
14 | "indent": [
15 | true,
16 | "spaces"
17 | ],
18 | "label-position": true,
19 | "max-line-length": [
20 | true,
21 | 140
22 | ],
23 | "member-access": false,
24 | "member-ordering": [
25 | true,
26 | "static-before-instance",
27 | "variables-before-functions"
28 | ],
29 | "no-arg": true,
30 | "no-bitwise": true,
31 | "no-console": [
32 | true,
33 | "debug",
34 | "info",
35 | "time",
36 | "timeEnd",
37 | "trace"
38 | ],
39 | "no-construct": true,
40 | "no-debugger": true,
41 | "no-duplicate-variable": true,
42 | "no-empty": false,
43 | "no-eval": true,
44 | "no-inferrable-types": true,
45 | "no-shadowed-variable": true,
46 | "no-string-literal": false,
47 | "no-switch-case-fall-through": true,
48 | "no-trailing-whitespace": true,
49 | "no-unused-expression": true,
50 | "no-unused-variable": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": false,
54 | "one-line": [
55 | true,
56 | "check-open-brace",
57 | "check-catch",
58 | "check-else",
59 | "check-whitespace"
60 | ],
61 | "quotemark": [
62 | true,
63 | "single"
64 | ],
65 | "radix": true,
66 | "semicolon": [
67 | "always"
68 | ],
69 | "triple-equals": [
70 | true,
71 | "allow-null-check"
72 | ],
73 | "typedef-whitespace": [
74 | true,
75 | {
76 | "call-signature": "nospace",
77 | "index-signature": "nospace",
78 | "parameter": "nospace",
79 | "property-declaration": "nospace",
80 | "variable-declaration": "nospace"
81 | }
82 | ],
83 | "variable-name": false,
84 | "whitespace": [
85 | true,
86 | "check-branch",
87 | "check-decl",
88 | "check-operator",
89 | "check-separator",
90 | "check-type"
91 | ],
92 | "directive-selector": [true, "attribute", "", "camelCase"],
93 | "component-selector": [true, "element", "", "kebab-case"],
94 | "use-input-property-decorator": true,
95 | "use-output-property-decorator": true,
96 | "use-host-property-decorator": true,
97 | "no-input-rename": true,
98 | "no-output-rename": true,
99 | "use-life-cycle-interface": true,
100 | "use-pipe-transform-interface": true,
101 | "component-class-suffix": true,
102 | "directive-class-suffix": true
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/typings.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/drusso85/ng2-scroll-to/89b6e696dcca987b8e8fb39c694db0e5b81ed2f5/typings.json
--------------------------------------------------------------------------------