39 |
40 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng-scrollbar",
3 | "version": "0.0.8",
4 | "main": "dist/ng-scrollbar.min.js",
5 | "description": "A custom scrollbar written in pure AngularJS",
6 | "keywords": [
7 | "angular",
8 | "angularjs",
9 | "scrollbar"
10 | ],
11 | "homepage": "https://github.com/asafdav/ng-scrollbar",
12 | "bugs": "https://github.com/asafdav/ng-scrollbar/issues",
13 | "author": {
14 | "name": "Asaf David",
15 | "email": "asafdav@gmail.com",
16 | "url": "http://about.me/asafdavid"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "https://github.com/asafdav/ng-scrollbar.git"
21 | },
22 | "licenses": [
23 | {
24 | "type": "MIT"
25 | }
26 | ],
27 | "devDependencies": {
28 | "grunt": "~0.4.1",
29 | "grunt-contrib-jshint": "~0.6.4",
30 | "grunt-contrib-concat": "~0.3.0",
31 | "grunt-contrib-uglify": "~0.2.4",
32 | "grunt-contrib-watch": "~0.5.3",
33 | "grunt-contrib-clean": "~0.5.0",
34 | "grunt-contrib-connect": "~0.5.0",
35 | "grunt-contrib-less": "~0.9.0",
36 | "grunt-contrib-cssmin": "~0.7.0",
37 | "connect-livereload": "~0.3.0",
38 | "grunt-open": "~0.2.2",
39 | "grunt-karma": "~0.6.2",
40 | "grunt-ngmin": "0.0.3",
41 | "grunt-bump": "0.0.11",
42 | "matchdep": "~0.1.2",
43 | "karma-script-launcher": "~0.1.0",
44 | "karma-chrome-launcher": "~0.1.0",
45 | "karma-firefox-launcher": "~0.1.0",
46 | "karma-html2js-preprocessor": "~0.1.0",
47 | "karma-jasmine": "~0.1.3",
48 | "karma-requirejs": "~0.2.0",
49 | "karma-coffee-preprocessor": "~0.1.0",
50 | "karma-phantomjs-launcher": "~0.1.0",
51 | "karma": "~0.10.2"
52 | },
53 | "dependencies": {
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 |
3 |
4 |
5 | module.exports = function(config) {
6 | config.set({
7 | // base path, that will be used to resolve files and exclude
8 | basePath: '',
9 |
10 | // list of files / patterns to load in the browser
11 | files: [
12 | 'bower_components/jquery/dist/jquery.js',
13 | 'bower_components/angular/angular.js',
14 | 'bower_components/angular-mocks/angular-mocks.js',
15 | 'src/*.js',
16 | 'test/spec/*.js'
17 | ],
18 |
19 | // list of files to exclude
20 | exclude: [],
21 |
22 | // test results reporter to use
23 | // possible values: dots || progress || growl
24 | reporters: ['progress'],
25 |
26 | frameworks: ['jasmine'],
27 |
28 | // web server port
29 | port: 8080,
30 |
31 | // cli runner port
32 | runnerPort: 9100,
33 |
34 | // enable / disable colors in the output (reporters and logs)
35 | colors: true,
36 |
37 | // level of logging
38 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
39 | logLevel: config.LOG_INFO,
40 |
41 | // enable / disable watching file and executing tests whenever any file changes
42 | autoWatch: false,
43 |
44 | // Start these browsers, currently available:
45 | // - Chrome
46 | // - ChromeCanary
47 | // - Firefox
48 | // - Opera
49 | // - Safari (only Mac)
50 | // - PhantomJS
51 | // - IE (only Windows)
52 | browsers: ['Chrome'],
53 |
54 | // If browser does not capture in given timeout [ms], kill it
55 | captureTimeout: 5000,
56 |
57 | // Continuous Integration mode
58 | // if true, it capture browsers, run tests and exit
59 | singleRun: false
60 |
61 | });
62 | };
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## Important notes
4 | Please don't edit files in the `dist` subdirectory as they are generated via Grunt. You'll find source code in the `src` subdirectory!
5 |
6 | ### Code style
7 | Regarding code style like indentation and whitespace, **follow the conventions you see used in the source already.**
8 |
9 | ### PhantomJS
10 | While Grunt can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `test/*.html` unit test file(s) in _actual_ browsers.
11 |
12 | ## Modifying the code
13 | First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed.
14 |
15 | Test that Grunt's CLI and Bower are installed by running `grunt --version` and `bower --version`. If the commands aren't found, run `npm install -g grunt-cli bower`. For more information about installing the tools, see the [getting started with Grunt guide](http://gruntjs.com/getting-started) or [bower.io](http://bower.io/) respectively.
16 |
17 | 1. Fork and clone the repo.
18 | 1. Run `npm install` to install all build dependencies (including Grunt).
19 | 1. Run `bower install` to install the front-end dependencies.
20 | 1. Run `grunt` to grunt this project.
21 |
22 | Assuming that you don't see any red, you're ready to go. Just be sure to run `grunt` after making any changes, to ensure that nothing is broken.
23 |
24 | ## Submitting pull requests
25 |
26 | 1. Create a new branch, please don't work in your `master` branch directly.
27 | 1. Add failing tests for the change you want to make. Run `grunt` to see the tests fail.
28 | 1. Fix stuff.
29 | 1. Run `grunt` to see if the tests pass. Repeat steps 2-4 until done.
30 | 1. Open `test/*.html` unit test file(s) in actual browser to ensure tests pass everywhere.
31 | 1. Update the documentation to reflect any changes.
32 | 1. Push to your fork and submit a pull request.
33 |
--------------------------------------------------------------------------------
/dist/ng-scrollbar.css:
--------------------------------------------------------------------------------
1 | .ngsb-wrap {
2 | -ms-touch-action: none;
3 | }
4 | .ngsb-wrap .ngsb-container {
5 | width: auto;
6 | overflow: hidden;
7 | transition: 0.5s all;
8 | }
9 | .ngsb-wrap:hover .ngsb-scrollbar {
10 | opacity: 1;
11 | filter: "alpha(opacity=100)";
12 | -ms-filter: "alpha(opacity=100)";
13 | /* old ie */
14 | }
15 | .ngsb-wrap .ngsb-scrollbar {
16 | width: 16px;
17 | height: 100%;
18 | top: 0;
19 | right: 0;
20 | opacity: 0.75;
21 | filter: "alpha(opacity=75)";
22 | -ms-filter: "alpha(opacity=75)";
23 | /* old ie */
24 | }
25 | .ngsb-wrap .ngsb-scrollbar .ngsb-thumb-container {
26 | position: absolute;
27 | top: 0;
28 | left: 0;
29 | bottom: 0;
30 | right: 0;
31 | height: auto;
32 | }
33 | .ngsb-wrap .ngsb-scrollbar a.ngsb-thumb-container {
34 | margin: 20px 0;
35 | }
36 | .ngsb-wrap .ngsb-scrollbar .ngsb-track {
37 | height: 100%;
38 | margin: 0 auto;
39 | width: 6px;
40 | background: #000;
41 | background: rgba(0, 0, 0, 0.4);
42 | -webkit-border-radius: 2px;
43 | -moz-border-radius: 2px;
44 | border-radius: 2px;
45 | filter: "alpha(opacity=40)";
46 | -ms-filter: "alpha(opacity=40)";
47 | /* old ie */
48 | box-shadow: 1px 1px 1px rgba(255, 255, 255, 0.1);
49 | }
50 | .ngsb-wrap .ngsb-scrollbar .ngsb-thumb-pos {
51 | cursor: pointer;
52 | width: 100%;
53 | height: 30px;
54 | }
55 | .ngsb-wrap .ngsb-scrollbar .ngsb-thumb-pos .ngsb-thumb {
56 | transition: 0.5s all;
57 | width: 4px;
58 | height: 100%;
59 | margin: 0 auto;
60 | -webkit-border-radius: 10px;
61 | -moz-border-radius: 10px;
62 | border-radius: 10px;
63 | text-align: center;
64 | background: #fff;
65 | /* rgba fallback */
66 | background: rgba(255, 255, 255, 0.4);
67 | filter: "alpha(opacity=40)";
68 | -ms-filter: "alpha(opacity=40)";
69 | /* old ie */
70 | }
71 | .ngsb-wrap .ngsb-scrollbar .ngsb-thumb-pos:hover .ngsb-thumb {
72 | background: rgba(255, 255, 255, 0.5);
73 | filter: "alpha(opacity=50)";
74 | -ms-filter: "alpha(opacity=50)";
75 | /* old ie */
76 | }
77 | .ngsb-wrap .ngsb-scrollbar .ngsb-thumb-pos:active {
78 | background: rgba(255, 255, 255, 0.6);
79 | filter: "alpha(opacity=60)";
80 | -ms-filter: "alpha(opacity=60)";
81 | /* old ie */
82 | }
83 |
--------------------------------------------------------------------------------
/src/ng-scrollbar.less:
--------------------------------------------------------------------------------
1 | .ngsb-wrap {
2 | -ms-touch-action:none;
3 |
4 | .ngsb-container{
5 | width:auto;
6 | overflow:hidden;
7 | transition: 0.5s all;
8 | }
9 |
10 | &:hover {
11 | .ngsb-scrollbar {
12 | opacity:1;
13 | filter:"alpha(opacity=100)"; -ms-filter:"alpha(opacity=100)"; /* old ie */
14 | }
15 | }
16 |
17 | .ngsb-scrollbar {
18 | width:16px;
19 | height:100%;
20 | top:0;
21 | right:0;
22 | opacity:0.75;
23 | filter:"alpha(opacity=75)"; -ms-filter:"alpha(opacity=75)"; /* old ie */
24 |
25 | .ngsb-thumb-container{
26 | position:absolute;
27 | top:0;
28 | left:0;
29 | bottom:0;
30 | right:0;
31 | height:auto;
32 | }
33 |
34 | a+ {
35 | &.ngsb-thumb-container{
36 | margin:20px 0;
37 | }
38 | }
39 |
40 | .ngsb-track{
41 | height:100%;
42 | margin:0 auto;
43 | width:6px;
44 | background: #000;
45 | background: rgba(0, 0, 0, 0.4);
46 | -webkit-border-radius:2px;
47 | -moz-border-radius:2px;
48 | border-radius:2px;
49 | filter:"alpha(opacity=40)"; -ms-filter:"alpha(opacity=40)"; /* old ie */
50 | box-shadow:1px 1px 1px rgba(255,255,255,0.1);
51 | }
52 |
53 | .ngsb-thumb-pos {
54 | cursor:pointer;
55 | width:100%;
56 | height:30px;
57 |
58 | .ngsb-thumb {
59 | transition: 0.5s all;
60 | width:4px;
61 | height:100%;
62 | margin:0 auto;
63 | -webkit-border-radius:10px;
64 | -moz-border-radius:10px;
65 | border-radius:10px;
66 | text-align:center;
67 | background:#fff; /* rgba fallback */
68 | background:rgba(255,255,255,0.4);
69 | filter:"alpha(opacity=40)";
70 | -ms-filter:"alpha(opacity=40)"; /* old ie */
71 | }
72 |
73 | &:hover {
74 | .ngsb-thumb {
75 | background:rgba(255,255,255,0.5);
76 | filter:"alpha(opacity=50)";
77 | -ms-filter:"alpha(opacity=50)"; /* old ie */
78 | }
79 | }
80 |
81 | &:active {
82 | background:rgba(255,255,255,0.6);
83 | filter:"alpha(opacity=60)"; -ms-filter:"alpha(opacity=60)"; /* old ie */
84 | }
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ng-scrollbar
2 | A custom scrollbar written in pure AngularJS.
3 |
4 | Works with the mouse and on touch screen.
5 |
6 | Tired of using jquery for a stupid scrollbar? well, this directive is just for you.
7 |
8 |
9 | ## Usage
10 |
11 | 1. Add ng-scrollbar.min.js to you main file (index.html)
12 |
13 | you can download this by:
14 | * using bower and running `bower install ng-scrollbar`
15 | * Download the [production version][min] or the [development version][max].
16 |
17 | [min]: https://raw.github.com/asafdav/ng-scrollbar/master/dist/angular-ng-scrollbar.min.js
18 | [max]: https://raw.github.com/asafdav/ng-scrollbar/master/dist/angular-ng-scrollbar.js
19 |
20 | In your web page:
21 |
22 | ```html
23 |
24 |
25 |
26 | ```
27 |
28 | 2. Set `ngScrollbar` as a dependency in your module
29 | ```javascript
30 | var myapp = angular.module('myapp', ['ngScrollbar'])
31 | ```
32 |
33 | 3. Add ng-scrollbar directive to the wanted element, example:
34 | ```html
35 |
....
36 | ```
37 |
38 | ## Rebuild the scrollbar
39 | In case you need to rebuild the scrollbar, you may tell ng-scrollbar to rebuild it for you by broadcasting an event.
40 | It's useful to use this option when the size or visibility of the container is dynamic and during the link phase the size can't be determined.
41 | ```html
42 |
....
43 | ```
44 |
45 | ```javascript
46 | // rebuild the scrollbar
47 | $scope.$broadcast('rebuild:me');
48 | ```
49 |
50 | In case you need to rebuild the scrollbar on every window's resize, you may use "rebuild-on-resize" option.
51 | ```html
52 |
....
53 | ```
54 |
55 | In case you need to stick content to bottom (chat or something) use "bottom" option.
56 | ```html
57 |
....
58 | ```
59 |
60 | ## Events and Flags
61 | On rebuilding the scrollbar you can get notified by 2 events
62 | ```javascript
63 | $scope.$on('scrollbar.show', function(){
64 | console.log('Scrollbar show');
65 | });
66 | $scope.$on('scrollbar.hide', function(){
67 | console.log('Scrollbar hide');
68 | });
69 | ```
70 |
71 | Or you can use "is-bar-shown" option. It should be read-only
72 | ```html
73 |