Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 01.07.2023, 10:06
Кандидат Javascript-наук
Отправить личное сообщение для Борис К Посмотреть профиль Найти все сообщения от Борис К
 
Регистрация: 22.02.2017
Сообщений: 145

Поворот изображения
Со вторым полугодием, JS-волшебники!
Экспериментируя с немного сокращённым кодом, обсуждаемым в другой теме, хотелось бы, чтобы каждый раз после перемещения кликами двух соседних изображений в табличке серая картинка под ней поворачивалась вокруг своей оси, например, на 90 градусов.
Я самостоятельно справился корявым способом с этой задачей, но хотелось бы узнать профессиональное решение от знатоков. Буду рад новым знаниям!
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        td {
            width: 150px;
            height: 150px;
            background-size: cover;
            background-image: var(--url);
        }
        .game.end{
            border-collapse: collapse;
            border-spacing: 0px;
        }
    </style>
</head>
<body>
    <br /><br />
    <table class="game">
        <tr>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </table>
<br /><br /><br />
<img id="rotate" src="https://via.placeholder.com/150x150.png" />
    
    <script>
        function imagedata_to_image(imagedata) {
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            canvas.width = imagedata.width;
            canvas.height = imagedata.height;
            ctx.putImageData(imagedata, 0, 0);
            return canvas.toDataURL();
        }
         
        function shuffle(array) {
            let i = array.length;
            while (i--) {
                let j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
            return array;
        }
        const x = 150;  
        const y = 150;  
        const w = 2;  
         
        const images = [
            "https://loremflickr.com/150/150/girl?random=1",
            "https://loremflickr.com/150/150/dog?random=2",
            "https://loremflickr.com/150/150/cat?random=3",
            "https://loremflickr.com/150/150/boy?random=4"
        ];
        const h = Math.ceil(images.length / w);  
        const canvas = Object.assign(document.createElement('canvas'), {
            width: w * x,
            height: h * y
        });
        
        const ctx = canvas.getContext('2d'),
            arrSrc = [],
            tb = document.querySelector('.game'),
            cells = Array.from(tb.querySelectorAll('td'));
        let win, temp = [];
        function endGame()
        {
           tb.classList.add('end');
        }
        function exch(event) {
            if (win) return;
            let td = event.target.closest('.game td');
            if (td) {
                let cellIndex = td.cellIndex;
                let rowIndex = td.closest("tr").rowIndex;
                if (temp.length) {
                    let x = Math.abs(cellIndex - temp[1]);
                    let y = Math.abs(rowIndex - temp[2]);
                    if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
                        let url = td.style.getPropertyValue('--url');
                        td.style.setProperty('--url', temp[0].style.getPropertyValue('--url'));
                        temp[0].style.setProperty('--url', url);
                        temp = [];
                    }
                } else {
                    temp = [td, cellIndex, rowIndex];
                }

            }
        }
        tb.addEventListener("click", exch);
        const createImg = () => Promise.all(
            shuffle(images).map((src, i) => new Promise(
                (onload, onerror) => Object.assign(new Image(), {
                    crossOrigin: 'anonymous',
                    src,
                    onerror,
                    onload
                })
            ).then(({
                target
            }) => {
                const hPos = Math.floor(i / w);
                const wPos = i - (hPos * w);
                ctx.drawImage(
                    target,
                    wPos * x,
                    hPos * y,
                    x,
                    y
                )
            }))
        ).then(() => {
            const wh = w * x / tb.rows.length;
            arrSrc.length = 0;
            win = false;
            temp = [];
            tb.classList.remove('end');
            for (let i = 0; i < tb.rows.length; i++) {
                for (let j = 0; j < tb.rows[i].cells.length; j++) {
                    let imagedata = ctx.getImageData(wh * j, wh * i, wh, wh);
                    let url = imagedata_to_image(imagedata);
                    arrSrc.push(`url(${url})`);
                }
            }
            shuffle(arrSrc.slice(0)).forEach((url, i) => cells[i].style.setProperty('--url', url))
        });
        createImg()
    </script>
</body>
</html>

Последний раз редактировалось Борис К, 01.07.2023 в 10:08.
Ответить с цитированием
  #2 (permalink)  
Старый 01.07.2023, 10:41
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

css transform rotate
Борис К,

<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        td {
            width: 150px;
            height: 150px;
            background-size: cover;
            background-image: var(--url);
        }
        .game.end{
            border-collapse: collapse;
            border-spacing: 0px;
        }
        #rotate{
            transform: rotate(var(--angle, 0deg));
            transition: transform 1s;
        }

    </style>
</head>
<body>
    <br /><br />
    <table class="game">
        <tr>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </table>
