Animace kontur na vašich webových stránkách

... Petr Blahoš, 2. 1. 2018 ComputerVision JavaScript Python

V minulém příspěvku jsme si animovali kontury. Ovšem řekněme si otevřeně, v Pythonu můžeme udělat skript na generování videa, skript na úpravy čehokoliv v čemkoliv, ale jak říká klasik: Oh, yes, everything's wireless nowadays, isn't it. Takže s tím potřebujeme jít na web.

Naším cílem je vygenerovat kód, který bude na webové stránce provádět nějakou takovou animaci:

Začneme v Pythonu

Utrpení s HTML a Javascriptem chceme minimalizovat, proto si aspoň něco připravíme v Pythonu. Konkrétně ty kontury. Do našeho kódu z minula si jen přidáme vypsání těch dvojic kontur, ze které na kterou se posunujeme.

Upravím kód z minulého dílu tak, aby vypsal dvojice kontur, mezi kterými se bude interpolovat. Poté už se přesuneme do Javascriptu. Takže náš interpolate_shapes bude vypadat takto:

def interpolate_shapes(img_size, i0, i1):
    out_shape = img_size

    c1 = get_contour(i0, out_shape[1])
    c2 = get_contour(i1, out_shape[1])

    c1 = c1.reshape(c1.shape[0], c1.shape[-1])
    c2 = c2.reshape(c2.shape[0], c2.shape[-1])


    if c1.shape[0] < c2.shape[0]:
        c1 = enlarge_contour(c1, c2.shape[0])
    else:
        c2 = enlarge_contour(c2, c1.shape[0])

    print(
        "(\n"
        "    [%s],\n"
        "    [%s]\n"
        ");" % (
            ", ".join(["[%d,%d]" % (i[0], i[1]) for i in c1]),
            ", ".join(["[%d,%d]" % (i[0], i[1]) for i in c2]),
        ))

Hurá do WebBrowseru

Zbytek uděláme v Javascriptu a HTML. Budeme animovat v HTML canvasu.

Skript je překvapivě skoro stejně jednoduchý jako v tom Pythonu. Snad jen s tím rozdílem, že v javascriptu nám neudělá numpy operace s polem - ty tady musíme udělat prvek po prvku. Takže mezi dvěma konturami tam bude něco takového:

// před animací si připravíme pole s rozdílem mezi interpolovanými body
this.diff = [];
for (var i = 0;i < this.c1.length; i++) {
    var p0 = this.c1[i];
    var p1 = this.c2[i];
    this.diff.push([p1[0] - p0[0], p1[1] - p0[1]]);
}


// při animaci v každém kroku počítáme cílový bod
var step = timestamp - this.start;
var scale = this.scale;

var c1 = this.c1;

for (var i = 0;i < this.diff.length; i++) {
    var p0 = c1[i];
    var d = this.diff[i]
    c.push([p0[0] + d[0]*step/scale, p0[1] + d[1]*step/scale]);
}

Celé to obalíme do objektu, který bude animovat pomocí requestAnimationFrame. Zjednodušený skript najdete na zde na jsfiddle.

Závěr

Dnes to bylo rychlé. Když už jsme u těch kontur, tak příště zkusíme trochu jinou animaci.