Мобильный Chrome ошибка - анимированный холст падает в браузере, когда высота холста в 3-5 раз превышает высоту экрана И холст используется на холсте - PullRequest
0 голосов
/ 03 апреля 2020

Если вы используете это, он работает нормально (используя img на холсте):

ctx_bg.drawImage($("#image_tile")[0], positions[i].x, positions[i].y);

Если вы используете это, он вылетает из браузера в течение 3 секунд (используя холст на холсте):

ctx_bg.drawImage($(".canvas_tile")[0], positions[i].x, positions[i].y);

Выше 2 строк - единственная разница между 2 витринами ниже. Протестировано на Android (Samsung S10, Chrome 80.0.3987.149).

Кроме того, холст на холсте отлично работает, когда высота холста меньше (1-2 высоты экрана). Кроме того, он отлично работает на рабочем столе chrome!

Это ошибка мобильного браузера или ее можно исправить?

РЕДАКТИРОВАТЬ: Поскольку вы не можете запустить код ниже на stackoverflow mobile view , тогда вот быстрые ссылки для просмотра на мобильном телефоне:

При этом используются 2-ые частицы CANVAS и CRASHES на мобильном телефоне:

$(document).ready(function() {

    ctx_bg = $(".bg_canvas")[0].getContext("2d");
    ctx_child = $(".canvas_tile")[0].getContext("2d");

    ctx_child.beginPath();
    ctx_child.arc(20, 20, 5, 0, 1.5 * Math.PI);
    ctx_child.stroke();

    innerWidth = $("body").innerWidth();
    innerHeight = $("body").innerHeight()*5; 
    numberOfElements = 222;
    positions = [];
    angle = 0;


    $(".bg_canvas")[0].width = innerWidth; 
    $(".bg_canvas")[0].height = innerHeight;

    for (var i=0; i<numberOfElements; i++) {
        positions.push({x: Math.random()*innerWidth, y: Math.random()*innerHeight});
    };


    function animateCircles() {
        bgAnimation = requestAnimationFrame(animateCircles)
        ctx_bg.clearRect(0, 0, innerWidth, innerHeight);
        for (var i = 0; i < numberOfElements; i++){
            positions[i].y+=3;
            if (positions[i].y > innerHeight) {
                positions[i].y = 0;
            }
            ctx_bg.drawImage($(".canvas_tile")[0], positions[i].x, positions[i].y);
            // ctx_bg.drawImage($("#image_tile")[0], positions[i].x, positions[i].y);
        }
    }
    animateCircles()
})
body, html {
    padding: 0;
    margin: 0;
    width: 100%;
    height: 100%;
}
#image_tile, .canvas_tile  {
    display: none;
}
<!DOCTYPE html>

<html>
    <head>
        <title>KRAATER</title>
        <meta charset="UTF-8">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
    </head>
    <body>
        <img id="image_tile" src="https://www.gravatar.com/avatar/435af02114568dbaf00005b28c3ef592?s=48&d=identicon&r=PG">
        <canvas class="canvas_tile"></canvas>
        <canvas class="bg_canvas"></canvas>
    </body>
</html>

При этом используются 2-ые частицы BITMAP и РАБОТЫ на мобильном телефоне:

$(document).ready(function() {

    ctx_bg = $(".bg_canvas")[0].getContext("2d");
    ctx_child = $(".canvas_tile")[0].getContext("2d");

    ctx_child.beginPath();
    ctx_child.arc(20, 20, 5, 0, 1.5 * Math.PI);
    ctx_child.stroke();

    innerWidth = $("body").innerWidth();
    innerHeight = $("body").innerHeight()*5;
    numberOfElements = 222;
    positions = [];
    angle = 0;


    $(".bg_canvas")[0].width = innerWidth; 
    $(".bg_canvas")[0].height = innerHeight;

    for (var i=0; i<numberOfElements; i++) {
        positions.push({x: Math.random()*innerWidth, y: Math.random()*innerHeight});
    };


    function animateCircles() {
        bgAnimation = requestAnimationFrame(animateCircles)
        ctx_bg.clearRect(0, 0, innerWidth, innerHeight);
        for (var i = 0; i < numberOfElements; i++){
            positions[i].y+=3;
            if (positions[i].y > innerHeight) {
                positions[i].y = 0;
            }
            // ctx_bg.drawImage($(".canvas_tile")[0], positions[i].x, positions[i].y);
            ctx_bg.drawImage($("#image_tile")[0], positions[i].x, positions[i].y);
        }
    }
    animateCircles()
})
body, html {
    padding: 0;
    margin: 0;
    width: 100%;
    height: 100%;
}
#image_tile, .canvas_tile  {
    display: none;
}
<!DOCTYPE html>

<html>
    <head>
        <title>KRAATER</title>
        <meta charset="UTF-8">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
    </head>
    <body>
        <img id="image_tile" src="https://www.gravatar.com/avatar/435af02114568dbaf00005b28c3ef592?s=48&d=identicon&r=PG">
        <canvas class="canvas_tile"></canvas>
        <canvas class="bg_canvas"></canvas>
    </body>
</html>

1 Ответ

0 голосов
/ 04 апреля 2020

Пока что я решил это с помощью хака, который сначала преобразует данные холста в изображение:

$("<img src='" + targetCanvas.toDataURL() + "'>");

Затем добавляю это в DOM и загружаю это изображение в большой холст. Не очень эффективно, так как при работе с большими объектами img рендеринг будет замедляться, поэтому я предлагаю использовать его только для рендеринга в размерах телефонов и использовать холст на холсте на рабочем столе.

Присвоит «принятый ответ» другому посту, который это не хак, если он придет.

Другое решение - зафиксировать положение основного холста и переместить контент на основе прокручиваемого количества, но оно будет иметь задержку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...