Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions chapters/chapter13.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,11 +468,11 @@ p.a.b#main {

Если бы мы просто обновляли DOM в цикле, страница бы зависла и ничего не было бы видно. Браузеры не обновляют страницу во время работы JavaScript, и не допускают в это время работы со страницей. Поэтому нам нужна requestAnimationFrame – она сообщает браузеру, что мы пока закончили, и он может заниматься своими браузерными вещами, например обновлять экран и отвечать на запросы пользователя.

Наша функция анимации передаётся текущее время через аргументы, которое оно сравнивает с предыдущим (переменная lastTime), чтобы движение кота было однородным, и анимация работала плавно. Если бы мы просто передвигали её на заданный промежуток на каждом шаге, движение бы запиналось если бы, например, другая задача загрузила бы компьютер.
Наша функция анимации передаёт текущее время через аргументы, которое она сравнивает с предыдущим (переменная lastTime), чтобы движение кота было однородным, и анимация работала плавно. Если бы мы просто передвигали её на заданный промежуток на каждом шаге, движение бы запиналось если бы, например, другая задача загрузила бы компьютер.

Движение по кругу осуществляется с применением тригонометрических функций Math.cos и Math.sin. Я кратко опишу их для тех, кто с ними незнаком, так как они понадобятся нам в дальнейшем.

Math.cos и Math.sin полезны тогда, когда надо найти точки на круге с центром в точке (0, 0) и радиусом в единицу. Обе функции интерпретируют свой аргумент как позицию на круге, где 0 обозначает точку с правого края круга, затем нужно против часовой стрелки, пока путь диной в 2π (около 6.28) не проведёт нас по кругу. Math.cos считает координату по оси x той точки, которая является нашей текущей позицией на круге, а Math.sin выдаёт координату y. Позиции (или углы) больше, чем 2π или меньше чем 0, тоже допустимы – повороты повторяются так, что a+2π означает тот же самый угол, что и a.
Math.cos и Math.sin полезны тогда, когда надо найти точки на круге с центром в точке (0, 0) и радиусом в единицу. Обе функции интерпретируют свой аргумент как позицию на круге, где 0 обозначает точку с правого края круга, затем нужно против часовой стрелки, пока путь длиной в 2π (около 6.28) не проведёт нас по кругу. Math.cos считает координату по оси x той точки, которая является нашей текущей позицией на круге, а Math.sin выдаёт координату y. Позиции (или углы) больше, чем 2π или меньше чем 0, тоже допустимы – повороты повторяются так, что a+2π означает тот же самый угол, что и a.

<img src="../img/13-4.png">

Expand Down
6 changes: 3 additions & 3 deletions chapters/chapter14.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ console.log("1".charCodeAt(0));
</script>
```

Источником события нажатия клавиши узел становится в зависимости от того, где находился фокус ввода во время нажатия. Обычные узлы не могут получить фокус ввода (если только вы не задали им атрибут tabindex), а такие, как ссылки, кнопки и поля форм – могут. Мы вернёся к полям ввода в главе 18. Когда ни у чего нет фокуса, в качестве целевого узла событий работает document.body
Источником события нажатия клавиши узел становится в зависимости от того, где находился фокус ввода во время нажатия. Обычные узлы не могут получить фокус ввода (если только вы не задали им атрибут tabindex), а такие, как ссылки, кнопки и поля форм – могут. Мы вернёмся к полям ввода в главе 18. Когда ни у чего нет фокуса, в качестве целевого узла событий работает document.body

##Кнопки мыши
Нажатие кнопки мыши тоже запускает несколько событий. События «mousedown» и «mouseup» похожи на «keydown» и «keyup», и запускаются, когда кнопка нажата и когда отпущена. События происходят у тех узлов DOM, над которыми находился курсор мыши.
Expand Down Expand Up @@ -272,7 +272,7 @@ console.log("1".charCodeAt(0));

Когда курсор попадает на узел и уходит с него, происходят события «mouseover» or «mouseout». Их можно использовать, кроме прочего, для создания эффектов проведения мыши, показывая или меняя стиль чего-либо, когда курсор находится над этим элементом.

К сожалению, создание такого эффекта не ограничивается запуском его при событии «mouseover» и завершением при событии «mouseout». При движении мыши от узла к его дочерним узлам на родительском узле происходит событие «mouseout», хотя мышь, вообще говоря, его и не покидала. Что ещё хуже, эти события распространяются как и все другие, поэтому вы всё равно получаете «mouseout» при уходе курсора с одного их дочерних узлов того узла, где вы зарегистрировали обработчик.
К сожалению, создание такого эффекта не ограничивается запуском его при событии «mouseover» и завершением при событии «mouseout». При движении мыши от узла к его дочерним узлам на родительском узле происходит событие «mouseout», хотя мышь, вообще говоря, его и не покидала. Что ещё хуже, эти события распространяются как и все другие, поэтому вы всё равно получаете «mouseout» при уходе курсора с одного из дочерних узлов того узла, где вы зарегистрировали обработчик.

Для обхода проблемы можно использовать свойство relatedTarget объекта событий. Он сообщает, на каком узле была до этого мышь при возникновении события «mouseover», и на какой элемент она переходит при событии «mouseout». Нам надо менять эффект, только когда relatedTarget находится вне нашего целевого узла. Только в этом случае событие на самом деле представляет собой переход на наш узел (или уход с узла).

Expand Down Expand Up @@ -439,7 +439,7 @@ if (Math.random() < 0.5) { // 50% chance
}
```