<br /><br /><br />
<img id="rotate" src="https://via.placeholder.com/150x150.png" />

    <script>
        function imagedata_to_image(imagedata) {
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            canvas.width = imagedata.width;
            canvas.height = imagedata.height;
            ctx.putImageData(imagedata, 0, 0);
            return canvas.toDataURL();
        }

        function shuffle(array) {
            let i = array.length;
            while (i--) {
                let j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
            return array;
        }
        const x = 150;
        const y = 150;
        const w = 2;

        const images = [
            "https://loremflickr.com/150/150/girl?random=1",
            "https://loremflickr.com/150/150/dog?random=2",
            "https://loremflickr.com/150/150/cat?random=3",
            "https://loremflickr.com/150/150/boy?random=4"
        ];
        const h = Math.ceil(images.length / w);
        const canvas = Object.assign(document.createElement('canvas'), {
            width: w * x,
            height: h * y
        });

        const ctx = canvas.getContext('2d'),
            arrSrc = [],
            tb = document.querySelector('.game'),
            cells = Array.from(tb.querySelectorAll('td'));
        let win, temp = [];
        function endGame()
        {
           tb.classList.add('end');
        }
        let  angle = 0;


        function exch(event) {
            if (win) return;
            let td = event.target.closest('.game td');
            if (td) {
                let cellIndex = td.cellIndex;
                let rowIndex = td.closest("tr").rowIndex;
                if (temp.length) {
                    let x = Math.abs(cellIndex - temp[1]);
                    let y = Math.abs(rowIndex - temp[2]);
                    if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
                        let url = td.style.getPropertyValue('--url');
                        td.style.setProperty('--url', temp[0].style.getPropertyValue('--url'));
                        temp[0].style.setProperty('--url', url);
                      td !== temp[0] && rotate.style.setProperty('--angle', `${angle += 90}deg`);
                        temp = [];
                    }
                } else {
                    temp = [td, cellIndex, rowIndex];
                }

            }
        }
        tb.addEventListener("click", exch);
        const createImg = () => Promise.all(
            shuffle(images).map((src, i) => new Promise(
                (onload, onerror) => Object.assign(new Image(), {
                    crossOrigin: 'anonymous',
                    src,
                    onerror,
                    onload
                })
            ).then(({
                target
            }) => {
                const hPos = Math.floor(i / w);
                const wPos = i - (hPos * w);
                ctx.drawImage(
                    target,
                    wPos * x,
                    hPos * y,
                    x,
                    y
                )
            }))
        ).then(() => {
            const wh = w * x / tb.rows.length;
            arrSrc.length = 0;
            win = false;
            temp = [];
            tb.classList.remove('end');
            for (let i = 0; i < tb.rows.length; i++) {
                for (let j = 0; j < tb.rows[i].cells.length; j++) {
                    let imagedata = ctx.getImageData(wh * j, wh * i, wh, wh);
                    let url = imagedata_to_image(imagedata);
                    arrSrc.push(`url(${url})`);
                }
            }
            shuffle(arrSrc.slice(0)).forEach((url, i) => cells[i].style.setProperty('--url', url))
        });
        createImg()
    </script>
</body>
</html>

Последний раз редактировалось рони, 01.07.2023 в 10:43.
Ответить с цитированием
  #3 (permalink)  
Старый 01.07.2023, 11:30
Кандидат Javascript-наук
Отправить личное сообщение для Борис К Посмотреть профиль Найти все сообщения от Борис К
 
Регистрация: 22.02.2017
Сообщений: 145

Отличная работа!
Рони, как всегда огромная благодарность за ценную помощь!
Good luck!
Ответить с цитированием
  #4 (permalink)  
Старый 24.07.2023, 08:32
Кандидат Javascript-наук
Отправить личное сообщение для Борис К Посмотреть профиль Найти все сообщения от Борис К
 
Регистрация: 22.02.2017
Сообщений: 145

Здравствуйте, Рони!)
Экспериментируя разное , добился того, что при кликах на обмен двумя изображениями все изображения в таблице изменяют угол.
А возможно ли, чтобы угол изменяли только те два изображения, которые поменялись местами?
Ответить с цитированием
  #5 (permalink)  
Старый 24.07.2023, 19:17
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

Сообщение от Борис К
А возможно ли, чтобы угол изменяли только те два изображения, которые поменялись местами?
Сообщение от рони
td !== temp[0] && rotate.style.setProperty('--angle', `${angle += 90}deg`);
if(td !== temp[0]) {
rotate.style.setProperty('--angle', `${angle += 90}deg`);
td.финт();
temp[0].тоже_финт();
}
Ответить с цитированием
  #6 (permalink)  
Старый 25.07.2023, 14:02
Кандидат Javascript-наук
Отправить личное сообщение для Борис К Посмотреть профиль Найти все сообщения от Борис К
 
Регистрация: 22.02.2017
Сообщений: 145

