Произвольные движение обьекта на сайта JS

KPACHODAP

DELETED
Регистрация
21 Дек 2009
Сообщения
675
Реакции
274
Второй день ломаю голову, нашел много вариантов разлиных фишек на JS, но припаять все вместе не выходит(((( Нужна помощь профи! но суть такая что мне нужно чтобы обьект(фура.png) на сайте вылетал к примеру: сначала справа в промежутке там с 1-30 секунд, прокрутив ниже или пройдя там например пол минуты или 2 минуты обьект опять вылетает слева произвольно и пролетает дальше по сайту зигзагом и т.д. за ранее благодарен!

озпjpg.jpg




Скрытое содержимое доступно для зарегистрированных пользователей!


первый более похожий но скорость и какие то странноватые линии движения очень! а также при движении как зафиксить нос грубо говоря машины чтобы она ехала по траектории!

ну и сама фишка хочется чтобы он как бы сам жил по сути! тоесть произвольные перещения! как то так! чтобы не сильно назойлево для клиентов сайта!



вот что то сделал! но как вместо шара машинку сделать из png или svg?
JavaScript:
/**
 * для вопроса https://toster.ru/q/455772
 * Какой алгоритм подойдет для описания полета насекомого?
 * Insect flight simulator.
 */
// create canvas
        var canvas = document.createElement('canvas')
            , ctx = canvas.getContext('2d')
            , divCanvas = document.createElement('div')
            , i
            , Point = function( x, y) { this.x = x || 0, this.y = y || 0 }
            , n = 28
            , chain = [] // Target is [0], fly is the last element of chain
            , radius = 160        // min distance to create a link, in px
            , getRnd = function( max){ return Math.floor( max * Math.random()); }
        ;
  
    // resize the canvas to fill browser window dynamically
      window.addEventListener('resize', divCanvas, false);

        // setup canvas
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        divCanvas.appendChild(canvas);
        divCanvas.className = "centered";
        document.body.appendChild(divCanvas);
      
        // initialize points
        for( i = 0; i < n; i++) chain.push( new Point( 0, 0));
      
      
        function render() {
            var target
                , fly
                , dx
                , dy
                , i
                , point
                , k = 0.09
            ;
          
            window.requestAnimationFrame(render);
          
            target = chain[0];
            fly = chain[ chain.length - 1];
          
            // check distance from fly to target
            dx = target.x - fly.x;
            dy = target.y - fly.y;
            if( Math.sqrt( dx * dx + dy * dy) <= radius) {
                // get a new target
                do {
                    target.x = getRnd( canvas.width);
                    target.y = getRnd( canvas.height);
                    dx = target.x - fly.x;
                    dy = target.y - fly.y;
                } while( Math.sqrt( dx * dx + dy * dy) <= radius);
            }
          
            // update chain
            for( i = 1; i < chain.length; i++) {
                point = chain[i];
                target = chain[i-1];
                point.x += k * (target.x - point.x);
                point.y += k * (target.y - point.y);
            }
          
            // erase canvas
            ctx.fillStyle = "rgba(0,0,0,0.1)";
            ctx.fillRect( 0, 0, canvas.width, canvas.height);
          
      // draw
            //target = chain[0];
            //ctx.fillStyle = "rgb(128,128,128)";
            //ctx.fillRect( target.x - 5, target.y, 10, 1);
            //ctx.fillRect( target.x, target.y - 5, 1, 10);

          
            ctx.fillStyle = "white";
            ctx.beginPath();
            ctx.arc( fly.x, fly.y, 3, 0, Math.PI * 2);
            ctx.fill();
        }
      
        render();


и верно ли это прописал?

Код:
// resize the canvas to fill browser window dynamically
      window.addEventListener('resize', divCanvas, false);

        // setup canvas
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

готов заплатить симвролически за подсказку!
 
Последнее редактирование:
есть кто может дописать код выше?
 
есть кто может дописать код выше?

Попробуй этот, может что-то выйдет)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Фура</title>
<style>
.truck {
position: absolute;
width: 100px; /* задайте нужную ширину и высоту для вашей фуры */
height: 100px;
transition: transform 120s linear; /* измените продолжительность движения, если нужно */
}
</style>
</head>
<body>

<script>
function randomInRange(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}

function createTruck() {
const truck = document.createElement('img');
truck.src = 'фура.png'; // замените 'фура.png' на путь к вашей картинке
truck.className = 'truck';
document.body.appendChild(truck);

const startX = document.documentElement.clientWidth;
const startY = randomInRange(0, document.documentElement.clientHeight - 100);
truck.style.left = startX + 'px';
truck.style.top = startY + 'px';

const endX = randomInRange(0, document.documentElement.clientWidth);
const endY = document.documentElement.clientHeight;

const duration = randomInRange(30000, 120000); // от 30 секунд до 2 минут
truck.style.transition = `transform ${duration}ms linear`;

setTimeout(() => {
truck.style.transform = `translate(${endX - startX}px, ${endY - startY}px)`;
}, 0);

setTimeout(() => {
truck.remove();
createTruck(); // Создаем новую фуру после того, как предыдущая достигнет конца
}, duration);
}

createTruck();
</script>

</body>
</html>
 
есть кто может дописать код выше?

Переписал твой код для использования спрайта, добавил чуть физики и комментарии для понимания что происходит
Для просмотра ссылки Войди или Зарегистрируйся

есть кто может дописать код выше?
А вообще, как по мне то случайная анимация создает ощущение хаоса. Это не всегда полезно, особенно на бизнес сайтах.

Лучше применить тригонометрические функции для иллюзии случайности движения. К примеру Для просмотра ссылки Войди или Зарегистрируйся отличный вариант. Или вообще Для просмотра ссылки Войди или Зарегистрируйся

Вот моя реализация того-же кода но с применением quadrifolium
Для просмотра ссылки Войди или Зарегистрируйся
 
Последнее редактирование:
Попробуй этот, может что-то выйдет)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Фура</title>
<style>
html, body {padding:0;
margin:0;
width: 100%;
}
.truck {
position: absolute;
width: 100px; /* задайте нужную ширину и высоту для вашей фуры */
height: 100px;
transition: transform 120s linear; /* измените продолжительность движения, если нужно */
}
</style>
</head>
<body>

<script>
function randomInRange(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}

function createTruck() {
const truck = document.createElement('img');
truck.src = 'фура.png'; // замените 'фура.png' на путь к вашей картинке
truck.className = 'truck';
document.body.appendChild(truck);

const startX = document.documentElement.clientWidth;
const startY = randomInRange(0, document.documentElement.clientHeight - 100);
truck.style.left = startX + 'px';
truck.style.top = startY + 'px';

const endX = randomInRange(0, document.documentElement.clientWidth);
const endY = document.documentElement.clientHeight;

const duration = randomInRange(30000, 120000); // от 30 секунд до 2 минут
truck.style.transition = `transform ${duration}ms linear`;

setTimeout(() => {
truck.style.transform = `translate(${endX - startX}px, ${endY - startY}px)`;
}, 0);

setTimeout(() => {
truck.remove();
createTruck(); // Создаем новую фуру после того, как предыдущая достигнет конца
}, duration);
}

createTruck();
</script>

</body>
</html>



почему то этот код создает скрол и движение по линии! а можно чтобы от пункта А до пункта Б менялся маршрут произвольно отрезками типа того.


а так же можно как то изменить чтобы не только справа выезжал а рандомно?

Переписал твой код для использования спрайта, добавил чуть физики и комментарии для понимания что происходит
Для просмотра ссылки Войди или Зарегистрируйся


А вообще, как по мне то случайная анимация создает ощущение хаоса. Это не всегда полезно, особенно на бизнес сайтах.

Лучше применить тригонометрические функции для иллюзии случайности движения. К примеру Для просмотра ссылки Войди или Зарегистрируйся отличный вариант. Или вообще Для просмотра ссылки Войди или Зарегистрируйся

Вот моя реализация того-же кода но с применением quadrifolium
Для просмотра ссылки Войди или Зарегистрируйся
просто то что нужно!!!!!! улет!

просто добавив код в <body>

<script src="/js/pen.js" crossorigin></script>

он создает область а может ли он без области летать по сайту?
 
Последнее редактирование:
он создает область а может ли он без области летать по сайту?
я не знаю какая у тебя структура HTML страницы, но для универсального решения я бы сделал так:
1. Указал канвасу какой-то специфичный класс
Код:
divCanvas.className = "centered";
=>
Код:
divCanvas.className = "canvas-random-fly";

2. Установил для этого класса CSS чтобы канвас был фиксированным, поверх всех остальных элементов (z-index), и обязательно pointer-events: none, чтобы быть пассивным и не перекрывать собой работу остальных элементов страницы.
CSS:
.canvas-random-fly {
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    pointer-events: none;
}

В этом случае канвас всегда будет поверх страницы, куда бы ты не скролив. Тебе возможно потребуется скрывать его в какой-то момент. Для этого можно слушать `scroll` событие и управлять видимостью канваса
CSS:
.canvas-random-fly {
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    pointer-events: none;
    transition: opacity 0.4s ease-out;
   will-change: opacity;
}
.canvas-random-fly.hidden {
   opacity: 0;
}
Код:
window.addEventListener('scroll', function() {
var scrollPositionY = window.scrollY || document.documentElement.scrollTop;

if(scrollPositionY >= УКАЗАТЬ ЧТО НАДО && scrollPositionY <= УКАЗАТЬ ЧТО НАДО) {
    divCanvas.classList.add('hidden');
} else {
    divCanvas.classList.remove('hidden');
}
});

Ну и т.д.

Ах, да, еще ж надо прозрачнім канвас сделать, вместо
ctx.fillStyle = "rgba(0,0,0,0.4)";
ctx.fillRect(0, 0, canvas.width, canvas.height);

пишем
ctx.clearRect(0, 0, canvas.width, canvas.height);

К сожалению пропадет эффект motion blur, но в этом случае по другому ни как. Делать его будет муторно.

P.S. перепроверь опечатки и ошибки в коде, пишу с телефона и мог ошибиться

Кстати по поводу motion blur, это может біть отличній способ потренероваться в JS и Canvas, рекомендую самостоятельно попробовать, как будет время
Алгоритм не сложен. Надо создать массив обектов с историей положений нашего спрайта (x, y, angle), например 10 значений, и каждій тик, после просчета новіх значений и перед отрисовкой, сохранять в голову массива новое значение, сдвигая старіе в хвост.
А на етапе отрисовки проходимся по массиву с хвоста в голову и отрисовуем спрайт начиная с opacity 0.1 до 1.0.
Получится такое себе затухание, попробуй, не сложно.
 
Последнее редактирование:
Спасибо много понтяного обьяснил, голову ломаю возможне ли какие то действия с обьектом!
1. К примеру кликнув по обьекту сделать оставновку?
2. Кликнув по обьекту он исчезает?
3. Кликнув по обьекту откроектя pop-up modal какой нить

А так крутая штука этот convas
 
смотри, здесь есть небольшая проблема.
Если, как ты хотел изначально, сделать канвас поверх страницы, чтобы объект всегда летал над текстом, и не установить pointer-events:none, то сайт будет нефункционален. Канвас будет перехватывать все клики и ссылки будут недоступны. Иначе ты не определишь клик точно над объектом до пикселя.

Если прям точность не важна, то можно схитрить, повесить на document слушатель событий на клик мышкой или тап и каждый клик сверять координаты курсора и текущие координаты объекта (плюс некоторый диаметр вокруг, +-). Если совпадает, то вызывать какое либо действие, куда фантазия заведет.
Канвас так же будет недоступен, а фунциональность документа не пострадает. Важно, если курсор совпал с объектом, при клике над объектом вызывать preventDefault в событии, иначе есть вероятность одновременного клика по объекту и ссылке какой нить.

добавил счетчик попаданий
Для просмотра ссылки Войди или Зарегистрируйся
 
Последнее редактирование:
смотри, здесь есть небольшая проблема.
Если, как ты хотел изначально, сделать канвас поверх страницы, чтобы объект всегда летал над текстом, и не установить pointer-events:none, то сайт будет нефункционален. Канвас будет перехватывать все клики и ссылки будут недоступны. Иначе ты не определишь клик точно над объектом до пикселя.

Если прям точность не важна, то можно схитрить, повесить на document слушатель событий на клик мышкой или тап и каждый клик сверять координаты курсора и текущие координаты объекта (плюс некоторый диаметр вокруг, +-). Если совпадает, то вызывать какое либо действие, куда фантазия заведет.
Канвас так же будет недоступен, а фунциональность документа не пострадает. Важно, если курсор совпал с объектом, при клике над объектом вызывать preventDefault в событии, иначе есть вероятность одновременного клика по объекту и ссылке какой нить.

добавил счетчик попаданий
Для просмотра ссылки Войди или Зарегистрируйся
крутяк! отдуши!

а вот вопрос тоесть при клике на обект можно вызывать другой png обьект над самолетом прям по верх верно и будет также двигаться с ним? как то такое сделать? :glob:
 
а вот вопрос тоесть при клике на обект можно вызывать другой png обьект над самолетом прям по верх верно и будет также двигаться с ним? как то такое сделать? :glob:
Довольно легко, я опишу как, ты попробуй.
У нас есть переменная sprite, заведи новую переменную, например sprite2
Загрузи в нее картинку по аналогии со sprite
Дальше в цикле рендера тебе надо выводить новый спрайт после нашего текущего (может быть потребуется для нового сайта поиграться с координатами, добавить или отнять разницу в размере, если размеры спрайтов не совпадают).
Но так второй объект будет всегда летать с первым, надо в начале создать переменную, например let isShowSprite2 = false;
Там где я проверяю попадание и добавляю счет надо эту переменную указать в true.
И в конце концов там где отрисовывается второй спрайт проверять эту переменную и отрисовывать спрайт только если isShowSprite2 равен true

Создай Pen и реализуй. Скинь ссылку.
 
Назад
Сверху