Помогите разобраться с canvas! (рисование через циклы).
Всем доброго времени суток.
Увидел на хабре как циклом стирали квадраты и получилась шахматная доска. Всё вроди бы понятно, но появились некоторые вопросы, и, возможно, это даже не о канвасе, а скорее об циклах.:-? Буду очень благодарен если мне помогут разобраться в некоторых вопросах по рисованию разных фигур через циклы. 1. Что означает число 20 в этой и подобных строках: ctx.clearRect(20 + i * 98.75, 20 + j * 98.75, 98.75, 98.75); и как узнать какое число нужно ставить? 2. После долгой и мучительной расстановки шашек, методом тыка (подставлял разные вариации и наборы цифр в цикл))), я таки выставил их как надо (более-менее), но всё же: как убрать лишние рядки так как их вышло по четыре у каждой из сторон, а не 3, как надо? 3. Возможно ли как-то вставить moveTo(), что бы не было видно переходов между кругами? Я знаю, что если бы я использовал метод fill() то линий не было бы, но мне не нужно заполнение. var canv = $('#canv')[0], ctx = canv.getContext('2d'); canv.width = 900; canv.height = 900; ctx.strokeRect(15, 15, 800, 800); // внешняя рамка доски; ctx.strokeRect(20, 20, 790, 790); // внутренняя рамка; ctx.fillRect(20, 20, 790, 790); // заливка доски; for (var i = 0; i < 8; i += 2) for (var j = 0; j < 8; j += 2) { // создание размметки шахматной доски; ctx.clearRect(20 + i * 98.75, 20 + j * 98.75, 98.75, 98.75); ctx.clearRect(20 + (i + 1) * 98.75, 20 + (j + 1) * 98.75, 98.75, 98.75); } for (var i = 0; i < 16; i += 4) { for (var j = 0; j < 6; j += 4) { // расстановка синих шашек; ctx.beginPath(); ctx.strokeStyle = 'blue'; ctx.arc(170 + i * 49.375, 70 + j * 49.375, 35, 0, Math.PI * 2, true); ctx.arc(-80 + (i + 3) * 49.375, 20 + (j + 3) * 49.375, 35, 0, Math.PI * 2, true); ctx.stroke(); } } for (var q = 0; q < 16; q += 4) { for (var w = 0; w < 6; w += 4) { // расстановка белых шашек; ctx.beginPath(); ctx.strokeStyle = 'white'; ctx.arc(170 + q * 49.375, 470 + w * 49.375, 35, 0, Math.PI * 2, true); ctx.arc(20 + (q + 1) * 49.375, 370 + (w + 4) * 49.375, 35, 0, Math.PI * 2, true); ctx.stroke(); } } Если я правильно всё понял, то здесь нужно использовать по три цикла для каждого ряда шашек каждому из сторон, чтобы не было остаточных линий и было всего три ряда в место 4. Надеюсь на помощь в разъяснении этих вопросов и подтверждении/опровержении моих домыслов. Сделал как предполагал: for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.strokeStyle = 'blue'; ctx.arc(170 + i * 49.375, 70, 35, 0, Math.PI * 2, true); ctx.stroke(); } for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.strokeStyle = 'blue'; ctx.arc(70 + i * 49.375, 170, 35, 0, Math.PI * 2, true); ctx.stroke(); } for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.strokeStyle = 'blue'; ctx.arc(170 + i * 49.375, 265, 35, 0, Math.PI * 2, true); ctx.stroke(); } Но такой код великоват. Проще никак нельзя? |
<canvas id = 'canv'></canvas> <script> var canv = document.querySelector('#canv'), ctx = canv.getContext('2d'); canv.width = 900; canv.height = 900; ctx.strokeRect(15, 15, 800, 800); // внешняя рамка доски; ctx.strokeRect(20, 20, 790, 790); // внутренняя рамка; ctx.fillRect(20, 20, 790, 790); // заливка доски; for (var i = 0; i < 8; i += 2) for (var j = 0; j < 8; j += 2) { // создание размметки шахматной доски; ctx.clearRect(20 + i * 98.75, 20 + j * 98.75, 98.75, 98.75); ctx.clearRect(20 + (i + 1) * 98.75, 20 + (j + 1) * 98.75, 98.75, 98.75); } for (j = 0; j < 3; j++) { for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.fillStyle = 'blue'; ctx.arc(69.375 + 98.75 * ((j + 1) % 2) + i * 49.375, (69.375 + 98.75 * j), 35, 0, Math.PI * 2, true); ctx.fill(); } } for (j = 0; j < 3; j++) { for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.fillStyle = 'white'; ctx.arc(69.375 + 98.75 * (j % 2) + i * 49.375, (563.125 + 98.75* j), 35, 0, Math.PI * 2, true); ctx.fill(); } } </script> 20 - это отсюда: ctx.strokeRect(20, 20, 790, 790); 69.375 = 20 + 98.75 / 2 ЗЫ: использовал fill, т.к. stroke бледновато выглядит |
Цитата:
Цитата:
Благодарю за пояснение. Цитата:
|
canvas шашки
:write: ... шифровка из центра, изменить ww!!!
Пример: canvas шашки
<!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> </head> <body> <canvas id = 'canv'></canvas> <script> var canv = document.querySelector('#canv'), ctx = canv.getContext('2d'); var ww = 387, k = 20, kk = k-5 , w = ww - k/2, v = w/8, vv = v/2, vd = vv + k, dr = vv-5; canv.width = ww + k; canv.height = ww + k; ctx.strokeRect(kk, kk, ww, ww); // внешняя рамка доски; ctx.strokeRect(k, k, w, w); // внутренняя рамка; ctx.fillRect(k, k, w, w); // заливка доски; for (var i = 0; i < 8; i += 2) for (var j = 0; j < 8; j += 2) { // создание размметки шахматной доски; ctx.clearRect(k + i * v, k + j * v, v, v); ctx.clearRect(k + (i + 1) * v, k + (j + 1) * v, v, v); } for (j = 0; j < 8; j++) { if(j == 3 || j == 4) continue; for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.fillStyle = j > 4 ?'white' : 'blue'; ctx.arc(vd + v * ((j + 1) % 2) + i * vv, (vd + v * j), dr, 0, Math.PI * 2, true); ctx.fill(); } } </script> </body> </html> |
рони,
мой мозг перестал понимать, что происходит ещё на объявлении переменных.:help: Точнее, я не могу понять, зачем так усложнять себе жизнь. Так актуально делать в каком-то случаи? |
Цитата:
|
Цитата:
|
Цитата:
<canvas id = 'canv'></canvas> <script> var canv = document.querySelector('#canv'), ctx = canv.getContext('2d'); canv.width = 900; canv.height = 900; ctx.strokeRect(15, 15, 800, 800); // внешняя рамка доски; ctx.strokeRect(20, 20, 790, 790); // внутренняя рамка; ctx.fillRect(20, 20, 790, 790); // заливка доски; for (var i = 0; i < 8; i += 2) for (var j = 0; j < 8; j += 2) { // создание размметки шахматной доски; ctx.clearRect(20 + i * 98.75, 20 + j * 98.75, 98.75, 98.75); ctx.clearRect(20 + (i + 1) * 98.75, 20 + (j + 1) * 98.75, 98.75, 98.75); } ctx.lineWidth = 10; for (j = 0; j < 3; j++) { for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.strokeStyle = 'blue'; ctx.arc(69.375 + 98.75 * ((j + 1) % 2) + i * 49.375, (69.375 + 98.75 * j), 35, 0, Math.PI * 2, true); ctx.stroke(); } } for (j = 0; j < 3; j++) { for (var i = 0; i < 16; i += 4) { ctx.beginPath(); ctx.strokeStyle = 'white'; ctx.arc(69.375 + 98.75 * (j % 2) + i * 49.375, (563.125 + 98.75* j), 35, 0, Math.PI * 2, true); ctx.stroke(); } } </script> |
Цитата:
Кстати, кто-нибудь знает почему брэкетс может вот так ругаться "Анализатор FS int завершился с ошибкой: [object Object]", вроди бы всё в порядке но в одной функции этот объект не виден, вот кусок кода с объектом и где появляется ошибка: var lap = []; var isCursorInArc = function (x, y lap) { return x > lap.x && x < lap.x + lap.r && y > lap.y && y < lap.y + lap.ea; }; Если закоментировать эту функцию то всё работает. |
var isCursorInArc = function (x, y, lap)
|
j0hnik, мдэ....засиделся я сегодня, надо наверное перерыв сделать, только что сам заметил. А я всё гуглю, ищу, чё оно за ошибка такая... Жаль фейспалма тут нет.
|
drakulawz,
eslint установите если у вас нет, ускоряет фикс такого рода рода ошибок. |
Цитата:
|
Цитата:
Да, оно как и раньше, показывает в какой строке ошибка, но если человек жёстко тупит (как я) то даже такой сверх хэлп не помогает.:cray: |
Не создаю новую тему так как это всё тот же скрипт практически с тем же вопросом. Надеюсь это не проблема.
Сделал разметку, расставил шашки, узнал как их выбирать мышкой. Но! Появились старые и пару новых проблем: 1. Шашки все стали белыми, точнее я могу менять цвет заливки но сделать три верхних ряда и три нижних ряда разного цвета не смог. Может сюда не подходят такие циклы? Или нужно делать, как раньше, - отдельно белые и отдельно синие? 2. Когда выбираю шашки (если включить в скрипт функцию с обрамлением) то, при их выборе мышкой, ко всем рамкам применяется функция select и уже не отменяется. Это происходит из-за того что мой конструктор ссылается на несколько похожих функций? Ведь метод ctx.stroke() есть в функции strokeArc() & selectArc() и, по методу конструктора Arc оно как-то "сливает" эти две функции? 3. Так же есть проблема с выбором - не могу найти правильные координаты для этого. Выбрать шашку могу только по клику на 1/4 круга. Это исправлял с помощью выражения: return x + x > lap.x && x < lap.x + lap.r && y + y > lap.y && y < lap.y + lap.r . Но если, после этого, можно выбрать верхние шашки (хоть и по две в некоторых местах), то при клике на нижние ряды выбирается по 3 сразу.:cray: Как правильно координаты взять? Создавать отдельный конструктор для этого? 4. Плюс, после выбора шашки, остаётся кружок - еле заметный но он там есть и если присмотреться то, всё таки, заметный. Я пробовал два варианта: ctx.globalCompositeOperation = 'destination-out' и ctx.clearRect(). Опять таки, из-за конструктора какой-то конфликт или это из-за цикла - после двух кликов удаляются все шашки и в доске делаются дырки.:cray: Вообще не пойму как эту функцию правильно осуществить. Может надо заново запускать отрисовку после удаления? var canv = $('#canv')[0], ctx = canv.getContext('2d'); var ww = 800, k = 20, kk = k - 5, w = ww - k / 2, v = w / 8, vv = v / 2, vd = vv + k, dr = vv - 10, up = v * 5, width = $('#w').val(), // высота из инпута; hight = $('#h').val(), // ширина из инпута; offset = 0; // переменная для анимирования таргета шашек; canv.width = width; //ширина канваса; canv.height = hight; //высота канваса; ctx.strokeRect(kk, kk, ww, ww); // внешняя рамка доски; ctx.strokeRect(k, k, w, w); // внутренняя рамка; ctx.fillRect(k, k, w, w); // заливка доски; // функция отрисовки шашек; var fillArc = function (x, y, r, sa, ea, cw) { for (var j = 0; j < 8; j++) { if (j == 3 || j == 4) continue; // переход между белыми и синими; ctx.fillStyle = j < 4 ? 'white' : 'blue'; //НЕ РАБОТАЕТ! ctx.beginPath(); ctx.arc(x, y, r, sa, ea, cw); ctx.fill(); } }; // функция обрамления шашек; var strokeArc = function (x, y, r, sa, ea, cw) { for (var j = 0; j < 8; j++) { if (j == 3 || j == 4) continue; // переход между белыми и синими; ctx.strokeStyle = j < 4 ? 'blue' : 'white'; //НЕ РАБОТАЕТ! ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(x, y, r, sa, ea, cw); ctx.stroke(); } }; // функция выделения шашек; var selectArc = function (x, y, r, sa, ea, cw) { ctx.strokeStyle = 'green'; ctx.beginPath(); ctx.lineWidth = 2; ctx.setLineDash([8, 2]); ctx.lineDashOffset = -offset; ctx.arc(x, y, r, sa, ea, cw); ctx.stroke(); }; // реализация "бегущей" преривистой для функции выделения; function march() { offset++; if (offset > 100) { offset = 0; } selectArc(); setTimeout(march, 20); }; // функция удаления остаточного круга после взятия в таргет шашки; // var circle = function (x, y, r, sa, ea, cw) { // ctx.globalCompositeOperation = 'destination-out' // ctx.arc(x, y, r, sa, ea, cw); // ctx.fill(); // } // конструктор создания элементов кроме разметки доски; var Arc = function (x, y, r, sa, ea, cw) { this.x = x; this.y = y; this.r = r; this.sa = sa; this.ea = ea; this.cw = true; this.selected = false; }; // прототип шаблонов для отрисовок; Arc.prototype = { draw: function () { fillArc(this.x, this.y, this.r, this.sa, this.ea, this.cw); }, frame: function () { strokeArc(this.x, this.y, this.r, this.sa, this.ea, this.cw); }, stroke: function () { march(); selectArc(this.x, this.y, this.r, this.sa, this.ea, this.cw); }, // clearCrcl: function () { // circle(this.x, this.y, this.r, this.sa, this.ea, this.cw); // }, select: function () { this.selected = !this.selected; } }; // создание разметки шахматной доски; for (var i = 0; i < 8; i += 2) { for (var j = 0; j < 8; j += 2) { ctx.clearRect(k + i * v, k + j * v, v, v); ctx.clearRect(k + (i + 1) * v, k + (j + 1) * v, v, v); } } var i = 0, lap = []; // массив с отрисованными объектами; // цикл отрисовки шашек; for (var j = 0; j < 8; j++) { if (j == 3 || j == 4) continue; // пропуск двух средних рядов клеток; for (var i = 0; i < 16; i += 4) { ctx.fillStyle = j > 4 ? 'white' : 'blue'; lap.push(new Arc(vd + v * ((j + 1) % 2) + i * vv, (vd + v * j), dr, 0, Math.PI * 2, true)); } }; // функция для проверки координат клика; var isCursorInArc = function (x, y, lap) { return x > lap.x && x < lap.x + lap.r && y > lap.y && y < lap.y + lap.r; }; // функция активация выделения шашки; canv.onclick = function (e) { var x = e.x, y = e.y; for (i in lap) { if (isCursorInArc(x, y, lap[i])) { lap[i].select(); } } }; // рисование шашек и рамки (после клика); setInterval(function () { for (i in lap) { lap[i].draw(); lap[i].frame(); if (lap[i].selected) { lap[i].stroke(); } } }, 30); |
drakulawz,
Цитата:
https://javascript.ru/forum/project/...tml#post464453 |
Цитата:
Пройдусь по видеоурокам по канвасу. Ещё и js нативный надо подтянуть нехило, тугова-то у меня с этими всеми колбэками. Да, и как правильно писать код толком не пойму, только то и делаю, что пародирую... Сейчас вот только понял, как важно писать сноски к каждой функции - реально помогает лучше ориентироваться в коде - прогресс!:p |
Часовой пояс GMT +3, время: 12:54. |