Как сделать передвижение шашки на тачскрине с помощью Pointer Events
Не могу добиться, чтобы шашка передвигалась на смартфоне движением пальца. На компе с помощью мыши все проходит без проблем, а на смартфоне срабатывает скроллинг либо масштабирование. Подскажите, что сделать? В комментарии забито то, что безуспешно пробовал.
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- <meta name="viewport" content="width=device-width, initial-scale=1"> -->
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<html>
<body>
<table class="chessboard">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<div id="result">
<br>
<table id='resTab'>
<tr>
<th><img id='black' src='black.png' class = 'checker'></th>
<th> </th><th><img id='white' src='white.png' class = 'checker'></th>
</tr>
<tr>
<td>0</td><td>:</td><td>0</td>
</tr>
</table>
<br>
<button id='newgame' class='button'>Новая партия</button>
<br>
<button id='stepback' class='button'>Шаг назад</button>
<br>
<button id='rules' class='button'>Правила</button>
<br>
<button id='settings' class='button'>Выход в меню</button>
<br>
</div>
<div id='message' hidden> sdfsdafsad</div>
<div id ="changesettings" hidden>
<center>
<br>
Волк: <input type='radio' name='black' value='man'> Человек
<input type='radio' name='black' value='computer' checked> Компьютер
<br>
<br>
Овцы: <input type='radio' name='white' value='man' checked> Человек
<input type='radio' name='white' value='computer'> Компьютер
<br>
<br>
Сила компьютера: <input type='radio' name='pclevel' value='1'> 1
<input type='radio' name='pclevel' value='2' > 2
<input type='radio' name='pclevel' value='3' checked> 3
<input type='radio' name='pclevel' value='4' > 4
<input type='radio' name='pclevel' value='5' > 5
<input type='radio' name='pclevel' value='6' > 6
<input type='radio' name='pclevel' value='7' > 7
<input type='radio' name='pclevel' value='8' > 8
<br>
<br>
Звук <input type='radio' name='soundSwitch' value='on'> вкл.
<input type='radio' name='soundSwitch' value='off' checked> выкл.
<br>
<br>
<button id='savesettings' class='button'>Начать игру</button>
<button id='exit' class='button'>Выход</button>
<br>
</center>
</div>
<script src='wolf-player.js'></script>
</body>
</html>
/*.chessboard {
position:fixed;
}*/
.chessboard td{
border:solid 1px #666666;
width:50px;
height:50px;
max-height:50px;
text-align:center;
vertical-align: bottom;
}
.chessboard td.b {
content: '';
background-image: url(black.png);
background-size: 50px;
}
.chessboard td.b.marked {
border-color: red;
}
.chessboard td.w {
content: '';
background-image: url(white.png);
background-size: 50px;
}
.chessboard td.w.marked {
border-color: red;
}
.chessboard td.empty{
background: orange;
}
.chessboard td.empty.marked{
border-color: red;
}
.checker{
width:45px;
height:45px;
}
@keyframes blinker {
0% { opacity: 1.0; }
50% { opacity: 0.0; }
100% { opacity: 1.0; }
}
.checker.blink {
animation:1s blinker linear infinite;
}
#result{
position: absolute;
position: absolute;
top: 10px;
left: 480px;
background:orange;
}
#message{
position: absolute;
position: absolute;
top: 150px;
left: 183px;
width: 600px;
height: 250px;
font-size: 250%;
text-align:center;
background:#c0bdbd;
border:solid 5px #666666;
}
#resTab{
border:solid 5px #666666;
border-collapse:collapse;
font-family: 'Times New Roman', Times, serif; /* Гарнитура текста */
font-size: 180%; /* Размер шрифта в процентах */
}
#resTab td{
border:solid 0px #666666;
width:51px;
height:60px;
max-height:60px;
text-align:center;
overflow:hidden;
}
#resTab td textarea{
display:block;
outline:0px;
border:0px;
width:100%;
height:100%;
}
.button{
width:170px;
height:60px;
border:solid 5px orange;
border-radius: 5px;
font-size: 130%;
}
#changesettings {
margin: 0;
background: rgba(255,165,40, 0.9);
position: absolute;
top: 30%;
left: 25%;
width: 600px;
height: 320px;
margin-right: -50%;
transform: translate(-50%, -50%);
border: solid 5px #666666;
border-collapse:collapse;
font-family: 'Times New Roman';
font-size: 150%;
}
#savesettings{
font-size: 100%;
width:380px;
height:60px;
}
#exit{
font-size: 100%;
width:120px;
height:60px;
}
[type="radio"] {
transform:scale(1.5);
}
let board = document.querySelector('.chessboard');
class Cells {//Класс представляет 32 клетки, по которым можно ходить
constructor(state = ['', '', '', '', '', '', '', '','', '', '', '','', '', '', '',
'', '', '', '','', '', '', '','', '', '', '','', '', '', '',]) {
this.state = state;
}
getAvailableMoves(chosenCell) {
let checkers = []; //массив шашек, для которых определяем возможные ходы
if (chosenCell === 'w' || chosenCell === 'b') { // для робота не указана конкретная шашка
for (let i=0; i<32; i++){
if (this.state[i] == chosenCell){
checkers.push(i);
}
}
}else checkers = [chosenCell]; // для человека определяем ходы только для выбранной шашки
const topRow = [0, 1, 2, 3];
const bottomRow = [28, 29, 30, 31];
const leftRow = [0, 8, 16, 24];
const rightRow = [7, 15, 23, 31];
const posB = this.state.indexOf('b');
const posFirstW = this.state.indexOf('w');
const posLastW = this.state.lastIndexOf('w');
let directions = new Set();
let moves = [];
for (let checker of checkers){
if (this.state[checker] == 'b'){
directions = new Set(['northwest','northeast','southwest', 'southeast']);
} else{
directions = new Set(['northwest','northeast']);
}
if (topRow.includes(checker) || (this.state[checker] == 'b' &&
chosenCell === 'b' && posFirstW - posB > 8) ||
(this.state[checker] == 'w' && chosenCell === 'w' &&
posFirstW - posB > 8 && checker - posLastW > 4)) {
directions.delete('northwest');
directions.delete('northeast');
}
if (bottomRow.includes(checker)) {
directions.delete('southwest');
directions.delete('southeast');
}
if (leftRow.includes(checker)) {
directions.delete('northwest');
directions.delete('southwest');
}
if (rightRow.includes(checker)) {
directions.delete('northeast');
directions.delete('southeast');
}
for (let dir of directions){
let y = Math.floor(checker/4);
switch (dir){
case 'northwest':
moves.push([checker, checker - 5 + (y%2 > 0)]);
break;
case 'northeast':
moves.push([checker, checker - 4 + (y%2 > 0)]);
break;
case 'southwest':
moves.push([checker, checker + 3 + (y%2 > 0)]);
break;
case 'southeast':
moves.push([checker, checker + 4 + (y%2 > 0)]);
}
}
}
return moves.filter(move => this.state[move[1]] == '');
}
move(from, to){
this.state[to] = this.state[from];
this.state[from] = '';
}
}
let cells = new Cells(['', 'b', '', '', '', '', '', '', '', '', '', '','', '', '', '',
'', '', '', '', '', '', '', '', '', '', '', '','', '', '', '',]);
updateBoard();
let chosenCell; // клетка с выбранной для хода шашкой
newGame();
/*function fullScreen(element) {
if(element.requestFullscreen) {
element.requestFullscreen();
} else if(element.webkitrequestFullscreen) {
element.webkitRequestFullscreen();
} else if(element.mozRequestFullscreen) {
element.mozRequestFullScreen();
}
}*/
function newGame(){
// document.documentElement.requestFullScreen();
window.ontouchmove = function(e){e.preventDefault;} // mobile
document.body.addEventListener('touchstart', function(e){ e.preventDefault(); });
// board.onmousedown = startMoving;
board.onpointerdown = startMoving;
turn = 'b'; // очередь хода
updateBoard();
function startMoving(e){
let target = e.target.closest('td');
if(!target) {
console.log('ни фига не таргет!');
return;
}
e.preventDefault();
let y = target.parentNode.rowIndex;
let x = target.cellIndex;
if (e.which == 3) { // для тестирования - показ номера ячейки
let buffer = target.innerHTML;
target.innerHTML = y*4 + (x - (y%2>0))/2;
target.onmouseup = function(e){
target.innerHTML = buffer;
}
return;
}
chosenCell = y*4 + (x - (y%2>0))/2;
let m = cells.getAvailableMoves(chosenCell);
m.forEach(function(current){
let y = Math.floor(current[1]/4);
let x = (current[1]%4)*2+1*(y%2>0);
board.rows[y].cells[x].classList.add('marked');
});
/*board.onmouseup = */board.onpointerup = function(e){
let target = e.target.closest('td');
if(!target) {
console.log('ни фига не таргет!');
}else{
let y = target.parentNode.rowIndex;
let x = target.cellIndex;
if (target.classList.contains('marked')){
let plannedCell = y*4 + (x - (y%2>0))/2;
cells.move(chosenCell, plannedCell);
}
}
updateBoard();
}
}
}
function updateBoard(){
for(let i=0; i<32; i++){
let y = Math.floor(i/4);
let x = (i%4)*2+1*(y%2>0);
board.rows[y].cells[x].classList.remove('marked');
if (cells.state[i] == 'b') board.rows[y].cells[x].classList ='b';
else if (cells.state[i] == 'w') {
board.rows[y].cells[x].classList = 'w';
} else board.rows[y].cells[x].classList = 'empty';
}
}