{"id":18953403,"url":"https://github.com/kreshikhin/clumsy","last_synced_at":"2025-04-16T02:32:16.370Z","repository":{"id":57200941,"uuid":"42242504","full_name":"kreshikhin/clumsy","owner":"kreshikhin","description":"A library written on node.js for creating math figures on HTMLCanvas in XKCD style.","archived":false,"fork":false,"pushed_at":"2016-08-29T20:23:12.000Z","size":759,"stargazers_count":112,"open_issues_count":1,"forks_count":9,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-10-31T19:49:33.494Z","etag":null,"topics":["animation","axis","canvas","drawing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kreshikhin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-09-10T12:14:57.000Z","updated_at":"2023-06-27T02:24:37.000Z","dependencies_parsed_at":"2022-09-16T15:12:21.712Z","dependency_job_id":null,"html_url":"https://github.com/kreshikhin/clumsy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kreshikhin%2Fclumsy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kreshikhin%2Fclumsy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kreshikhin%2Fclumsy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kreshikhin%2Fclumsy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kreshikhin","download_url":"https://codeload.github.com/kreshikhin/clumsy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223692944,"owners_count":17187100,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","axis","canvas","drawing"],"created_at":"2024-11-08T13:38:25.560Z","updated_at":"2024-11-08T13:38:26.240Z","avatar_url":"https://github.com/kreshikhin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Clumsy\n\n  [![NPM Version][npm-image]][npm-url]\n  [![NPM Downloads][downloads-image]][downloads-url]\n  [![Build Status][travis-image]][travis-url]\n\n\nClumsy.js is a library for creating math figures on HTMLCanvas in XKCD style.\n\nThis library can be used with Node.js libraries `canvas` and `gifencoder`:\n\n```shell\n$ npm install canvas gifencoder\n```\n\n![readme-intro](https://raw.github.com/kreshikhin/clumsy/master/examples/readme-intro.png)\n\n## Contents\n\n  * [Preparing for drawing](#preparing)\n  * [Drawing a figure](#drawing)\n  * [Drawing a figure with scaled axis and title](#axis-and-title)\n  * [Animation](#animation)\n  * [API](#api)\n    * [new Clumsy(canvas)](#newclumsy)\n    * methods:\n    * [axis](#axis)\n    * [background](#background)\n    * [clean](#clean)\n    * [draw](#draw)\n    * [fillTextAtCenter](#filltext)\n    * [overdraw](#overdraw)\n    * [padding](#padding)\n    * [seed](#seed)\n    * [range](#range)\n    * [tabulate](#tabulate)\n    * properties:\n    * [background](#properties)\n    * [color](#properties)\n    * [defaultBoxAscent](#properties)\n    * [lineWidth](#properties)\n    * [radius](#properties)\n    * [step](#properties)\n\n  * [License](#license)\n\n\u003ca name=\"preparing\" /\u003e\n## Preparing for drawing\n\n It needs to create Canvas before drawing and pass this canvas to constructor of object Clumsy. By default clumsy object have padding in 100px and ranges [-1, 1] in both directions. This can be changed by special methods:\n\n```js\n// Adds canvas module from npm repository for example\nvar Canvas = require('canvas');\n\n// Adds this module\nvar clumsy = require('clumsy');\n\n// And some helpers for interaction with canvas and gifencoder modules\nvar helpers = require('clumsy/helpers');\n\n// Inits objects\nvar canvas = new Canvas(800, 600)\nvar clumsy = new Clumsy(canvas);\n\n// Sets padding and ranges before drawing\nclumsy.padding(50);\nclumsy.range(0, 2*Math.PI, -1.5, 1.5);\n```\n\n\u003ca name=\"drawing\" /\u003e\n## Drawing a figure\n\nPass arrays with points to method draw. Each point must consider x and y field, e.g. {x: 0, y: 0} - begin coordinate system.\n\n```js\nvar Canvas = require('canvas');\nvar clumsy = require('clumsy');\nvar helpers = require('clumsy/helpers');\n\nvar canvas = new Canvas(800, 600)\nvar clumsy = new Clumsy(canvas);\n\nclumsy.padding(50);\nclumsy.range(0, 2*Math.PI, -1.5, 1.5);\nclumsy.color('red');\nclumsy.lineWidth(2);\n\nvar sine = clumsy.tabulate(0, 2*Math.PI, 0.01, Math.sin);\nclumsy.draw(sine);\n\nhelpers.saveAsPng(clumsy); // save as png of same name\n```\n\nThe result:\n\n![sine](https://raw.github.com/kreshikhin/clumsy/master/examples/readme-sine.png)\n\n\n\u003ca name=\"axis-and-titles\" /\u003e\n## Drawing a figure with scaled axis and title\n\n```javascript\nvar Canvas = require('canvas');\nvar Clumsy = require('clumsy');\nvar helpers = require('clumsy/helpers');\n\nvar canvas = new Canvas(800, 600)\nvar clumsy = new Clumsy(canvas);\n\nclumsy.font('24px VoronovFont');\nclumsy.padding(50);\nclumsy.range(0, 7, -2, 2);\nclumsy.lineWidth(2);\n\nclumsy.axis('x', 0, 7, 0.5);\nclumsy.axis('y', -2, 2, 0.5);\n\nclumsy.color('red');\nvar sine = clumsy.tabulate(0, 2*Math.PI, 0.01, Math.sin);\nclumsy.draw(sine);\n\nclumsy.fillTextAtCenter('Синус', clumsy.canvas.width/2, 50);\n\nhelpers.saveAsPng(clumsy);\n\n```\n\nThe result:\n\n![axis](https://raw.github.com/kreshikhin/clumsy/master/examples/readme-axis.png)\n\n\n\u003ca name=\"#animation\" /\u003e\n## Animation\n\nThis module also can be used for animation of figure. The best way is prepare a separate script with drawing function.\nThe function must receive two arguments: a clumsy object and an animation param. So without any other dependencies this script can be used for rendering by both ways in a browser or  node.js\n\nDrawing script [spiral.js](examples/spiral.js):\n\n```js\n\nfunction Spiral(clumsy, phase){\n    clumsy.font('24px VoronovFont');\n    clumsy.clean('white');\n\n    clumsy.padding(50);\n    clumsy.range(-2, 2, -2, 2);\n    clumsy.lineWidth(2);\n    clumsy.radius(5);\n\n    clumsy.color('black');\n    clumsy.axis('x', -2, 2, 0.5);\n    clumsy.axis('y', -2, 2, 0.5);\n\n    var spiral = clumsy.tabulate(0, 3, 0.01, function(t){\n        var r = 0.5 * t;\n        return {\n            x: r * Math.cos(2 * Math.PI * t + phase),\n            y: r * Math.sin(2 * Math.PI * t + phase)\n        };\n    })\n\n    clumsy.color('red');\n    clumsy.draw(spiral);\n\n    clumsy.fillTextAtCenter('Спираль', clumsy.canvas.width/2, 30);\n}\n\nif(typeof module != 'undefined' \u0026\u0026 module.exports){\n    module.exports = Spiral;\n}\n\n```\n\nPreview script for browser:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cmeta charset=\"utf-8\"\u003e\n\u003ctitle\u003espiral\u003c/title\u003e\n\u003cscript src=\"https://rawgit.com/kreshikhin/clumsy/master/clumsy.js\"\u003e\u003c/script\u003e\n\u003clink rel=\"stylesheet\" href=\"http://webfonts.ru/import/voronov.css\"\u003e\u003c/link\u003e\n\u003ccanvas id=\"canvas\" width=600 height=600\u003e\n\u003cscript type=\"text/javascript\" src=\"spiral.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\"\u003e\n    var canvas = document.getElementById('canvas');\n    var clumsy = new Clumsy(canvas);\n    clumsy.font('12px VoronovFont');\n\n    var phase = 0;\n    setInterval(function(){\n        clumsy.seed(123);\n\n        clumsy.clear('white');\n        Spiral(clumsy, phase);\n\n        phase += Math.PI / 10;\n    }, 50);\n\u003c/script\u003e\n```\n\nBuilding script for node.js:\n\n```js\n\nvar Canvas = require('canvas');\nvar GIFEncoder = require('gifencoder');\nvar path = require('path');\nvar fs = require('fs');\n\nvar Clumsy = require('clumsy');\nvar helpers = require('clumsy/helpers');\n\nvar Spiral = require('./spiral.js');\n\nvar canvas = new Canvas(600, 600);\nvar clumsy = new Clumsy(canvas);\nclumsy.font('24px VoronovFont');\n\nvar encoder = helpers.prepareEncoder(GIFEncoder, canvas);\nvar phase = 0;\nvar n = 10;\n\nencoder.start();\nfor(var i = 0; i \u003c n; i++){\n    clumsy.seed(123);\n\n    clumsy.clear('white');\n    Spiral(clumsy, phase);\n\n    phase += 2 * Math.PI / n;\n    encoder.addFrame(clumsy.ctx);\n};\n\nencoder.finish();\n```\n\nThe result:\n\n![spiral](https://raw.github.com/kreshikhin/clumsy/master/examples/spiral.gif)\n\n\n## API\n\n\u003ca name=\"newclumsy\" /\u003e\n### new Clumsy(canvas)\n\nCreates new clumsy object.\n\n* `canvas` - an instance of HTMLCanvas\n\n```js\nvar clumsy = new Clumsy(canvas);\n```\n\n\u003ca name=\"axis\" /\u003e\n### axis(axis, start, end, [step | options]);\nDraws axis.\n\n* `axis` may be 'x', 'y', {x: 1, y: 1}\n* `start`, `end` - range of axis\n* `step` - step of scale\n* `options` - sets of options allowed by method:\n  * `zero` - coordinates of zero point of the axis\n  * `step` - a step of the scale\n  * `limits` - limits of scale, [start + step, end - step] by default\n  * `hide_zero` - hides zero if true\n  * `tick_size` - size of scale ticks in px, default is 5px\n  * `mark` - a function that generate label for ticks\n\n```js\n// Draws axis from -1 to 1 without a scale\nclumsy.axis('x', -1, 1);\n// Draws axis from -1 to 1 with a scale and step 0.2\nclumsy.axis('x', -1, 1, 0.2);\n// Draws axis with custom options:\nclumsy.axis('x', -1, 1, {\n    zero: {x: 0, y: 0}, // default\n    step: 0.1,\n    limits: [start + step, end - step],\n    hide_zero: true, // hide zero mark\n    tick_size: 5, // in px\n    mark: function(t){ // default\n        return parseInt(t) + '.' + parseInt(Math.abs(t*10) % 10)\n    }\n});\n```\n\n\u003ca name=\"clean\" /\u003e\n### clean([color])\nUpdates the background color (if argument is not undefined) and cleans the canvas.\n\n * `color` - new background color.\n\n```js\nclumsy.clean();\n```\n\n\u003ca name=\"draw\" /\u003e\n### draw(curve)\n\nDraws a curve by array of point in `{x: x, y: y}` format.\n\n* `curve` is [{x: x0, y: y0}, ... {x: xn-1, yn-1}]\n\n```js\n// Draws line from (0,0) to (1,1).\nclumsy.draw([{x: 0, y:0}, {x: 1, y:1}]);\n```\n\n\u003ca name=\"fillText\" /\u003e\n### fillTextAtCenter(x, y, text)\n\nDraws text at center (x, y).\n\n* x, y - coordinates of text center\n* text - a text for drawing\n\n```js\nclumsy.fillTextAtCenter(100, 100, \"Hello World!\");\n```\n\u003ca name=\"overdraw\" /\u003e\n### overdraw(curve)\n\nDraws a curve with clearing canvas under the curve by background color.\n\n* `curve` is [{x: x0, y: y0}, ... {x: xn-1, yn-1}]\n\n```js\n// Draws line from (0,0) to (1,1)\nclumsy.draw([{x: 0, y:0}, {x: 1, y:1}]);\n// Overdraws line from (0,1) to (0,1)\nclumsy.draw([{x: 1, y:0}, {x: 0, y:1}]);\n```\n\n\u003ca name=\"padding\" /\u003e\n### padding(size)\n### padding(vertical, horizontal)\n### padding(left, right, bottom, top)\n\nSets paddings from the edges of the canvas.\n\n* `size` - size of all paddings\n* `veritcal`, `horizontal` - vertical and horizontal paddings\n* `left`, `right`, `bottom`, `top` - vertical and horizontal paddings\n\n```js\n// Sets all padding in 100px\nclumsy.padding(100);\n// Sets vertical paddings are 100px and horizontal are 200px\nclumsy.padding(100, 200);\n// Sets left, right, bottom and top paddings\nclumsy.padding(50, 100, 150, 200);\n```\n\n\u003ca name=\"range\" /\u003e\n### range(start, end)\n### range(start0, end0, start1, start1)\n\nSets ranges of the coordinate system.\n\n```js\n// Sets same range for horizontal and vertical scales\nclumsy.range(-10, 10);\n// Sets horizontal [-10,10] and vertical [-20,20] ranges\nclumsy.range(-10, 10, -20, 20);\n```\n\n\u003ca name=\"seed\" /\u003e\n### seed([seed])\nSets the seed of generator of pseudo random numbers.\n\n```js\n// Sets the seed\nclumsy.seed(123456);\n// Gets current seed\nvar seed = clumsy.seed();\n```\n\n### properties\n\nProperties with setters/getters:\n\n```js\n// In pixels\nclumsy.step(10);\nclumsy.radius(10);\nclumsy.defaultBoxAscent(16);\nclumsy.lineWidth(1);\n\n// CSS color\nclumsy.background('white');\nclumsy.color('black');\n\n// CSS font\nclumsy.font('12px Arial');\n\n// Seed number for the built-in pseudo random generator\nclumsy.seed(12345);\n```\n\n## License\n\n  [MIT](LICENSE)\n\n[npm-image]: https://img.shields.io/npm/v/clumsy.svg\n[npm-url]: https://npmjs.org/package/clumsy\n[downloads-image]: https://img.shields.io/npm/dm/clumsy.svg\n[downloads-url]: https://npmjs.org/package/clumsy\n[travis-image]: https://img.shields.io/travis/kreshikhin/clumsy/master.svg\n[travis-url]: https://travis-ci.org/kreshikhin/clumsy\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkreshikhin%2Fclumsy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkreshikhin%2Fclumsy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkreshikhin%2Fclumsy/lists"}