├── .editorconfig
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── bs-config.json
├── example
├── app
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ └── app.module.ts
├── index.html
├── main.ts
├── styles.css
└── tsconfig.json
├── index.ts
├── package.json
├── src
├── counto.directive.ts
└── counto.module.ts
├── tests
└── .gitkeep
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 |
7 | [*.{ts,json}]
8 | charset = utf-8
9 | indent_style = space
10 | indent_size = 4
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | node_modules
3 | *.js
4 | *.js.map
5 | *.d.ts
6 | package-lock.json
7 | *.metadata.json
8 | *.ngsummary.json
9 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *~
2 | node_modules
3 | *.ts
4 | !*.d.ts
5 | package-lock.json
6 | *.ngFactory.ts
7 | *.ngsummary.json
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Igor Zupet
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular2-counto
2 |
3 | Angular 5 package for nice count animations
4 |
5 | ## Installation
6 | ```
7 | npm install angular2-counto --save
8 | ```
9 |
10 | ### SystemJS
11 | ```
12 | var map = {
13 | 'angular2-counto': 'node_modules/angular2-counto/src'
14 | };
15 |
16 | var packages = {
17 | 'angular2-counto': { main: 'counto.module.js', defaultExtension: 'js' }
18 | };
19 | ```
20 |
21 | ### Angular-CLI
22 | Just import module as below:
23 |
24 |
25 | ```
26 | import { NgModule } from '@angular/core';
27 | import { BrowserModule } from '@angular/platform-browser';
28 | import { CountoModule } from 'angular2-counto';
29 |
30 | @NgModule({
31 | imports: [ BrowserModule, CountoModule ],
32 | declarations: [ AppComponent ],
33 | bootstrap: [ AppComponent ]
34 | })
35 | export class AppModule { }
36 | ```
37 |
38 | Example with currency pipe:
39 | ```
40 |
{{counto | currency:'EUR':'symbol':'1.2-2'}}
41 | ```
42 |
43 | ## Usage
44 |
45 | | Parameter | Required | Unit | Description |
46 | | ------------- | ------------- | ------------- | --------------------------------------- |
47 | | step | yes | milisecond | How fast counter is updated |
48 | | countTo | yes | number | Any start number |
49 | | countFrom | yes | number | Any end number |
50 | | duration | yes | seconds | Duration of animation |
51 |
52 | Any of above parameters can be freely binded to an event. Every time parameter changes, animation will be executed.
53 | You can use any pipe you want to modify output to your needs.
54 |
55 | ## Demo
56 |
57 | http://izupet.github.io/angular2-counto
58 |
--------------------------------------------------------------------------------
/bs-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server": {
3 | "baseDir": "example",
4 | "routes": {
5 | "/node_modules": "node_modules",
6 | "/src": "src"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { AppComponent } from './app.component';
2 |
3 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
4 | import { By } from '@angular/platform-browser';
5 | import { DebugElement } from '@angular/core';
6 |
7 | describe('AppComponent', function () {
8 | let de: DebugElement;
9 | let comp: AppComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [ AppComponent ]
15 | })
16 | .compileComponents();
17 | }));
18 |
19 | beforeEach(() => {
20 | fixture = TestBed.createComponent(AppComponent);
21 | comp = fixture.componentInstance;
22 | de = fixture.debugElement.query(By.css('h1'));
23 | });
24 |
25 | it('should create component', () => expect(comp).toBeDefined() );
26 |
27 | it('should have expected text', () => {
28 | fixture.detectChanges();
29 | const h1 = de.nativeElement;
30 | expect(h1.innerText).toMatch(/angular/i,
31 | ' should say something about "Angular"');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/example/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'my-app',
5 | template: `
{{intermediate | currency:'EUR':'symbol':'1.2-2'}}
`,
6 | })
7 | export class AppComponent {
8 |
9 | onCountoEnd(): void {
10 | console.log('counto end');
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/example/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { BrowserModule } from '@angular/platform-browser';
3 | import { CountoModule } from 'angular2-counto';
4 | import { AppComponent } from './app.component';
5 |
6 | @NgModule({
7 | imports: [ BrowserModule, CountoModule ],
8 | declarations: [ AppComponent ],
9 | bootstrap: [ AppComponent ]
10 | })
11 | export class AppModule { }
12 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Counto Example
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 | Loading...
19 |
20 |
21 |
--------------------------------------------------------------------------------
/example/main.ts:
--------------------------------------------------------------------------------
1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2 |
3 | import { AppModule } from './app/app.module';
4 |
5 | platformBrowserDynamic().bootstrapModule(AppModule);
6 |
--------------------------------------------------------------------------------
/example/styles.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/izupet/angular2-counto/9b467b5774fe2a189fc646e60baf2cdfc91a65f2/example/styles.css
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "emitDecoratorMetadata": true,
8 | "experimentalDecorators": true,
9 | "lib": [ "es2015", "dom" ],
10 | "noImplicitAny": true,
11 | "suppressImplicitAnyIndexErrors": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/index.ts:
--------------------------------------------------------------------------------
1 | import { CountoDirective } from './src/counto.directive';
2 | import { CountoModule } from './src/counto.module';
3 |
4 | export { CountoDirective, CountoModule };
5 | export default CountoModule;
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular2-counto",
3 | "version": "1.2.5",
4 | "description": "Awesome angular package for counting animations.",
5 | "main": "index.js",
6 | "directories": {
7 | "test": "tests"
8 | },
9 | "scripts": {
10 | "build": "ngc",
11 | "build:example": "ngc -p example/",
12 | "lite": "lite-server",
13 | "serve": "concurrently \"npm run build\" \"npm run build:example\" \"npm run lite\" "
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/izupet/angular2-counto.git"
18 | },
19 | "dependencies": {},
20 | "keywords": [
21 | "angular",
22 | "count",
23 | "animation",
24 | "awesome"
25 | ],
26 | "author": "Igor Zupet",
27 | "license": "MIT",
28 | "bugs": {
29 | "url": "https://github.com/izupet/angular2-counto/issues"
30 | },
31 | "devDependencies": {
32 | "@angular/common": "^5.1.0",
33 | "@angular/compiler": "^5.1.0",
34 | "@angular/compiler-cli": "^5.1.0",
35 | "@angular/core": "^5.1.0",
36 | "@angular/forms": "^5.1.0",
37 | "@angular/http": "^5.1.0",
38 | "@angular/platform-browser": "^5.1.0",
39 | "@angular/platform-browser-dynamic": "^5.1.0",
40 | "@types/node": "~6.0.60",
41 | "concurrently": "^3.5.1",
42 | "core-js": "^2.4.1",
43 | "jasmine-core": "~2.8.0",
44 | "lite-server": "^2.3.0",
45 | "rxjs": "^5.5.6",
46 | "systemjs": "0.21.0",
47 | "typescript": "~2.5.3",
48 | "zone.js": "^0.8.19"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/counto.directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, Output, EventEmitter } from '@angular/core';
2 |
3 | @Directive({
4 | selector: '[counto]'
5 | })
6 |
7 | export class CountoDirective {
8 |
9 | @Output() countoChange = new EventEmitter();
10 | @Output() countoEnd = new EventEmitter();
11 | private _timer: any;
12 | private _duration: number;
13 | private _countTo: number;
14 | private _countFrom: number;
15 | private _step: number;
16 |
17 | @Input()
18 | set duration(duration: string) {
19 | this._duration = parseFloat(duration);
20 | this.run();
21 | }
22 |
23 | @Input()
24 | set countTo(countTo: string) {
25 | this._countTo = parseFloat(countTo);
26 | this.run();
27 | }
28 |
29 | @Input()
30 | set countFrom(countFrom: string) {
31 | this._countFrom = parseFloat(countFrom);
32 | this.run();
33 | }
34 |
35 | @Input()
36 | set step(step: string) {
37 | this._step = parseFloat(step);
38 | this.run();
39 | }
40 |
41 | run() {
42 | var _this = this;
43 | clearInterval(_this._timer);
44 |
45 | if (isNaN(_this._duration)) {
46 | return false;
47 | }
48 |
49 | if (isNaN(_this._step)) {
50 | return false;
51 | }
52 |
53 | if (isNaN(_this._countFrom)) {
54 | return false;
55 | }
56 |
57 | if (isNaN(_this._countTo)) {
58 | return false;
59 | }
60 |
61 | if (_this._step <= 0) {
62 | console.info('Step must be greater than 0.');
63 | return false;
64 | }
65 |
66 | if (_this._duration <= 0) {
67 | console.info('Duration must be greater than 0.');
68 | return false;
69 | }
70 |
71 | if (_this._step > _this._duration*1000) {
72 | console.info('Step must be equal or smaller than duration.');
73 | return false;
74 | }
75 |
76 | var intermediate = _this._countFrom;
77 | var increment = Math.abs(_this._countTo - _this._countFrom) / ((_this._duration * 1000) / _this._step);
78 |
79 | _this.countoChange.emit(intermediate);
80 |
81 | _this._timer = setInterval(function() {
82 | if (_this._countTo < _this._countFrom) {
83 | if (intermediate <= _this._countTo) {
84 | clearInterval(_this._timer);
85 | _this.countoChange.emit(_this._countTo);
86 | _this.countoEnd.emit();
87 | } else {
88 | _this.countoChange.emit(intermediate);
89 | intermediate -= increment;
90 | }
91 | } else {
92 | if (intermediate >= _this._countTo) {
93 | clearInterval(_this._timer);
94 | _this.countoChange.emit(_this._countTo);
95 | _this.countoEnd.emit();
96 | } else {
97 | _this.countoChange.emit(intermediate);
98 | intermediate += increment;
99 | }
100 | }
101 | }, _this._step);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/counto.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { CountoDirective } from './counto.directive';
3 |
4 | @NgModule({
5 | declarations: [ CountoDirective ],
6 | exports: [ CountoDirective ]
7 | })
8 | export class CountoModule {}
9 |
--------------------------------------------------------------------------------
/tests/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/izupet/angular2-counto/9b467b5774fe2a189fc646e60baf2cdfc91a65f2/tests/.gitkeep
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "sourceMap": true,
7 | "inlineSources": true,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "lib": [ "es2015", "dom" ],
11 | "noImplicitAny": true,
12 | "suppressImplicitAnyIndexErrors": true,
13 | "declaration": true
14 | },
15 | "angularCompilerOptions": {
16 | "fullTemplateTypeCheck": true,
17 | "preserveWhiteSpaces": false,
18 | "strictMetadataEmit" : true
19 | },
20 | "exclude": [
21 | "node_modules",
22 | "example",
23 | "tests"
24 | ],
25 | "include": [
26 | "index.ts",
27 | "src/*"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------