Рони, спасибо, но дальше понимания, что строку 098 следует заменить примером вашего последнего сообщения, дело не пошло... не пошло!(((((
Ломал голову полночи, но не понял следующее:
Сообщение от рони
финт();
temp[0].тоже_финт();
Повторюсь, получилось сделать, чтобы при обмене сменяли угол все изображения таблицы, а хотелось бы, чтобы только те, которые поменялись местами.
Ответить с цитированием
  #7 (permalink)  
Старый 25.07.2023, 14:41
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

Борис К,

<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
        td {
            width: 150px;
            height: 150px;
            background-size: cover;
            background-image: var(--url);
        }

        .game.end {
            border-collapse: collapse;
            border-spacing: 0px;
        }

        #rotate,
        .game td {
            transform: rotate(var(--angle, 0deg));
            transition: transform 1s;
        }
    </style>
</head>

<body>
    <br /><br />
    <table class="game">
        <tr>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
        </tr>
    </table>
    <br /><br /><br />
    <img id="rotate" src="https://via.placeholder.com/150x150.png" />
    <script>
        function imagedata_to_image(imagedata) {
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d');
            canvas.width = imagedata.width;
            canvas.height = imagedata.height;
            ctx.putImageData(imagedata, 0, 0);
            return canvas.toDataURL();
        }

        function shuffle(array) {
            let i = array.length;
            while (i--) {
                let j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
            return array;
        }
        const x = 150;
        const y = 150;
        const w = 2;

        const images = [
            "https://loremflickr.com/150/150/girl?random=1",
            "https://loremflickr.com/150/150/dog?random=2",
            "https://loremflickr.com/150/150/cat?random=3",
            "https://loremflickr.com/150/150/boy?random=4"
        ];
        const h = Math.ceil(images.length / w);
        const canvas = Object.assign(document.createElement('canvas'), {
            width: w * x,
            height: h * y
        });

        const ctx = canvas.getContext('2d'),
            arrSrc = [],
            tb = document.querySelector('.game'),
            cells = Array.from(tb.querySelectorAll('td'));
        let win, temp = [];

        function endGame() {
            tb.classList.add('end');
        }
        let angle = 0;


        function exch(event) {
            if (win) return;
            let td = event.target.closest('.game td');
            if (td) {
                let cellIndex = td.cellIndex;
                let rowIndex = td.closest("tr").rowIndex;
                if (temp.length) {
                    let x = Math.abs(cellIndex - temp[1]);
                    let y = Math.abs(rowIndex - temp[2]);
                    if ((x == 0 && y == 1) || (x == 1 && y == 0) || td === temp[0]) {
                        let url = td.style.getPropertyValue('--url');
                        td.style.setProperty('--url', temp[0].style.getPropertyValue('--url'));
                        temp[0].style.setProperty('--url', url);
                        if (td !== temp[0]) {
                            rotate.style.setProperty('--angle', `${angle += 90}deg`);
                            td.style.setProperty('--angle', `${td.dataset.angle = (+td.dataset.angle || 0) + 360 }deg`);
                            temp[0].style.setProperty('--angle', `${temp[0].dataset.angle = (+temp[0].dataset.angle || 0) - 360 }deg`);
                        }

                        temp = [];
                    }
                } else {
                    temp = [td, cellIndex, rowIndex];
                }

            }
        }
        tb.addEventListener("click", exch);
        const createImg = () => Promise.all(
            shuffle(images).map((src, i) => new Promise(
                (onload, onerror) => Object.assign(new Image(), {
                    crossOrigin: 'anonymous',
                    src,
                    onerror,
                    onload
                })
            ).then(({
                target
            }) => {
                const hPos = Math.floor(i / w);
                const wPos = i - (hPos * w);
                ctx.drawImage(
                    target,
                    wPos * x,
                    hPos * y,
                    x,
                    y
                )
            }))
        ).then(() => {
            const wh = w * x / tb.rows.length;
            arrSrc.length = 0;
            win = false;
            temp = [];
            tb.classList.remove('end');
            for (let i = 0; i < tb.rows.length; i++) {
                for (let j = 0; j < tb.rows[i].cells.length; j++) {
                    let imagedata = ctx.getImageData(wh * j, wh * i, wh, wh);
                    let url = imagedata_to_image(imagedata);
                    arrSrc.push(`url(${url})`);
                }
            }
            shuffle(arrSrc.slice(0)).forEach((url, i) => cells[i].style.setProperty('--url', url))
        });
        createImg()
    </script>
</body>

</html>
Ответить с цитированием
  #8 (permalink)  
Старый 25.07.2023, 21:12
Кандидат Javascript-наук
Отправить личное сообщение для Борис К Посмотреть профиль Найти все сообщения от Борис К
 
Регистрация: 22.02.2017
Сообщений: 145

Восхитительно... просто восхитительно!
Рони, огромная благодарность!
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не пойму как это сделано.. поворот изображения AleksSergSB Общие вопросы Javascript 7 21.09.2018 23:21
HTML5 Canvas. Поворот изображения Valdemor Элементы интерфейса 3 29.04.2013 18:12
плавный поворот изображения vvsh Элементы интерфейса 5 21.04.2012 22:55
Поворот изображения в браузере Владимир Седов Элементы интерфейса 1 15.03.2011 00:10
Поворот изображения Titanic jQuery 1 12.03.2011 17:37