├── .gitignore ├── package.json ├── LICENSE ├── CONTRIBUTING.md ├── lib └── index.js ├── example └── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.swo 3 | *~ 4 | *.log 5 | node_modules 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ascii-heart", 3 | "version": "2.0.0", 4 | "description": "Create ASCII hearts using Node.js.", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+ssh://git@github.com/nuvipannu/ascii-heart.git" 12 | }, 13 | "keywords": [ 14 | "heart", 15 | "ascii", 16 | "text" 17 | ], 18 | "author": "Nuvi Pannu (http://nuvipannu.com)", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/nuvipannu/ascii-heart/issues" 22 | }, 23 | "homepage": "https://github.com/nuvipannu/ascii-heart#readme", 24 | "dependencies": { 25 | "cli-graph": "^3.2.0", 26 | "deffy": "^2.2.1", 27 | "ul": "^5.2.1" 28 | } 29 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Nuvi Pannu (http://nuvipannu.com) 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 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # :eight_spoked_asterisk: :stars: :sparkles: :dizzy: :star2: :star2: :sparkles: :dizzy: :star2: :star2: Contributing :star: :star2: :dizzy: :sparkles: :star: :star2: :dizzy: :sparkles: :stars: :eight_spoked_asterisk: 2 | 3 | So, you want to contribute to this project! That's awesome. However, before 4 | doing so, please read the following simple steps how to contribute. This will 5 | make the life easier and will avoid wasting time on things which are not 6 | requested. :sparkles: 7 | 8 | ## Discuss the changes before doing them 9 | - First of all, open an issue in the repository, using the [bug tracker][1], 10 | describing the contribution you would like to make, the bug you found or any 11 | other ideas you have. This will help us to get you started on the right 12 | foot. 13 | 14 | - If it makes sense, add the platform and software information (e.g. operating 15 | system, Node.JS version etc.), screenshots (so we can see what you are 16 | seeing). 17 | 18 | - It is recommended to wait for feedback before continuing to next steps. 19 | However, if the issue is clear (e.g. a typo) and the fix is simple, you can 20 | continue and fix it. 21 | 22 | ## Fixing issues 23 | - Fork the project in your account and create a branch with your fix: 24 | `some-great-feature` or `some-issue-fix`. 25 | 26 | - Commit your changes in that branch, writing the code following the 27 | [code style][2]. If the project contains tests (generally, the `test` 28 | directory), you are encouraged to add a test as well. :memo: 29 | 30 | - If the project contains a `package.json` or a `bower.json` file add yourself 31 | in the `contributors` array (or `authors` in the case of `bower.json`; 32 | if the array does not exist, create it): 33 | 34 | ```json 35 | { 36 | "contributors": [ 37 | "Your Name (http://your.website)" 38 | ] 39 | } 40 | ``` 41 | 42 | ## Creating a pull request 43 | 44 | - Open a pull request, and reference the initial issue in the pull request 45 | message (e.g. *fixes #*). Write a good description and 46 | title, so everybody will know what is fixed/improved. 47 | 48 | - If it makes sense, add screenshots, gifs etc., so it is easier to see what 49 | is going on. 50 | 51 | ## Wait for feedback 52 | Before accepting your contributions, we will review them. You may get feedback 53 | about what should be fixed in your modified code. If so, just keep committing 54 | in your branch and the pull request will be updated automatically. 55 | 56 | ## Everyone is happy! 57 | Finally, your contributions will be merged, and everyone will be happy! :smile: 58 | Contributions are more than welcome! 59 | 60 | Thanks! :sweat_smile: 61 | 62 | [1]: https://github.com/nuvipannu/ascii-heart/issues 63 | 64 | [2]: https://github.com/IonicaBizau/code-style -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var CliGraph = require("cli-graph") 2 | , deffy = require("deffy") 3 | , ul = require("ul") 4 | ; 5 | 6 | /** 7 | * asciiHeart 8 | * Generates a beautiful heart in ASCII art. :sparkling_heart: 9 | * 10 | * @name asciiHeart 11 | * @function 12 | * @param {Number} width The heart width (default: `40`). 13 | * @param {Number} height The heart height (default: `40`). 14 | * @param {Object} options An object containing the following fields: 15 | * 16 | * - `fill` (String): The character used to fill the heart (default: `" "`). 17 | * - `trim` (Boolean): If `false`, the trailing spaces on the right side will *not* be removed (default: `true`). 18 | * - `k` (Number): A magic number used in the graph generating (default: `100`). 19 | * - `step` (Number): The step precision (default: `0.01`). 20 | * 21 | * @return {String} The stringified heart. 22 | */ 23 | module.exports = function asciiHeart(width, height, options) { 24 | 25 | options = ul.merge(options, { 26 | k: 100 27 | , step: 0.01 28 | , fill: " " 29 | , trim: true 30 | }); 31 | 32 | width = deffy(width, 40); 33 | height = deffy(height, 40); 34 | 35 | var k = options.k 36 | , step = options.step 37 | ; 38 | 39 | // Create the graph 40 | var heart = new CliGraph({ 41 | height: height 42 | , width: width 43 | , marks: { 44 | hAxis: " " 45 | , vAxis: " " 46 | , center: " " 47 | , point: "*" 48 | , topArrow: " " 49 | , rightArrow: " " 50 | } 51 | }); 52 | 53 | var minX = Infinity 54 | , maxX = -Infinity 55 | ; 56 | 57 | // Add points 58 | for (var i = -k; i <= k; i += step) { 59 | var x = (16 * Math.pow(Math.sin(i), 3)) * width / 40 60 | , y = (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i)) * height / 40 61 | ; 62 | 63 | if (minX > x) { 64 | minX = x; 65 | } 66 | 67 | if (maxX < x) { 68 | maxX = x; 69 | } 70 | 71 | heart.addPoint(x, y); 72 | } 73 | 74 | // Start filling the heart 75 | if (options.fill !== " ") { 76 | for (var x = minX + 1; x < maxX; ++x) { 77 | var found = 0; 78 | for (var y = heart.options.center.y - heart.options.height; y < heart.options.height - heart.options.center.y; ++y) { 79 | 80 | if (heart.isPoint(x, y)) { 81 | ++found; 82 | while (heart.isPoint(x, ++y)) {} 83 | } 84 | 85 | if (found === 1) { 86 | debugger 87 | heart.addPoint(x, y, options.fill); 88 | } 89 | } 90 | } 91 | } 92 | 93 | var str = heart.toString(); 94 | 95 | if (options.trim !== false) { 96 | str = str.split("\n").map(function (c) { 97 | return c.trimRight(); 98 | }).filter(Boolean).join("\n"); 99 | } 100 | 101 | return str; 102 | }; 103 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | var asciiHeart = require("../lib"); 2 | 3 | // Default behavior 4 | console.log(asciiHeart()); 5 | // => 6 | // * * * * * * * * * * * * 7 | // * * * * * * * * * * * * 8 | // * * * * * * * * * * 9 | // * * * * * * 10 | // * * * * 11 | // * * * * * * * 12 | // * * * 13 | // * * * 14 | // * * 15 | // * * 16 | // * * 17 | // * * * * 18 | // * * 19 | // * * * * 20 | // * * * * 21 | // * * * * 22 | // * * * * 23 | // * * * * 24 | // * * * * 25 | // * * * * 26 | // * * * * 27 | // * * * * 28 | // * * * * 29 | // * * * * 30 | // * * * * 31 | // * * * * 32 | // * * * * 33 | // * * * 34 | // * 35 | // * 36 | 37 | // Display a small heart (width x height) <3 38 | console.log(asciiHeart(10, 10)); 39 | // => 40 | // * * * * * * 41 | // * * * * * * * 42 | // * * * 43 | // * * * * 44 | // * * * * 45 | // * * * * 46 | // * * * 47 | // * 48 | 49 | // Display a small heart, 50 | console.log(asciiHeart(40, 40, { 51 | fill: "❤" 52 | })); 53 | // => 54 | // * * * * * * * * * * * * 55 | // * * * ❤ ❤ ❤ ❤ * * * * * * ❤ ❤ ❤ ❤ * * * 56 | // * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * 57 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 58 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 59 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 60 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 61 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 62 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 63 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 64 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 65 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 66 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 67 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 68 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 69 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 70 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 71 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 72 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 73 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 74 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 75 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 76 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 77 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 78 | // * * ❤ ❤ ❤ ❤ ❤ * * 79 | // * * ❤ ❤ ❤ * * 80 | // * * ❤ * * 81 | // * * * 82 | // * 83 | // * 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ascii-heart [![Version](https://img.shields.io/npm/v/ascii-heart.svg)](https://www.npmjs.com/package/ascii-heart) [![Downloads](https://img.shields.io/npm/dt/ascii-heart.svg)](https://www.npmjs.com/package/ascii-heart) 2 | 3 | > Create ASCII hearts using Node.js. 4 | 5 | ## Installation 6 | 7 | ```sh 8 | $ npm i --save ascii-heart 9 | ``` 10 | 11 | ## Example 12 | 13 | ```js 14 | var asciiHeart = require("ascii-heart"); 15 | 16 | // Default behavior 17 | console.log(asciiHeart()); 18 | // => 19 | // * * * * * * * * * * * * 20 | // * * * * * * * * * * * * 21 | // * * * * * * * * * * 22 | // * * * * * * 23 | // * * * * 24 | // * * * * * * * 25 | // * * * 26 | // * * * 27 | // * * 28 | // * * 29 | // * * 30 | // * * * * 31 | // * * 32 | // * * * * 33 | // * * * * 34 | // * * * * 35 | // * * * * 36 | // * * * * 37 | // * * * * 38 | // * * * * 39 | // * * * * 40 | // * * * * 41 | // * * * * 42 | // * * * * 43 | // * * * * 44 | // * * * * 45 | // * * * * 46 | // * * * 47 | // * 48 | // * 49 | 50 | // Display a small heart (width x height) <3 51 | console.log(asciiHeart(10, 10)); 52 | // => 53 | // * * * * * * 54 | // * * * * * * * 55 | // * * * 56 | // * * * * 57 | // * * * * 58 | // * * * * 59 | // * * * 60 | // * 61 | 62 | // Display a small heart, 63 | console.log(asciiHeart(40, 40, { 64 | fill: "❤" 65 | })); 66 | // => 67 | // * * * * * * * * * * * * 68 | // * * * ❤ ❤ ❤ ❤ * * * * * * ❤ ❤ ❤ ❤ * * * 69 | // * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * 70 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 71 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 72 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 73 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 74 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 75 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 76 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 77 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 78 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 79 | // * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * 80 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 81 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 82 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 83 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 84 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 85 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 86 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 87 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 88 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 89 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 90 | // * * ❤ ❤ ❤ ❤ ❤ ❤ ❤ * * 91 | // * * ❤ ❤ ❤ ❤ ❤ * * 92 | // * * ❤ ❤ ❤ * * 93 | // * * ❤ * * 94 | // * * * 95 | // * 96 | // * 97 | ``` 98 | 99 | ## Documentation 100 | 101 | ### `asciiHeart(width, height, options)` 102 | Generates a beautiful heart in ASCII art. :sparkling_heart: 103 | 104 | #### Params 105 | - **Number** `width`: The heart width (default: `40`). 106 | - **Number** `height`: The heart height (default: `40`). 107 | - **Object** `options`: An object containing the following fields: 108 | - `fill` (String): The character used to fill the heart (default: `" "`). 109 | - `trim` (Boolean): If `false`, the trailing spaces on the right side will *not* be removed (default: `true`). 110 | - `k` (Number): A magic number used in the graph generating (default: `100`). 111 | - `step` (Number): The step precision (default: `0.01`). 112 | 113 | #### Return 114 | - **String** The stringified heart. 115 | 116 | ## How to contribute 117 | Have an idea? Found a bug? See [how to contribute][contributing]. 118 | 119 | ## Where is this library used? 120 | If you are using this library in one of your projects, add it in this list. :sparkles: 121 | 122 | ## License 123 | 124 | [MIT][license] © [Nuvi Pannu][website] 125 | 126 | [license]: http://showalicense.com/?fullname=Nuvi%20Pannu%20%3Cnuvipannu%40gmail.com%3E%20(http%3A%2F%2Fnuvipannu.com)&year=2016#license-mit 127 | [website]: http://nuvipannu.com 128 | [contributing]: /CONTRIBUTING.md 129 | [docs]: /DOCUMENTATION.md --------------------------------------------------------------------------------