├── .gitignore ├── LICENSE ├── README.md ├── dist └── pixel.js ├── gulpfile.js ├── index.html ├── js └── pixel.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Ahmet Simsek 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 | # pixel-animator 2 | 3 | ######[demo](https://jsfiddle.net/indatawetrust/2zsqmfab/15/) 4 | 5 | ####npm install -g http-server 6 | 7 | ####http-server 8 | 9 | ~color selector added 10 | 11 | ~frame timer added 12 | 13 | ![image](http://i.hizliresim.com/RkvZE7.png) 14 | 15 | -------------------------------------------------------------------------------- /dist/pixel.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var canvas = document.querySelector('#frame'), 4 | colorSelector = document.querySelector('#colors'), 5 | time = document.querySelector('input'), 6 | span = document.querySelector('span'), 7 | c = canvas.getContext('2d'), 8 | _c = colorSelector.getContext('2d'), 9 | add = document.querySelector('#add'), 10 | remove = document.querySelector('#remove'), 11 | reset = document.querySelector('#reset'), 12 | start = document.querySelector('#start'), 13 | colors = ['#1abc9c', '#2ecc71', '#3498db', '#9b59b6', '#34495e', '#f1c40f', '#e67e22', '#e74c3c', '#95a5a6', '#bdc3c7']; 14 | 15 | var interval = null, 16 | frames = [], 17 | isdown = false, 18 | list = [], 19 | selectColor = colors[0]; 20 | 21 | var draw = function draw(maps, opacity) { 22 | c.clearRect(0, 0, 200, 200); 23 | 24 | maps.forEach(function (map, i) { 25 | map.forEach(function (_, j) { 26 | if (maps[i][j].select) { 27 | c.save(); 28 | c.beginPath(); 29 | c.globalAlpha = opacity; 30 | c.fillStyle = maps[i][j].color; 31 | c.fillRect(i * 20, j * 20, 20, 20); 32 | c.closePath(); 33 | c.restore(); 34 | } 35 | 36 | c.strokeRect(i * 20, j * 20, 20, 20); 37 | }); 38 | }); 39 | }; 40 | 41 | // color selector 42 | colors.forEach(function (color, i) { 43 | _c.fillStyle = color; 44 | _c.fillRect(i * 20, 0, 20, 20); 45 | }); 46 | 47 | colorSelector.addEventListener('mousedown', function (e) { 48 | _c.clearRect(0, 0, 200, 20); 49 | 50 | colors.forEach(function (color, i) { 51 | _c.fillStyle = color; 52 | _c.fillRect(i * 20, 0, 20, 20); 53 | }); 54 | 55 | var x = e.clientX - 8, 56 | dx = -1; 57 | 58 | while (x > 0) { 59 | x -= 20; 60 | dx++; 61 | } 62 | _c.lineWidth = 4; 63 | _c.strokeRect(dx * 20, 0, 20, 20); 64 | selectColor = colors[dx]; 65 | }); 66 | 67 | // frame create 68 | var frame = function frame() { 69 | var maps = []; 70 | 71 | for (var i = 0; i < 10; i++) { 72 | var _ = []; 73 | for (var j = 0; j < 10; j++) { 74 | _.push({ 75 | select: 0, 76 | color: '#fff', 77 | opacity: 1 78 | }); 79 | } 80 | maps.push(_); 81 | } 82 | 83 | return maps; 84 | }; 85 | 86 | frames.push(frame()); 87 | 88 | draw(frames[0]); 89 | 90 | canvas.addEventListener('mousedown', function (e) { 91 | isdown = true; 92 | 93 | var x = e.clientX - 8; 94 | var y = e.clientY - 8; 95 | var dx = -1;var dy = -1; 96 | while (x > 0) { 97 | x -= 20; 98 | dx++; 99 | } 100 | while (y > 0) { 101 | y -= 20; 102 | dy++; 103 | } 104 | 105 | if (list.indexOf(dx + '' + dy) == -1) { 106 | frames[frames.length - 1][dx][dy].select = !frames[frames.length - 1][dx][dy].select; 107 | frames[frames.length - 1][dx][dy].color = selectColor; 108 | 109 | draw(frames[frames.length - 1], 1); 110 | list.push(dx + '' + dy); 111 | } 112 | }); 113 | 114 | canvas.addEventListener('mousemove', function (e) { 115 | if (isdown) { 116 | var x = e.clientX - 8; 117 | var y = e.clientY - 8; 118 | var dx = -1;var dy = -1; 119 | while (x > 0) { 120 | x -= 20; 121 | dx++; 122 | } 123 | while (y > 0) { 124 | y -= 20; 125 | dy++; 126 | } 127 | 128 | if (list.indexOf(dx + '' + dy) == -1) { 129 | frames[frames.length - 1][dx][dy].select = !frames[frames.length - 1][dx][dy].select; 130 | frames[frames.length - 1][dx][dy].color = selectColor; 131 | 132 | draw(frames[frames.length - 1], 1); 133 | list.push(dx + '' + dy); 134 | } 135 | } 136 | }); 137 | 138 | canvas.addEventListener('mouseup', function (e) { 139 | isdown = false; 140 | list = []; 141 | }); 142 | 143 | canvas.addEventListener('mouseout', function (e) { 144 | isdown = false; 145 | list = []; 146 | }); 147 | 148 | // add frame 149 | add.addEventListener('click', function () { 150 | frames.push(frame()); 151 | draw(frames[frames.length - 2], 0.5); 152 | }); 153 | 154 | // remove frame 155 | remove.addEventListener('click', function () { 156 | clearInterval(interval); 157 | frames.pop(); 158 | 159 | if (frames.length) { 160 | draw(frames[frames.length - 1], 1); 161 | } else { 162 | frames.push(frame()); 163 | draw(frames[0]); 164 | } 165 | 166 | interval = null; 167 | }); 168 | 169 | // start animation 170 | start.addEventListener('click', function () { 171 | var i = -1; 172 | 173 | interval = setInterval(function () { 174 | if (frames.length - 1 == i++) i = 0; 175 | draw(frames[i], 1); 176 | }, time.value); 177 | 178 | start.setAttribute('disabled', 1); 179 | }); 180 | 181 | // reset animation 182 | reset.addEventListener('click', function () { 183 | start.removeAttribute('disabled'); 184 | 185 | clearInterval(interval); 186 | frames = []; 187 | frames.push(frame()); 188 | draw(frames[0]); 189 | interval = null; 190 | }); 191 | 192 | // frame time change 193 | time.addEventListener('mouseup', function (e) { 194 | span.innerText = time.value + ' ms'; 195 | 196 | if (interval != null) { 197 | (function () { 198 | clearInterval(interval); 199 | 200 | var i = -1; 201 | 202 | interval = setInterval(function () { 203 | if (frames.length - 1 == i++) i = 0; 204 | draw(frames[i], 1); 205 | }, time.value); 206 | })(); 207 | } 208 | }); -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const babel = require('gulp-babel'); 3 | 4 | gulp.task('default', () => 5 | gulp.src('js/pixel.js') 6 | .pipe(babel({ 7 | presets: ['es2015'] 8 | })) 9 | .pipe(gulp.dest('dist')) 10 | ); 11 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | pixel animator 4 | 36 | 37 | 38 | 39 |
40 | 50 ms 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /js/pixel.js: -------------------------------------------------------------------------------- 1 | const canvas = document.querySelector('#frame'), 2 | colorSelector = document.querySelector('#colors'), 3 | time = document.querySelector('input'), 4 | span = document.querySelector('span'), 5 | c = canvas.getContext('2d'), 6 | _c = colorSelector.getContext('2d'), 7 | add = document.querySelector('#add'), 8 | remove = document.querySelector('#remove'), 9 | reset = document.querySelector('#reset'), 10 | start = document.querySelector('#start'), 11 | colors = ['#1abc9c','#2ecc71','#3498db','#9b59b6','#34495e', 12 | '#f1c40f','#e67e22','#e74c3c','#95a5a6','#bdc3c7']; 13 | 14 | let interval = null,frames = [],isdown = false,list = [],selectColor = colors[0]; 15 | 16 | const draw = (maps,opacity) => { 17 | c.clearRect(0,0,200,200); 18 | 19 | maps.forEach((map,i) => { 20 | map.forEach((_,j) => { 21 | if(maps[i][j].select){ 22 | c.save(); 23 | c.beginPath(); 24 | c.globalAlpha = opacity; 25 | c.fillStyle = maps[i][j].color; 26 | c.fillRect(i*20,j*20,20,20); 27 | c.closePath(); 28 | c.restore(); 29 | } 30 | 31 | c.strokeRect(i*20,j*20,20,20); 32 | }); 33 | }); 34 | } 35 | 36 | // color selector 37 | colors.forEach((color,i) => { 38 | _c.fillStyle = color; 39 | _c.fillRect(i*20,0,20,20); 40 | }); 41 | 42 | colorSelector.addEventListener('mousedown',(e) => { 43 | _c.clearRect(0,0,200,20); 44 | 45 | colors.forEach((color,i) => { 46 | _c.fillStyle = color; 47 | _c.fillRect(i*20,0,20,20); 48 | }); 49 | 50 | let x = e.clientX-8,dx = -1; 51 | 52 | while(x > 0){ 53 | x -= 20; 54 | dx++; 55 | } 56 | _c.lineWidth = 4; 57 | _c.strokeRect(dx*20,0,20,20); 58 | selectColor = colors[dx]; 59 | }); 60 | 61 | // frame create 62 | const frame = () => { 63 | const maps = []; 64 | 65 | for(let i=0;i<10;i++){ 66 | let _ = []; 67 | for(let j=0;j<10;j++){ 68 | _.push({ 69 | select : 0, 70 | color : '#fff', 71 | opacity : 1 72 | }); 73 | } 74 | maps.push(_); 75 | } 76 | 77 | return maps; 78 | } 79 | 80 | frames.push(frame()); 81 | 82 | draw(frames[0]); 83 | 84 | canvas.addEventListener('mousedown',(e) => { 85 | isdown = true; 86 | 87 | let [x,y] = [e.clientX-8,e.clientY-8], 88 | dx = -1, dy = -1; 89 | while(x > 0){ 90 | x -= 20; 91 | dx++; 92 | } 93 | while(y > 0){ 94 | y -= 20; 95 | dy++; 96 | } 97 | 98 | if(list.indexOf(dx + '' + dy) == -1){ 99 | frames[frames.length-1][dx][dy].select = !frames[frames.length-1][dx][dy].select; 100 | frames[frames.length-1][dx][dy].color = selectColor; 101 | 102 | draw(frames[frames.length-1],1); 103 | list.push(dx + '' + dy); 104 | } 105 | }); 106 | 107 | canvas.addEventListener('mousemove',(e) => { 108 | if(isdown){ 109 | let [x,y] = [e.clientX-8,e.clientY-8], 110 | dx = -1, dy = -1; 111 | while(x > 0){ 112 | x -= 20; 113 | dx++; 114 | } 115 | while(y > 0){ 116 | y -= 20; 117 | dy++; 118 | } 119 | 120 | if(list.indexOf(dx + '' + dy) == -1){ 121 | frames[frames.length-1][dx][dy].select = !frames[frames.length-1][dx][dy].select; 122 | frames[frames.length-1][dx][dy].color = selectColor; 123 | 124 | draw(frames[frames.length-1],1); 125 | list.push(dx + '' + dy); 126 | } 127 | } 128 | }); 129 | 130 | canvas.addEventListener('mouseup',(e) => { 131 | isdown = false; 132 | list = []; 133 | }); 134 | 135 | canvas.addEventListener('mouseout',(e) => { 136 | isdown = false; 137 | list = []; 138 | }); 139 | 140 | // add frame 141 | add.addEventListener('click',() => { 142 | frames.push(frame()); 143 | draw(frames[frames.length-2],0.5); 144 | }); 145 | 146 | // remove frame 147 | remove.addEventListener('click',() => { 148 | clearInterval(interval); 149 | frames.pop(); 150 | 151 | if(frames.length){ 152 | draw(frames[frames.length-1],1); 153 | }else{ 154 | frames.push(frame()); 155 | draw(frames[0]); 156 | } 157 | 158 | interval = null; 159 | }); 160 | 161 | // start animation 162 | start.addEventListener('click',() => { 163 | let i=-1; 164 | 165 | interval = setInterval(() => { 166 | if(frames.length - 1 == i++) 167 | i = 0; 168 | draw(frames[i],1); 169 | },time.value); 170 | 171 | start.setAttribute('disabled',1); 172 | }); 173 | 174 | // reset animation 175 | reset.addEventListener('click',() => { 176 | start.removeAttribute('disabled'); 177 | 178 | clearInterval(interval); 179 | frames = []; 180 | frames.push(frame()); 181 | draw(frames[0]); 182 | interval = null; 183 | }); 184 | 185 | // frame time change 186 | time.addEventListener('mouseup',(e) => { 187 | span.innerText = time.value + ' ms'; 188 | 189 | if(interval != null){ 190 | clearInterval(interval); 191 | 192 | let i=-1; 193 | 194 | interval = setInterval(() => { 195 | if(frames.length - 1 == i++) 196 | i = 0; 197 | draw(frames[i],1); 198 | },time.value); 199 | } 200 | }); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixel-animator", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "gulpfile.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "babel-preset-es2015": "^6.6.0", 13 | "gulp": "^3.9.1", 14 | "gulp-babel": "^6.1.2" 15 | } 16 | } 17 | --------------------------------------------------------------------------------