├── .gitattributes ├── .gitignore ├── circle.yml ├── .editorconfig ├── test.js ├── package.json ├── LICENSE ├── index.js └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 4 4 | 5 | test: 6 | override: 7 | - nvm use 4 && npm test 8 | - nvm use 5 && npm test 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | indent_size = 2 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var Hinata = require('./') 2 | 3 | var hinata = new Hinata() 4 | 5 | hinata.start() 6 | 7 | setTimeout(function () { 8 | hinata.text = 'loading lodash' 9 | }, 2000) 10 | 11 | setTimeout(function () { 12 | hinata.char = '❤' 13 | hinata.spacing = 2 14 | hinata.text = 'loading react' 15 | }, 4000) 16 | 17 | setTimeout(function () { 18 | hinata.text = 'loading webpack' 19 | }, 6000) 20 | 21 | setTimeout(function () { 22 | hinata.text = 'loading lunch' 23 | }, 8000) 24 | 25 | setTimeout(function () { 26 | hinata.stop() 27 | }, 10000) 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hinata", 3 | "version": "0.1.0", 4 | "description": "Your cli spinner which like a marquee.", 5 | "license": "MIT", 6 | "repository": "egoist/hinata", 7 | "author": { 8 | "name": "EGOIST", 9 | "email": "0x142857@gmail.com", 10 | "url": "github.com/egoist" 11 | }, 12 | "engines": { 13 | "node": ">=4" 14 | }, 15 | "scripts": { 16 | "test": "xo && node test" 17 | }, 18 | "files": [ 19 | "index.js" 20 | ], 21 | "keywords": [ 22 | "spinner", 23 | "loading", 24 | "marquee" 25 | ], 26 | "dependencies": { 27 | "chalk": "^1.1.1" 28 | }, 29 | "devDependencies": { 30 | "xo": "^0.12.1" 31 | }, 32 | "xo": { 33 | "semicolon": false, 34 | "space": true 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) EGOIST <0x142857@gmail.com> (github.com/egoist) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | var chalk = require('chalk') 3 | 4 | function randomColor(text) { 5 | var colors = [ 6 | 'red', 7 | 'green', 8 | 'yellow', 9 | 'blue', 10 | 'magenta', 11 | 'bold' 12 | ] 13 | var color = colors[Math.round(Math.random() * (colors.length - 1))] 14 | return chalk[color](text) 15 | } 16 | 17 | function replaceCharAt(str, index, value) { 18 | return str.substr(0, index) + value + str.substr(index + 1) 19 | } 20 | 21 | function Hinata(opts) { 22 | opts = opts || {} 23 | this.text = opts.text || '' 24 | this.char = opts.char || '.' 25 | this.length = opts.length || 3 26 | this.color = opts.color 27 | this.spacing = opts.spacing || 0 28 | this.timeout = opts.timeout || 100 29 | this.prepend = opts.prepend 30 | this.stream = process.stdout 31 | } 32 | 33 | Hinata.prototype.start = function () { 34 | var index = 0 35 | this.loop = setInterval(function () { 36 | var dots = this.char.repeat(this.length) 37 | var replaceDot = this.color ? chalk[this.color] : randomColor(this.char) 38 | dots = replaceCharAt(dots, index, replaceDot) 39 | dots = dots.split(this.char).join(this.char + ' '.repeat(this.spacing)) 40 | var text = this.prepend ? this.text + dots : dots + this.text 41 | this.stream.clearLine() 42 | this.stream.write('\r' + text) 43 | if (index === this.length - 1) { 44 | index = 0 45 | } else { 46 | index++ 47 | } 48 | }.bind(this), this.timeout) 49 | } 50 | 51 | Hinata.prototype.stop = function () { 52 | clearInterval(this.loop) 53 | this.stream.clearLine() 54 | this.stream.cursorTo(0) 55 | this.loop = null 56 | } 57 | 58 | module.exports = Hinata 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hinata [![NPM version](https://img.shields.io/npm/v/hinata.svg)](https://npmjs.com/package/hinata) [![NPM downloads](https://img.shields.io/npm/dm/hinata.svg)](https://npmjs.com/package/hinata) [![Build Status](https://img.shields.io/circleci/project/egoist/hinata/master.svg)](https://circleci.com/gh/egoist/hinata) 2 | 3 | > Your cli spinner which like a marquee. 4 | 5 | ![gif](http://ooo.0o0.ooo/2016/03/03/56d90169c39f1.gif) 6 | 7 | ## Install 8 | 9 | ```js 10 | $ npm install --save hinata 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```js 16 | const Hinata = require('hinata') 17 | 18 | const hinata = new Hinata({char: '❤', spacing: 2}) 19 | 20 | hinata.start() 21 | 22 | setTimeout(() => { 23 | // update loading text 24 | hinata.text = 'loading something' 25 | }, 2000) 26 | 27 | setTimeout(() => { 28 | // update loading character 29 | hinata.char = '.' 30 | // update character spacing 31 | hinata.spacing = 0 32 | }, 3000) 33 | 34 | setTimeout(() => { 35 | hinata.stop() 36 | }, 10000) 37 | ``` 38 | 39 | ## API 40 | 41 | ### new Hinata([options]) 42 | 43 | #### options 44 | 45 | **text** 46 | 47 | default `''` 48 | 49 | Placeholder for loading text, eg: `Loading` in `Loading ...` 50 | 51 | **char** 52 | 53 | default `.` 54 | 55 | Loading character, eg: `❤` in `❤ ❤ ❤ loading webpack` 56 | 57 | **length** 58 | 59 | default `3` 60 | 61 | How many time a loading character should repeat itself. 62 | 63 | **color** 64 | 65 | default `false` 66 | 67 | If set to be true, spinner uses your color instead of a random color. 68 | 69 | **spacing** 70 | 71 | default `0` 72 | 73 | How many spaces between each loading character. 74 | 75 | **timeout** 76 | 77 | default `100` 78 | 79 | The timeout to update the spinner. 80 | 81 | **prepend** 82 | 83 | default `false` 84 | 85 | Show loading text at the beginning of the spinner. 86 | 87 | ## Related 88 | 89 | - [io-spin](https://github.com/egoist/io-spin): Cli spinner made simple. 90 | 91 | ## License 92 | 93 | MIT © [EGOIST](https://github.com/egoist) 94 | --------------------------------------------------------------------------------