видео на холсте продолжает изменять размер

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

Я попробовал идею этой публикации, и это, казалось, немного успокоило Chrome, но не помогло. влияет на Firefox.

Этот другой пост дал мне некоторые идеи, но все еще не исправил их. Похоже, я либо вызываю изменение размера несколько раз в цикле (чего я не вижу), либо контекст холста не знает, как установить окончательный размер. Любые идеи?

<!DOCTYPE html>

<html>
<head>
    <title>overflow</title>
<style>
#c {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
}
#hold {
    position: fixed;
}

#v {
    position: absolute;
    height: auto;
    width: 100%;
    z-index: 0;

}
#see {
    position: relative;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2;

}
</style>
</head>

<body>
<canvas id=c></canvas>

<div id=hold>
<video id=v>
</video>
</div>

<canvas id=see></canvas>


<script>
window.onload = start;

function start() {

    var v = document.getElementById('v');
    var house = document.getElementById('hold');
    var base = document.getElementById('c');
    var canvas = base.getContext('2d');
    var cover = document.getElementById('see');
    var canvastwo = cover.getContext('2d');


    v.src=("keyed.ogv")
    v.load();
    v.play();

    resize();

    function resize() {
        var wth = (window.innerWidth * 0.65);
        house.width = wth;
        house.height = (wth * 9/16);
        house.style.marginTop=((window.innerHeight/2) - (house.height/2) + "px");
        house.style.marginLeft=((window.innerWidth/2) - (house.width/2) + "px");
        cover.width = (wth/2);
        cover.height = (house.height/2);
        cover.style.marginTop=((window.innerHeight/2) - (cover.height/2) + "px");
        cover.style.marginLeft=((window.innerWidth/2) - (cover.width/2) + "px");
        var rw = cover.width;
        var rh = cover.height;

        canvastwo.clearRect(0, 0, rw, rh);
        draw(v, canvastwo, rw, rh);
    }

    window.onresize = resize;

function draw(o,j,w,h) {
    if(v.paused || v.ended) return false;
    j.drawImage(o,0,0,w,h);
    setTimeout(draw,20,o,j,w,h);
    }

}
</script>
</body>
</html>

person subtle cinema    schedule 20.07.2013    source источник
comment
событие изменения размера срабатывает много раз по какой-то причине. Даже когда я только вызываю функцию явно и перестаю слушать изменения размеров окна, дрожание все еще происходит. Обратите внимание, что это только поведение холста. Если я показываю видео, я могу изменять размер весь день без проблем.   -  person subtle cinema    schedule 21.07.2013


Ответы (1)


Кажется, вы фиксируете старые значения, которые вы используете для функции setTimeout, так же, как вы используете ее здесь, по мере изменения контекста. Таким образом, когда вы изменяете размер, цикл по-прежнему использует старые значения, которые больше не соответствуют новым размерам, и приводит к переключению видео между этими размерами.

Постарайтесь больше «глобализировать» значения, чтобы вызов цикла был чистым, когда дело доходит до аргументов. Таким образом, вы уверены, что переменные содержат правильные значения для каждого раунда.

Также замените setTimeout на requestAnimationFrame, чтобы сделать цикл более низкоуровневым (эффективным) и плавным, поскольку это синхронизируется с промежутком vblank монитора. Это особенно важно для видео, так как в противном случае вы получите пропуск кадров, так как setTimeout не может синхронизироваться с монитором.

Вот основной код, который вам нужно изменить:

/// put these into you start block to keep them "global"
/// for the functions within it.
var w, h;

Измените эту часть в функции resize:

/// ...
w = cover.width;
h = cover.height;

canvastwo.clearRect(0, 0, w, h);

/// argument free call to draw:
draw();

И, наконец, цикл:

function draw() {
    if(v.paused || v.ended) return false;
    canvastwo.drawImage(v,0,0,w,h);
    requestAnimationFrame(draw);
}

Это удалит дергающееся видео, а также сделает обновление синхронизированным с монитором, как это делает сам элемент видео.

ОНЛАЙН-ДЕМО

person Community    schedule 21.07.2013
comment
Спасибо. Я тоже очень оценил jsfiddle! (в следующий раз мне не потребуется столько исправления.) - person subtle cinema; 21.07.2013