Функция cancelAnimationFrame работает так же, как clearTimeout – вызов её со значением, возвращённым requestAnimationFrame, отменит этот кадр (если он уже не был вызван).
Функция cancelAnimationFrame работает так же, как clearTimeout – вызов её со значением, возвращённым requestAnimationFrame, отменит этот кадр (если он ещё не был вызван).

Похожий набор функций, setInterval и clearInterval используется для установки таймеров, которые будут повторяться каждые X миллисекунд.

Expand Down
4 changes: 2 additions & 2 deletions chapters/chapter15.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
##Технология
Мы используем DOM браузера для графики, и читаем ввод пользователя, обслуживая события клавиатуры.

Код, относящийся к экрану и клавиатуре – небольшая часть работы, которую нам над проделать для создания игры. Так как всё состоит из цветных квадратиков, рисовать это просто: мы создаём элементы DOM и используем стили, чтобы задать им цвет фона, размер и расположение.
Код, относящийся к экрану и клавиатуре – небольшая часть работы, которую нам надо проделать для создания игры. Так как всё состоит из цветных квадратиков, рисовать это просто: мы создаём элементы DOM и используем стили, чтобы задать им цвет фона, размер и расположение.

Мы представляем фон как таблицу, поскольку это – неизменная решётка из квадратов. Свободно двигающиеся элементы можно накладывать сверху, используя абсолютное позиционирование.

Expand Down Expand Up @@ -461,7 +461,7 @@ Level.prototype.animate = function(step, keys) {
};
```

Когда у свойства уровня status есть значение, отличное от null (а это бывает, когда игрок выиграл или проиграл), мы уменьшить до нуля счётчик finishDelay, считающий время между моментом, когда произошёл выигрыш или проигрыш и моментом, когда надо заканчивать показ уровня.
Когда у свойства уровня status есть значение, отличное от null (а это бывает, когда игрок выиграл или проиграл), мы можем уменьшить до нуля счётчик finishDelay, считающий время между моментом, когда произошёл выигрыш или проигрыш и моментом, когда надо заканчивать показ уровня.

Цикл while делит временной интервал на удобные мелкие куски. Он следит, чтобы промежутки были не больше maxStep. К примеру, шаг в 0.12 секунды будет нарезан на два шага по 0.05 и остаток в 0.02

Expand Down
2 changes: 1 addition & 1 deletion chapters/chapter16.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ function flipHorizontally(context, around) {

Функция branch в примере показывает, что можно сделать с функцией, которая выполняет преобразования и вызывает другую функцию (в данном случае, саму себя), которая продолжает рисовать с заданными преобразованиями.

Функция рисует древовидную структуру, рисуя линию, потом передвигая центр координат на конец линии, и вызывая себя затем дважды – сначала, повернув влево, а затем вправо. Каждый вызов уменьшает длину ветви, и рекурсия останавливается, когда длина падает меньше 8.
Функция рисует древовидную структуру, рисуя линию, потом передвигая центр координат на конец линии, и вызывая себя дважды – сначала повернув влево, а затем вправо. Каждый вызов уменьшает длину ветви, и рекурсия останавливается, когда длина падает меньше 8.

```html
<canvas width="600" height="300"></canvas>
Expand Down
10 changes: 5 additions & 5 deletions chapters/chapter18.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@

Много типов полей ввода используют тег `<input>`. Его атрибут type используется для выбора стиля поля. Вот несколько распространённых типов:

<b>text </b>текстовое поле на одну строку
<b>password </b>то же, что текст, но прячет ввод
<b>checkbox </b>переключатель вкл/выкл
<b>radio </b>часть поля с возможностью выбора из нескольких вариантов
<b>file </b>позволяет пользователю выбрать файл на его компьютере
* <b>text </b>текстовое поле на одну строку
* <b>password </b>то же, что <b>text</b>, но прячет ввод
* <b>checkbox </b>переключатель вкл/выкл
* <b>radio </b>часть поля с возможностью выбора из нескольких вариантов
* <b>file </b>позволяет пользователю выбрать файл на его компьютере

Поля форм не обязательно должны появляться внутри тега `<form>`. Их можно разместить в любом месте страницы. Информацию из таких полей нельзя передавать на сервер (это возможно только для всей формы целиком), но когда мы делаем поля, которые обрабатывает JavaScript, нам обычно и не нужно передавать информацию из полей через submit.

Expand Down
2 changes: 1 addition & 1 deletion chapters/chapter19.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ controls.openFile = function(cx) {
};
```

Загружать файл с URL ещё проще. Но с текстовым полем мы не знаем, закончил ли пользователь набирать в нём URL, поэтому мы не можем просто слушать события “change”. Вместо этого мы обернём поле в форму и среагируем, когда она будет отправлена – либо по нажатию Enter, либо по нажатию кнопку load.
Загружать файл с URL ещё проще. Но с текстовым полем мы не знаем, закончил ли пользователь набирать в нём URL, поэтому мы не можем просто слушать события “change”. Вместо этого мы обернём поле в форму и среагируем, когда она будет отправлена – либо по нажатию Enter, либо по нажатию кнопки load.

```js
controls.openURL = function(cx) {
Expand Down