├── .gitignore ├── src ├── scripts │ ├── index.js │ └── particle.js └── index.html ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | dist 3 | node_modules 4 | package-lock.json 5 | -------------------------------------------------------------------------------- /src/scripts/index.js: -------------------------------------------------------------------------------- 1 | import Particle from './particle' 2 | 3 | const particles = [] 4 | 5 | document.addEventListener('click', event => { 6 | const initialX = event.clientX 7 | const initialY = event.clientY 8 | 9 | particles.push(new Particle(initialX, initialY)) 10 | }) 11 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Assay 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "particles", 3 | "version": "1.0.0", 4 | "description": "One small click for man, one giant event for particle.", 5 | "main": "src/scripts/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "parcel src/index.html" 9 | }, 10 | "keywords": [], 11 | "author": "border-radius", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "parcel-bundler": "^1.6.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Particles 2 | 3 | Если кликнуть на странице, на ней появится частица, которая будет произвольно двигаться (наблюдателю может показаться будто бы она дрожит). Если много кликать по странице, будет много разноцветных частиц и все они будут произвольно двигаться. 4 | 5 | Работает в последнем Chrome и Firefox, а про другие версии и браузеры я знаю только то, что они наследие. 6 | 7 | ### Где посмотреть 8 | 9 | Можно прямо по ссылке: https://border-radius.github.io/particles 10 | 11 | Ничего не требуется, только кликайте, пожалуйста. 12 | 13 | ### Как запустить 14 | 15 | Нужно склонировать репозиторий к себе и установить зависимости: 16 | 17 | ```bash 18 | git clone https://github.com/border-radius/particles 19 | cd particles 20 | npm i 21 | ``` 22 | 23 | Учтите, для этой процедуры у вас должен быть установлен [node.js и npm](https://nodejs.org/en/download/). 24 | 25 | Установится новый модный сборщик [parcel](https://github.com/parcel-bundler/parcel). Если вы с ним не знакомы, не пугайтесь, все очень просто. Теперь вам достаточно выполнить команду `npm start` чтобы сборщик сделал свое дело и запустил сервер для разработки. В консоли вы увидите на него ссылку, по которой стоит перейти. 26 | 27 | Кликайте по странице и наслаждайтесь. 28 | 29 | ### Что с этим надо сделать 30 | 31 | 1. Иногда частицы улетают за край экрана и наблюдателю может стать грустно. Не ясно, вернется частица обратно или нет. Надо с этим что-нибудь сделать, например, чтобы частицы отталкивались от края экрана. 32 | 33 | 2. Частицам все равно какого размера экран. Было бы забавно если бы частицам было неуютно в тесноте и они двигались быстрее и наоборот: на просторах фуллскрина 4K-монитора, впадали бы практически в анабиоз. 34 | 35 | 3. Все это как-то ужасно тормозит если покликать усердно. С этим можно что-нибудь сделать, доктор? 36 | 37 | ### Чего хочется от вас 38 | 39 | Пулл-реквест с желанными фичами и оптимизациями. Простор возможностей ограничен только вашей фантазией. Будет круто если вы сможете прямо цифрами рассказать насколько мир стал лучше вашими усилиями. Все-таки, многие люди скептики и излишне придирчивы, им может не хватить сухого "стало быстрее". 40 | -------------------------------------------------------------------------------- /src/scripts/particle.js: -------------------------------------------------------------------------------- 1 | export default class Particle { 2 | constructor(initialX, initialY) { 3 | this.speed = this.getRandomNumber(10, 20) 4 | 5 | this.el = document.createElement('div') 6 | this.el.style.position = 'absolute' 7 | this.el.style.transition = 'all 0.1s ease 0s' 8 | this.el.style['border-radius'] = '50%' 9 | 10 | document.body.appendChild(this.el) 11 | 12 | this.setPosition(initialX, initialY) 13 | this.setRandomSize() 14 | this.setRandomColor() 15 | this.startBrownianMotion() 16 | } 17 | 18 | getRandomNumber(from, to) { 19 | const rnd = Math.random() 20 | return parseInt((rnd * (to - from)) + from) 21 | } 22 | 23 | setRandomColor() { 24 | const rnd = Math.random() 25 | const hex = 0x1000000 + rnd * 0xffffff 26 | const color = hex.toString(16).substr(1, 6) 27 | this.el.style.background = ['#', color].join('') 28 | } 29 | 30 | getPixels(property) { 31 | const value = this.el.style[property] 32 | return parseInt(value) 33 | } 34 | 35 | setPixels(property, value) { 36 | this.el.style[property] = [value, 'px'].join('') 37 | } 38 | 39 | setRandomSize() { 40 | const side = this.getRandomNumber(20, 70) 41 | this.setPixels('width', side) 42 | this.setPixels('height', side) 43 | } 44 | 45 | getPositionX() { 46 | return this.getPixels('left') 47 | } 48 | 49 | getPositionY() { 50 | return this.getPixels('top') 51 | } 52 | 53 | setPosition(x, y) { 54 | this.setPixels('left', x) 55 | this.setPixels('top', y) 56 | } 57 | 58 | moveRandomly() { 59 | const to = parseInt(this.speed / 2) 60 | const from = to * -1 61 | const prevX = this.getPositionX() 62 | const prevY = this.getPositionY() 63 | const nextX = prevX + this.getRandomNumber(from, to) 64 | const nextY = prevY + this.getRandomNumber(from, to) 65 | this.setPosition(nextX, nextY) 66 | } 67 | 68 | startBrownianMotion() { 69 | const timeout = 100 70 | const interval = setInterval(this.moveRandomly.bind(this), timeout) 71 | } 72 | } 73 | --------------------------------------------------------------------------------