primocode 10.16.0 → 10.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/edit-ia-pro.txt +32 -0
- package/LICENSES/fontes-OFL.txt +476 -0
- package/LICENSES/hyperframes-Apache-2.0.txt +205 -0
- package/LICENSES/permanent-marker-Apache-2.0.txt +204 -0
- package/LICENSES/selfie-multiclass-Apache-2.0.txt +227 -0
- package/LICENSES/three-MIT.txt +23 -0
- package/LICENSES/video-use-MIT.txt +24 -0
- package/LICENSES/woven-sfx-CC0.txt +16 -0
- package/LICENSES/yunet-MIT.txt +21 -0
- package/README.md +2 -2
- package/bin/primocode.js +28 -8
- package/editor/LICENSE.md +11 -0
- package/editor/README.md +321 -0
- package/editor/SKILL.md +307 -0
- package/editor/THIRD_PARTY_NOTICES.md +228 -0
- package/editor/assets/baixar.json +591 -0
- package/editor/assets/fonts/anton/OFL.txt +93 -0
- package/editor/assets/fonts/caveat/OFL.txt +93 -0
- package/editor/assets/fonts/figtree/OFL.txt +93 -0
- package/editor/assets/fonts/fonts.json +10 -0
- package/editor/assets/fonts/montserrat/OFL.txt +93 -0
- package/editor/assets/fonts/permanentmarker/LICENSE.txt +202 -0
- package/editor/assets/models/SELFIE_MULTICLASS_LICENSE.txt +227 -0
- package/editor/assets/models/YUNET_LICENSE.txt +21 -0
- package/editor/assets/sfx/licencas/bass_drop.txt +32 -0
- package/editor/assets/sfx/licencas/cash.txt +76 -0
- package/editor/assets/sfx/licencas/charge.txt +31 -0
- package/editor/assets/sfx/licencas/click.txt +46 -0
- package/editor/assets/sfx/licencas/coin.txt +50 -0
- package/editor/assets/sfx/licencas/count.txt +47 -0
- package/editor/assets/sfx/licencas/data.txt +31 -0
- package/editor/assets/sfx/licencas/error.txt +32 -0
- package/editor/assets/sfx/licencas/flash.txt +31 -0
- package/editor/assets/sfx/licencas/gears.txt +82 -0
- package/editor/assets/sfx/licencas/keyboard.txt +48 -0
- package/editor/assets/sfx/licencas/metal_hit.txt +62 -0
- package/editor/assets/sfx/licencas/metal_riser.txt +61 -0
- package/editor/assets/sfx/licencas/mouse_click.txt +50 -0
- package/editor/assets/sfx/licencas/notification.txt +54 -0
- package/editor/assets/sfx/licencas/pop.txt +38 -0
- package/editor/assets/sfx/licencas/rewind.txt +32 -0
- package/editor/assets/sfx/licencas/rise.txt +46 -0
- package/editor/assets/sfx/licencas/sinteticos.txt +21 -0
- package/editor/assets/sfx/licencas/snap.txt +50 -0
- package/editor/assets/sfx/licencas/success.txt +40 -0
- package/editor/assets/sfx/licencas/synth_hit.txt +32 -0
- package/editor/assets/sfx/licencas/tick.txt +14 -0
- package/editor/assets/sfx/licencas/whoosh.txt +47 -0
- package/editor/assets/sfx/licencas/wind.txt +31 -0
- package/editor/assets/sfx/sfx.json +832 -0
- package/editor/assets/sfx/sfx_sinteticos.json +317 -0
- package/editor/assets/sfx/sfx_woven.json +387 -0
- package/editor/assets/sfx/woven/LICENCA.md +16 -0
- package/editor/fichas/briefing-do-video.md +45 -0
- package/editor/fichas/conferencia-da-amostra.md +56 -0
- package/editor/fichas/matriz-de-ganchos.csv +3 -0
- package/editor/fichas/padrao.json +16 -0
- package/editor/fichas/planilha-de-cenas.csv +4 -0
- package/editor/fichas/planilha-de-versoes.csv +4 -0
- package/editor/fichas/plano-em-blocos.md +32 -0
- package/editor/fichas/registro-de-materiais.json +27 -0
- package/editor/helpers/assets_ocr/ocr_vision.swift +41 -0
- package/editor/helpers/bordas_precisas.py +272 -0
- package/editor/helpers/camera_viva.py +426 -0
- package/editor/helpers/captions.py +601 -0
- package/editor/helpers/common.py +308 -0
- package/editor/helpers/compose_final.py +3555 -0
- package/editor/helpers/conferir_corte.py +234 -0
- package/editor/helpers/conferir_dados.py +405 -0
- package/editor/helpers/contact_sheet.py +282 -0
- package/editor/helpers/corte_por_onda.py +433 -0
- package/editor/helpers/corte_seco.py +595 -0
- package/editor/helpers/denoise.py +971 -0
- package/editor/helpers/efeitos.py +408 -0
- package/editor/helpers/efeitos_gerar.py +159 -0
- package/editor/helpers/elevenlabs_api.py +442 -0
- package/editor/helpers/face_layout.py +570 -0
- package/editor/helpers/fetch_images.py +423 -0
- package/editor/helpers/ganho_por_trecho.py +214 -0
- package/editor/helpers/gen_image.py +312 -0
- package/editor/helpers/gen_music.py +316 -0
- package/editor/helpers/gen_sfx.py +148 -0
- package/editor/helpers/grade.py +307 -0
- package/editor/helpers/icloud.py +119 -0
- package/editor/helpers/make_sfx.py +940 -0
- package/editor/helpers/matte.py +1342 -0
- package/editor/helpers/medir_referencia.py +2232 -0
- package/editor/helpers/mixar_trilha.py +354 -0
- package/editor/helpers/montar_corte.py +295 -0
- package/editor/helpers/motion/__init__.py +13 -0
- package/editor/helpers/motion/engine.py +1915 -0
- package/editor/helpers/motion/registry.py +510 -0
- package/editor/helpers/motion/render.py +665 -0
- package/editor/helpers/motion/templates/barra_progresso.py +370 -0
- package/editor/helpers/motion/templates/carimbo.py +132 -0
- package/editor/helpers/motion/templates/checklist.py +271 -0
- package/editor/helpers/motion/templates/comentario_cta.py +380 -0
- package/editor/helpers/motion/templates/contador.py +222 -0
- package/editor/helpers/motion/templates/destaque.py +263 -0
- package/editor/helpers/motion/templates/etiqueta_preco.py +461 -0
- package/editor/helpers/motion/templates/grafico_barras.py +510 -0
- package/editor/helpers/motion/templates/grafico_linha.py +462 -0
- package/editor/helpers/motion/templates/notificacao.py +266 -0
- package/editor/helpers/motion/templates/palavra_impacto.py +410 -0
- package/editor/helpers/motion/templates/passos.py +321 -0
- package/editor/helpers/motion/templates/riscado.py +298 -0
- package/editor/helpers/motion/templates/selo_garantia.py +150 -0
- package/editor/helpers/motion_render.py +241 -0
- package/editor/helpers/motion_sugerir.py +961 -0
- package/editor/helpers/noise_check.py +134 -0
- package/editor/helpers/pack_transcripts.py +223 -0
- package/editor/helpers/palavras_na_onda.py +176 -0
- package/editor/helpers/plano_sfx.py +839 -0
- package/editor/helpers/portao.py +427 -0
- package/editor/helpers/preview_server.py +1177 -0
- package/editor/helpers/rastrear_rosto.py +298 -0
- package/editor/helpers/render_cut.py +1256 -0
- package/editor/helpers/respiros.py +89 -0
- package/editor/helpers/sincronizar_cameras.py +571 -0
- package/editor/helpers/speech_regions.py +423 -0
- package/editor/helpers/style_catalog.json +231 -0
- package/editor/helpers/style_samples.py +246 -0
- package/editor/helpers/tela_verde.py +2113 -0
- package/editor/helpers/text_render.py +2059 -0
- package/editor/helpers/texto_na_tela.py +366 -0
- package/editor/helpers/timeline_view.py +292 -0
- package/editor/helpers/tira_de_quadros.py +113 -0
- package/editor/helpers/transcribe.py +734 -0
- package/editor/helpers/transcribe_batch.py +129 -0
- package/editor/helpers/trilhas.py +1146 -0
- package/editor/helpers/trilhas_humores.json +66 -0
- package/editor/helpers/valores.py +187 -0
- package/editor/helpers/verify_cut.py +820 -0
- package/editor/helpers/voice_levels.py +233 -0
- package/editor/helpers/voz_check.py +386 -0
- package/editor/helpers/voz_limpa.py +81 -0
- package/editor/helpers/watch_preview.py +372 -0
- package/editor/modelo-projeto/LEIA.md +402 -0
- package/editor/modelo-projeto/assets/fontes/OFL-Caveat.txt +93 -0
- package/editor/modelo-projeto/assets/fontes/OFL-JetBrainsMono.txt +93 -0
- package/editor/modelo-projeto/assets/fontes/OFL-Montserrat.txt +93 -0
- package/editor/modelo-projeto/assets/fontes/larguras.json +1 -0
- package/editor/modelo-projeto/assets/three/BufferGeometryUtils.js +1438 -0
- package/editor/modelo-projeto/assets/three/GLTFLoader.js +4895 -0
- package/editor/modelo-projeto/assets/three/LICENSE +21 -0
- package/editor/modelo-projeto/assets/three/ORIGEM.txt +17 -0
- package/editor/modelo-projeto/assets/three/RoomEnvironment.js +185 -0
- package/editor/modelo-projeto/assets/three/three.core.min.js +6 -0
- package/editor/modelo-projeto/assets/three/three.module.min.js +6 -0
- package/editor/modelo-projeto/build.py +4828 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_antes_depois.html +199 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_arquivo.html +232 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_busca.html +315 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_comando.html +304 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_conversa.html +217 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_esquema.html +289 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_medidor.html +249 -0
- package/editor/modelo-projeto/compositions/cenas/2d/k2d_notas.html +233 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_caminho.html +197 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_explodida.html +152 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_tela.html +167 -0
- package/editor/modelo-projeto/compositions/cenas/3d/k3d_volume.html +124 -0
- package/editor/modelo-projeto/compositions/cenas/3d/motor-three.js +728 -0
- package/editor/modelo-projeto/compositions/cenas/LEIA.md +177 -0
- package/editor/modelo-projeto/ferramentas/medir_fontes.py +65 -0
- package/editor/modelo-projeto/ferramentas/pessoa_recortada.py +176 -0
- package/editor/modelo-projeto/ferramentas/rastrear_maos.py +189 -0
- package/editor/modelo-projeto/hyperframes.json +12 -0
- package/editor/modelo-projeto/package.json +11 -0
- package/editor/modelo-projeto/projeto.json +16 -0
- package/editor/preview/app.css +1009 -0
- package/editor/preview/app.js +2122 -0
- package/editor/preview/index.html +307 -0
- package/editor/pyproject.toml +23 -0
- package/editor/references/3d.md +236 -0
- package/editor/references/animacao-catalogo.md +672 -0
- package/editor/references/animacao.md +498 -0
- package/editor/references/comandos.md +92 -0
- package/editor/references/corte-seco-como-funciona.md +50 -0
- package/editor/references/corte-seco.md +88 -0
- package/editor/references/corte.md +290 -0
- package/editor/references/direcao-por-blocos.md +218 -0
- package/editor/references/enquadramento.md +654 -0
- package/editor/references/estilos-prontos.md +355 -0
- package/editor/references/estudio.md +100 -0
- package/editor/references/exemplo-eventos.json +67 -0
- package/editor/references/lettering.md +252 -0
- package/editor/references/modelos.md +494 -0
- package/editor/references/phase2.md +1007 -0
- package/editor/references/referencia-aplicar.md +203 -0
- package/editor/references/referencia-medir.md +375 -0
- package/editor/references/revisao.md +335 -0
- package/editor/references/som-e-trilha.md +146 -0
- package/editor/references/tabela-de-sons.md +130 -0
- package/editor/references/variacoes.md +234 -0
- package/editor/uv.lock +1141 -0
- package/lib/act.js +36 -8
- package/lib/catalogo.js +4 -0
- package/lib/chamada-torta.js +81 -0
- package/lib/editor-pro.js +786 -0
- package/lib/entrega.js +58 -0
- package/lib/estudio/conferencia-visual.js +76 -0
- package/lib/estudio/diretor.js +6 -1
- package/lib/estudio/exportar.js +3 -1
- package/lib/estudio/gosto.js +45 -4
- package/lib/estudio/index.js +8 -5
- package/lib/estudio/kit-ae/base.jsx +119 -13
- package/lib/estudio/kit-ae/cenas.jsx +47 -15
- package/lib/estudio/kit-ae/guarda.jsx +274 -0
- package/lib/estudio/kit-ae/primitivas.jsx +180 -24
- package/lib/estudio/maquina-diretor.js +61 -7
- package/lib/estudio/maquina-foto.js +177 -0
- package/lib/estudio/maquina-guarda.js +207 -0
- package/lib/estudio/maquina-layout.js +22 -1
- package/lib/estudio/maquina.js +60 -11
- package/lib/estudio/referencias.js +1 -1
- package/lib/estudio/visao/visao.swift +97 -0
- package/lib/estudio/visao.js +60 -0
- package/lib/local/cerebro.json +192 -6
- package/lib/local/motor.js +5 -2
- package/lib/mcp.js +105 -7
- package/lib/nuvem.js +11 -1
- package/lib/outra-pasta.js +1 -1
- package/lib/passagem.js +50 -0
- package/lib/perigo.js +29 -12
- package/lib/protecao.js +134 -0
- package/lib/sandbox.js +11 -4
- package/lib/titulo-conversa.js +46 -0
- package/lib/tools.js +3 -0
- package/lib/ui.js +1 -1
- package/package.json +3 -2
- package/skills/editar-meu-video/SKILL.md +6 -2
- package/skills/editar-video/SKILL.md +113 -0
- package/studio/pessoa.py +52 -0
- package/voz/primo_voz/app.py +43 -4
- package/voz/primo_voz/chat.html +17 -6
- package/voz/primo_voz/painel_dados.py +134 -0
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
function kPre(comp, P) { var g = { W: comp.width, H: comp.height, u: kU(comp), v: kVert(comp), cam: kBase(comp, P) }; g.cx = g.W / 2; g.cy = g.H / 2; return g; }
|
|
15
15
|
function kSobre(P) { return kLum(P.ac) > 0.5 ? '#14110F' : '#FFFFFF'; }
|
|
16
|
+
/* O cartão em destaque vem da paleta da cena (maquina.js, cartaoDestaque): o acento quando é cor; senão o brilho. Nunca preto solto. */
|
|
17
|
+
function kCardAc(P) { return P.cardAc || P.ac; }
|
|
18
|
+
function kSobreCard(P) { return P.sobreCardAc || kSobre(P); }
|
|
16
19
|
function kT(g, comp, P, str, y, o) {
|
|
17
20
|
o = o || {};
|
|
18
21
|
var t0 = o.t0 != null ? o.t0 : 0.14, W = g.W, H = g.H;
|
|
@@ -31,7 +34,13 @@ function kT(g, comp, P, str, y, o) {
|
|
|
31
34
|
}
|
|
32
35
|
return r;
|
|
33
36
|
}
|
|
34
|
-
|
|
37
|
+
/* Os itens da lista, sem repetir (o mesmo texto, ignorando caixa, acento e espaço, entra uma vez só): faltou item, a lista fica menor. */
|
|
38
|
+
function kChaveItem(s) { return String(s || '').toLowerCase().replace(/[\*\s.,;:!?]+/g, '').replace(/[áàâã]/g, 'a').replace(/[éê]/g, 'e').replace(/[í]/g, 'i').replace(/[óôõ]/g, 'o').replace(/[ú]/g, 'u').replace(/ç/g, 'c'); }
|
|
39
|
+
function kItens(d, padrao, n) {
|
|
40
|
+
var fonte = d.itens && d.itens.length ? d.itens : padrao, it = [], visto = {}, i;
|
|
41
|
+
for (i = 0; i < fonte.length && it.length < (n || 5); i++) { var k = kChaveItem(fonte[i]); if (!k || visto[k]) continue; visto[k] = 1; it.push(fonte[i]); }
|
|
42
|
+
return it;
|
|
43
|
+
}
|
|
35
44
|
function kEstrelaPts(r, ri) { var p = [], i; for (i = 0; i < 10; i++) { var a = -Math.PI / 2 + i * Math.PI / 5, rr = i % 2 ? ri : r; p.push([Math.cos(a) * rr, Math.sin(a) * rr]); } return p; }
|
|
36
45
|
function kContr(a, b) { var x = kLum(a) + 0.05, y = kLum(b) + 0.05; return x > y ? x / y : y / x; }
|
|
37
46
|
function kEsc(s) { return String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\r?\n/g, ' '); }
|
|
@@ -59,8 +68,10 @@ function cenaCinetico(comp, P, d) {
|
|
|
59
68
|
var disco = forma(comp, 'circulo', { x: g.cx, y: g.cy, w: Math.min(W, H) * 0.9, cor: P.card, parent: cam.no, nome: 'disco' });
|
|
60
69
|
for (i = 0; i < n; i++) {
|
|
61
70
|
var ti = Q(pal[i].t, 0.14 + i * passo), fim = i < n - 1 ? Math.max(ti + 0.22, Q(pal[i + 1].t, 0.14 + (i + 1) * passo) - 0.02) : comp.duration;
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
// a palavra tem que ficar INTEIRA e legível antes de sair (0,15 s de verdade: a cena nominal toca f× mais rápido); a letra
|
|
72
|
+
// que voa só entra se dá tempo de montar e ler
|
|
73
|
+
var modo = kEntradaQueCabe(modos[i % modos.length], pal[i].t, (i < n - 1 ? fim : comp.duration) - ti, 0.15 * (KIT.f || 1));
|
|
74
|
+
var r = texto(comp, (pal[i].kw ? '*' : '') + pal[i].t, { tamanho: (g.v ? 230 : 200) * u, cor: i % 3 == 2 ? P.ac : P.fg, corDestaque: P.ac, x: g.cx, y: g.cy, parent: cam.no, entrada: modo, t0: ti, largura: W * 0.84, maxLinhas: 1, sublinhado: false, fala: false, sobrepoe: true });
|
|
64
75
|
var j; for (j = 0; j < r.camadas.length; j++) if (i < n - 1) curva(kO(r.camadas[j]), [[fim, 100, null, 30], [fim + 0.06, 0, 60, null]]);
|
|
65
76
|
mola(kS(disco), ti, [88, 88], [100, 100], { quique: 0.5, dur: 0.45 });
|
|
66
77
|
som(ti, i % 2 ? 'tique' : 'pop', 0.55);
|
|
@@ -97,8 +108,8 @@ function cenaInterface(comp, P, d) {
|
|
|
97
108
|
var cx0 = sx + sw / 2 + 24 * u, cwid = ww / 2 - cx0 - 22 * u, k, vals = [d.valor || '+128', '4,9', '32'];
|
|
98
109
|
for (k = 0; k < 3; k++) {
|
|
99
110
|
var cw = (cwid - 2 * 18 * u) / 3, kx = cx0 + cw / 2 + k * (cw + 18 * u), ky = -wh / 2 + 160 * u, tk = Q(vals[k], T0 + 1.0 + k * 0.2);
|
|
100
|
-
var cd = forma(comp, 'retangulo', { x: kx, y: ky, w: cw, h: 130 * u, r: 24 * u, cor: k == 0 ? P
|
|
101
|
-
texto(comp, String(vals[k]), { fonte: P.fonteTitulo, tamanho: 46 * u, cor: k == 0 ?
|
|
111
|
+
var cd = forma(comp, 'retangulo', { x: kx, y: ky, w: cw, h: 130 * u, r: 24 * u, cor: k == 0 ? kCardAc(P) : P.bg, alfa: k == 0 ? 100 : 70, parent: frente, entrada: 'pop', t0: tk, quique: 0.6, nome: 'card' });
|
|
112
|
+
texto(comp, String(vals[k]), { fonte: P.fonteTitulo, tamanho: 46 * u, cor: k == 0 ? kSobreCard(P) : P.fg, x: kx, y: ky - 6 * u, parent: frente, entrada: 'palavra', t0: tk + 0.08, largura: cw * 0.86, maxLinhas: 1, sublinhado: false, livre: true, fala: false });
|
|
102
113
|
som(tk, 'pop', 0.5);
|
|
103
114
|
}
|
|
104
115
|
// gráfico de barras dentro da janela
|
|
@@ -152,8 +163,8 @@ function cenaCameraNulls(comp, P, d) {
|
|
|
152
163
|
for (i = 0; i < n; i++) {
|
|
153
164
|
var ox = v ? 0 : i * gap, oy = v ? i * gap : 0, ti = Q(it[i], 0.3 + i * passo);
|
|
154
165
|
ts.push(ti);
|
|
155
|
-
var c = forma(comp, 'retangulo', { x: ox, y: oy, w: pw, h: ph, r: 56 * u, cor: i % 2 ? P.card : P
|
|
156
|
-
var tc = i % 2 ? P.fg :
|
|
166
|
+
var c = forma(comp, 'retangulo', { x: ox, y: oy, w: pw, h: ph, r: 56 * u, cor: i % 2 ? P.card : kCardAc(P), parent: zoom, nome: 'painel' });
|
|
167
|
+
var tc = i % 2 ? P.fg : kSobreCard(P), ta = i % 2 ? P.ac : kSobreCard(P);
|
|
157
168
|
texto(comp, String(i + 1), { fonte: P.fonteTitulo, tamanho: 220 * u, cor: ta, corDestaque: ta, x: ox - pw * 0.28, y: oy - ph * 0.25, parent: zoom, entrada: 'palavra', t0: 0.3, largura: pw * 0.4, maxLinhas: 1, sublinhado: false, livre: true, fala: false });
|
|
158
169
|
elemento(comp, i, { x: ox + pw * 0.25, y: oy - ph * 0.22, w: pw * 0.38, parent: zoom, flutua: 8, fase: i });
|
|
159
170
|
texto(comp, it[i], { tamanho: 70 * u, cor: tc, corDestaque: ta, x: ox, y: oy + ph * 0.22, parent: zoom, entrada: 'mascara', t0: 0.4, largura: pw * 0.82, maxLinhas: 3, sublinhado: false, livre: true, fala: false });
|
|
@@ -185,7 +196,7 @@ function cenaBarras(comp, P, d) {
|
|
|
185
196
|
var tops = [];
|
|
186
197
|
for (i = 0; i < n; i++) {
|
|
187
198
|
var altura = ah * (0.2 + 0.8 * Math.pow((i + 1) / n, 1.5)), bx = area[0] + gap * (i + 0.5), ti = Q(it[i], T0 + 0.3 + i * 0.4), ult = i == n - 1;
|
|
188
|
-
var b = forma(comp, 'retangulo', { x: bx, y: area[3], w: bw, h: altura, r: 18 * u, cor: ult ? P
|
|
199
|
+
var b = forma(comp, 'retangulo', { x: bx, y: area[3], w: bw, h: altura, r: 18 * u, cor: ult ? kCardAc(P) : P.card, traco: ult ? null : P.mudo, tracoL: 3 * u, parent: cam.no, nome: 'barra' });
|
|
189
200
|
kA(b).setValue([0, altura / 2]);
|
|
190
201
|
mola(kS(b), ti, [100, 0], [100, 100], { quique: ult ? 0.7 : 0.4, dur: 0.7 });
|
|
191
202
|
som(ti, ult ? 'impacto' : 'pop', ult ? 0.8 : 0.55);
|
|
@@ -274,14 +285,14 @@ function cenaCardsPulam(comp, P, d) {
|
|
|
274
285
|
var cw = v ? W * 0.8 : W * 0.44, ch = Math.min(v ? H * 0.15 : H * 0.2, (H * 0.62) / n - 16 * u), top = v ? H * 0.31 : H * 0.5 - (n * (ch + 18 * u)) / 2 + ch / 2, cx0 = v ? g.cx : W * 0.72;
|
|
275
286
|
for (i = 0; i < n; i++) {
|
|
276
287
|
var y = top + i * (ch + 18 * u) + (v ? ch / 2 : 0), ti = Q(it[i], T0 + 0.3 + i * 0.42), ult = i == n - 1, rot = (i % 2 ? 1 : -1) * 5;
|
|
277
|
-
var c = forma(comp, 'retangulo', { x: cx0, y: y, w: cw, h: ch, r: 36 * u, cor: ult ? P
|
|
288
|
+
var c = forma(comp, 'retangulo', { x: cx0, y: y, w: cw, h: ch, r: 36 * u, cor: ult ? kCardAc(P) : P.card, traco: ult ? null : P.mudo, tracoL: 3 * u, parent: cam.no, nome: 'card' });
|
|
278
289
|
mola(kP(c), ti, [cx0 + (i % 2 ? 1 : -1) * 40 * u, y + H * 0.45], [cx0, y], { quique: 0.75, dur: 0.85 });
|
|
279
290
|
mola(kR(c), ti, rot * 2, 0, { quique: 0.6, dur: 0.9 });
|
|
280
291
|
curva(kO(c), [[ti - 0.04, 0, null, 30], [ti, 100, null, 30]]);
|
|
281
292
|
som(ti + 0.22, 'pop', 0.6);
|
|
282
293
|
var ex = cx0 - cw / 2 + ch * 0.62;
|
|
283
294
|
var ic = elemento(comp, i, { x: ex, y: y, w: ch * 0.78, parent: cam.no, entrada: 'pop', t0: ti + 0.3, quique: 0.7 });
|
|
284
|
-
texto(comp, it[i], { tamanho: Math.min(58 * u, ch * 0.42), cor: ult ?
|
|
295
|
+
texto(comp, it[i], { tamanho: Math.min(58 * u, ch * 0.42), cor: ult ? kSobreCard(P) : P.fg, corDestaque: ult ? kSobreCard(P) : P.ac, x: cx0 + ch * 0.4, y: y, parent: cam.no, entrada: 'sobe', t0: ti + 0.3, largura: cw - ch * 1.6, maxLinhas: 2, sublinhado: false, fala: false });
|
|
285
296
|
}
|
|
286
297
|
cam.empurra(0.8, 0, -10 * u, 1.03).empurra(comp.duration - 0.2, 0, 20 * u, 1.08);
|
|
287
298
|
fecha(comp);
|
|
@@ -314,20 +325,24 @@ function cenaCursor(comp, P, d) {
|
|
|
314
325
|
var bt = botao(comp, { x: px, y: by, w: bw, h: bh, rotulo: d.botao || 'Enviar', cor: P.ac, corTexto: kSobre(P), t0: T0 + 0.4, tam: 46 * u, parent: cam.no });
|
|
315
326
|
var cur = kCursor(comp, cam.no, u, P.fg, P.bg);
|
|
316
327
|
var tc = T0 + 0.9, txt = d.texto || d.sub || d.rotulo || 'o que você quer';
|
|
328
|
+
// o cursor é elemento: clica no fim do campo (o texto digitado nasce à esquerda) e na borda do botão, nunca em cima de letra
|
|
329
|
+
var xt0 = px - campoW / 2 + 36 * u, wt = Math.min(kMedir(comp, txt, P.fonteTexto, 42 * u), campoW * 0.86);
|
|
330
|
+
var pc = kCursorNoBotao(comp, [px - campoW / 2, cy1 - campoH / 2, px + campoW / 2, cy1 + campoH / 2], { x: xt0 + wt / 2, y: cy1, w: wt + 12 * u, h: 60 * u }, 0, 0, 1, [px + campoW * 0.34, cy1 + 6 * u], u);
|
|
331
|
+
var pb = kCursorNoBotao(comp, [px - bt.w / 2, by - bt.h / 2, px + bt.w / 2, by + bt.h / 2], bt.texto, 0, 0, 1, [px + bt.w / 2 - bt.h * 0.45, by + bt.h * 0.12], u);
|
|
317
332
|
kP(cur).setValue([px + pw * 0.6, py + ph * 0.9]);
|
|
318
|
-
curva(kP(cur), [[tc - 0.7, [px + pw * 0.6, py + ph * 0.9], null, 20], [tc,
|
|
333
|
+
curva(kP(cur), [[tc - 0.7, [px + pw * 0.6, py + ph * 0.9], null, 20], [tc, pc, 75, 30]]);
|
|
319
334
|
curva(kO(cur), [[tc - 0.7, 0, null, 30], [tc - 0.5, 100, 60, null]]);
|
|
320
335
|
curva(kS(cur), [[tc, [100, 100], null, 25], [tc + 0.07, [82, 82], 70, 40], [tc + 0.2, [100, 100], 70, null]]);
|
|
321
336
|
curva(kO(foco), [[tc, 0, null, 30], [tc + 0.12, 100, 60, null]]);
|
|
322
337
|
som(tc, 'clique', 0.8);
|
|
323
338
|
var dg = digita(comp, txt, { x: px - campoW / 2 + 36 * u, y: cy1, tamanho: 42 * u, fonte: P.fonteTexto, cor: P.fg, largura: campoW * 0.86, parent: cam.no, t0: tc + 0.25, cps: 26 });
|
|
324
339
|
var t2 = Math.max(dg.fim + 0.15, tc + 0.9);
|
|
325
|
-
curva(kP(cur), [[tc + 0.1,
|
|
340
|
+
curva(kP(cur), [[tc + 0.1, pc, null, 25], [t2, pb, 75, 30]]);
|
|
326
341
|
curva(kS(cur), [[t2, [100, 100], null, 25], [t2 + 0.07, [82, 82], 70, 40], [t2 + 0.2, [100, 100], 70, null]]);
|
|
327
342
|
bt.aperta(t2);
|
|
328
|
-
var res = forma(comp, 'pilula', { x: px, y: py + ph * 0.02, w: campoW * 0.9, h: 96 * u, cor: P
|
|
329
|
-
check(comp, { x: px - campoW * 0.36, y: py + ph * 0.02, tam: 44 * u, cor:
|
|
330
|
-
texto(comp, d.rotulo || 'Pronto!', { fonte: P.fonteTitulo, tamanho: 44 * u, cor:
|
|
343
|
+
var res = forma(comp, 'pilula', { x: px, y: py + ph * 0.02, w: campoW * 0.9, h: 96 * u, cor: kCardAc(P), parent: cam.no, entrada: 'pop', t0: t2 + 0.25, quique: 0.7, nome: 'resultado' });
|
|
344
|
+
check(comp, { x: px - campoW * 0.36, y: py + ph * 0.02, tam: 44 * u, cor: kSobreCard(P), parent: cam.no, t0: t2 + 0.4 });
|
|
345
|
+
texto(comp, d.rotulo || 'Pronto!', { fonte: P.fonteTitulo, tamanho: 44 * u, cor: kSobreCard(P), corDestaque: kSobreCard(P), x: px + 20 * u, y: py + ph * 0.02, parent: cam.no, entrada: 'sobe', t0: t2 + 0.3, largura: campoW * 0.6, maxLinhas: 1, sublinhado: false, livre: true, fala: false });
|
|
331
346
|
som(t2 + 0.28, 'brilho', 0.7);
|
|
332
347
|
curva(kO(cur), [[t2 + 0.7, 100, null, 30], [t2 + 0.95, 0, 60, null]]);
|
|
333
348
|
cam.empurra(0.8, 0, 0, 1.02).empurra(tc, 0, -10 * u, 1.06).empurra(t2 + 0.2, 0, 30 * u, 1.1).empurra(comp.duration - 0.2, 0, 40 * u, 1.12);
|
|
@@ -687,8 +702,29 @@ function cenaParedeLogos(comp, P, d) {
|
|
|
687
702
|
}
|
|
688
703
|
}
|
|
689
704
|
kR(par).setValue(-8);
|
|
690
|
-
var
|
|
691
|
-
|
|
705
|
+
var pw0 = W * (v ? 0.88 : 0.62), ph0 = H * (v ? 0.2 : 0.26);
|
|
706
|
+
var plaquinha = forma(comp, 'retangulo', { x: g.cx, y: g.cy, w: pw0, h: ph0, r: 48 * u, cor: P.bg, traco: P.ac, tracoL: 8 * u, parent: cam.no, nome: 'faixa' });
|
|
707
|
+
var n0 = comp.numLayers;
|
|
708
|
+
var tt = kT(g, comp, P, d.titulo || '', g.cy, { maxLinhas: 2, tam: v ? 84 : 72, t0: T0 + 0.8, largura: W * (v ? 0.8 : 0.56), sobrepoe: true });
|
|
709
|
+
// texto dentro de cartão, pela guarda: cabe com folga; senão o corpo encolhe até o mínimo; senão a faixa cresce (o texto
|
|
710
|
+
// principal ganha linha e "PrimoCode" e "de bolso" vazavam da faixa fixa)
|
|
711
|
+
if (tt && tt.h) {
|
|
712
|
+
var tc = [tt.x - tt.w / 2, tt.y - tt.h / 2, tt.x + tt.w / 2, tt.y + tt.h / 2], pc = [g.cx - pw0 / 2, g.cy - ph0 / 2, g.cx + pw0 / 2, g.cy + ph0 / 2];
|
|
713
|
+
var tMin = (H / W > 1.6 ? 112 : H * 0.036) * KIT.ajuste * KIT.ajusteCena; // o piso do texto() (principal no 9:16, 3,6% fora)
|
|
714
|
+
var gc = gTextoNoCartao(tc, pc, { folga: 55 * u, kMin: Math.min(1, tMin / Math.max(1, tt.tam)), max: [W * 0.03, H * 0.1, W * 0.97, H * 0.9] });
|
|
715
|
+
if (gc.k < 0.999) { // o corpo encolhe em volta do centro do bloco: cada camada criada pelo título (palavras, sublinhado)
|
|
716
|
+
var j0, cxT = tt.x, cyT = tt.y;
|
|
717
|
+
for (j0 = 1; j0 <= comp.numLayers - n0; j0++) { var Lt = comp.layer(j0), pv = kP(Lt).valueAtTime(comp.duration, false); kDesloca(Lt, (pv[0] - cxT) * (gc.k - 1), (pv[1] - cyT) * (gc.k - 1), gc.k); }
|
|
718
|
+
}
|
|
719
|
+
if (gc.cresceu) {
|
|
720
|
+
var pw = gW(gc.cartao), ph = gH(gc.cartao);
|
|
721
|
+
try { plaquinha.property('ADBE Root Vectors Group').property(1).property('ADBE Vectors Group').property('ADBE Vector Shape - Rect').property('ADBE Vector Rect Size').setValue([pw, ph]); }
|
|
722
|
+
catch (e) { kS(plaquinha).setValue([100 * pw / pw0, 100 * ph / ph0]); }
|
|
723
|
+
kP(plaquinha).setValue([gCx(gc.cartao), gCy(gc.cartao)]);
|
|
724
|
+
}
|
|
725
|
+
if (gc.log.length) writeLn('GUARDA ' + JSON.stringify({ cena: KIT.cenaIdx, w: W, h: H, log: gc.log, caixas: [{ tipo: 'cartao', nome: 'faixa do título', c: [Math.round(gc.cartao[0]), Math.round(gc.cartao[1]), Math.round(gc.cartao[2]), Math.round(gc.cartao[3])], fora: 0 }], violacoes: gc.ok ? [] : ['título maior que a faixa máxima'] }));
|
|
726
|
+
}
|
|
727
|
+
kEntrada(plaquinha, T0 + 0.7, 'pop', 0.5);
|
|
692
728
|
som(T0, 'sobe', 0.5); som(T0 + 0.7, 'impacto', 0.7);
|
|
693
729
|
cam.empurra(0.8, 0, 0, 1.0).empurra(comp.duration - 0.2, 0, 0, 1.08);
|
|
694
730
|
fecha(comp);
|
|
@@ -719,10 +755,10 @@ function cenaPrompt(comp, P, d) {
|
|
|
719
755
|
for (i = 0; i < n; i++) {
|
|
720
756
|
var ry = by + 70 * u + rh / 2 + i * (rh + 14 * u), ti = Q(it[i], tr + i * 0.2);
|
|
721
757
|
ti = Math.max(ti, tr);
|
|
722
|
-
forma(comp, 'retangulo', { x: px, y: ry, w: iw, h: rh, r: 26 * u, cor: i == 0 ? P
|
|
758
|
+
forma(comp, 'retangulo', { x: px, y: ry, w: iw, h: rh, r: 26 * u, cor: i == 0 ? kCardAc(P) : P.bg, parent: cam.no, entrada: 'pop', t0: ti, quique: 0.7, nome: 'resultado' });
|
|
723
759
|
if (v) elemento(comp, i, { x: px - iw / 2 + rh * 0.7, y: ry, w: rh * 0.7, parent: cam.no, entrada: 'pop', t0: ti + 0.06 }); // em 16:9 a linha é baixa: só o texto e o check (ícone de 12% da largura não cabe)
|
|
724
|
-
texto(comp, it[i], { tamanho: Math.min(40 * u, rh * 0.45), cor: i == 0 ?
|
|
725
|
-
check(comp, { x: px + iw / 2 - rh * 0.6, y: ry, tam: rh * 0.34, cor: i == 0 ?
|
|
760
|
+
texto(comp, it[i], { tamanho: Math.min(40 * u, rh * 0.45), cor: i == 0 ? kSobreCard(P) : P.fg, corDestaque: P.ac, x: px + rh * 0.3, y: ry, parent: cam.no, entrada: 'sobe', t0: ti + 0.1, largura: iw - rh * 2, maxLinhas: 1, sublinhado: false, fala: false });
|
|
761
|
+
check(comp, { x: px + iw / 2 - rh * 0.6, y: ry, tam: rh * 0.34, cor: i == 0 ? kSobreCard(P) : P.ac, parent: cam.no, t0: ti + 0.25 });
|
|
726
762
|
som(ti, 'notif', 0.6);
|
|
727
763
|
}
|
|
728
764
|
cam.empurra(0.8, 0, 0, 1.02).empurra(tr, 0, 20 * u, 1.06).empurra(comp.duration - 0.2, 0, 30 * u, 1.1);
|
|
@@ -829,9 +865,9 @@ function cenaLeque(comp, P, d) {
|
|
|
829
865
|
var ang = (i - (n - 1) / 2) * spread, ti = Q(it[i], T0 + 0.35 + i * 0.28), ult = i == n - 1;
|
|
830
866
|
var carta = grupo(comp, { x: px, y: py, parent: cam.no, nome: 'carta' });
|
|
831
867
|
kA(carta).setValue([0, 0]);
|
|
832
|
-
var c = forma(comp, 'retangulo', { x: 0, y: -ch * 0.78, w: cw, h: ch, r: 34 * u, cor: ult ? P
|
|
868
|
+
var c = forma(comp, 'retangulo', { x: 0, y: -ch * 0.78, w: cw, h: ch, r: 34 * u, cor: ult ? kCardAc(P) : P.card, traco: ult ? null : P.mudo, tracoL: 3 * u, parent: carta, nome: 'carta-corpo' });
|
|
833
869
|
elemento(comp, i, { x: 0, y: -ch * 0.95, w: cw * 0.6, parent: carta });
|
|
834
|
-
texto(comp, it[i], { fonte: P.fonteTexto, tamanho: 36 * u, cor: ult ?
|
|
870
|
+
texto(comp, it[i], { fonte: P.fonteTexto, tamanho: 36 * u, cor: ult ? kSobreCard(P) : P.fg, corDestaque: P.ac, x: 0, y: -ch * 0.52, parent: carta, entrada: 'fade', t0: ti, largura: cw * 0.84, maxLinhas: 2, sublinhado: false, fala: false, livre: true });
|
|
835
871
|
mola(kR(carta), ti - 0.1, 0, ang, { quique: 0.55, dur: 0.8 });
|
|
836
872
|
curva(kO(carta), [[ti - 0.14, 0, null, 30], [ti - 0.1, 100, null, 30]]);
|
|
837
873
|
som(ti, 'papel', 0.6);
|
|
@@ -865,8 +901,10 @@ function cenaRolagem(comp, P, d) {
|
|
|
865
901
|
var cw = v ? W * 0.8 : W * 0.38, ch = v ? H * 0.2 : H * 0.28, gap = 28 * u, x = v ? g.cx : W * 0.7;
|
|
866
902
|
var feed = grupo(comp, { x: x, y: 0, parent: cam.no, nome: 'feed' });
|
|
867
903
|
var total = n * (ch + gap), y0 = v ? H * 0.3 : H * 0.14, tl = T0 + 0.2, dd = 1.3;
|
|
868
|
-
|
|
869
|
-
|
|
904
|
+
// no 9:16 com título, o feed sobe UM cartão: começa um cartão abaixo do topo do conteúdo (Ct do kT) pra nunca passar por baixo do título
|
|
905
|
+
if (v && d.titulo) y0 = H * 0.2 + gap + (ch + gap);
|
|
906
|
+
for (i = 0; i < n; i++) { // um post por item: nada de repetir o primeiro no fim pra encher o feed
|
|
907
|
+
var y = y0 + i * (ch + gap) + ch / 2, idx = i;
|
|
870
908
|
forma(comp, 'retangulo', { x: 0, y: y, w: cw, h: ch, r: 36 * u, cor: P.card, traco: P.mudo, tracoL: 3 * u, parent: feed, nome: 'post' });
|
|
871
909
|
elemento(comp, i, { x: -cw / 2 + ch * 0.55, y: y, w: ch * 0.7, parent: feed });
|
|
872
910
|
texto(comp, it[idx], { tamanho: Math.min(44 * u, ch * 0.28), cor: P.fg, corDestaque: P.ac, x: ch * 0.28, y: y - ch * 0.12, parent: feed, entrada: 'fade', t0: T0, largura: cw - ch * 1.5, maxLinhas: 2, sublinhado: false, fala: false, livre: true });
|
|
@@ -909,3 +947,121 @@ function cenaEstrelas(comp, P, d) {
|
|
|
909
947
|
cam.empurra(0.8, 0, 0, 1.02).empurra(comp.duration - 0.2, 0, 0, 1.08);
|
|
910
948
|
fecha(comp);
|
|
911
949
|
}
|
|
950
|
+
|
|
951
|
+
// ---------------------------------------------------------------- 31. foto: a foto do pedido em 3 planos, em 3D, com passeio de câmera
|
|
952
|
+
/* d.foto = {arquivo, fundo, recorte, w, h, moldura} (o Node já copiou pro projeto, desfocou o fundo e tentou o recorte);
|
|
953
|
+
d.movimento (aproxima · passeio · revela · orbita · afasta) é o que o diretor sorteou a partir da câmera da cena, e
|
|
954
|
+
d.sentido (±1) alterna entre fotos seguidas. Planos: 1) o fundo desfocado e ampliado, 2) a foto (recorte com alfa, ou a foto
|
|
955
|
+
inteira numa moldura arredondada que é uma comp própria: o passeio acontece DENTRO da moldura), em 3D com rotação,
|
|
956
|
+
3) elementos reais na frente, que andam mais que a foto (parallax). Tudo com ease: nada linear. */
|
|
957
|
+
function kFotoImp(arq) {
|
|
958
|
+
if (!arq) return null;
|
|
959
|
+
KIT.cache = KIT.cache || {};
|
|
960
|
+
if (KIT.cache[arq]) return KIT.cache[arq];
|
|
961
|
+
try { var it = app.project.importFile(new ImportOptions(new File(arq))); KIT.cache[arq] = it; return it; }
|
|
962
|
+
catch (er) { KIT.avisos.push('cena ' + KIT.cenaIdx + ': a foto não abriu: ' + arq); return null; }
|
|
963
|
+
}
|
|
964
|
+
function kFotoPonto(cw, ch, pan, z, fx, fy) { var lim = (z - 1) / 2 * pan; return [cw / 2 - fx * lim * cw, ch / 2 - fy * lim * ch]; }
|
|
965
|
+
function kRot(L, eixo) { return L.property('ADBE Transform Group').property('ADBE Rotate ' + eixo); }
|
|
966
|
+
function cenaFoto(comp, P, d) {
|
|
967
|
+
var F = d.foto, itF = F ? kFotoImp(F.recorte || F.arquivo) : null;
|
|
968
|
+
if (!itF) { KIT.avisos.push('cena ' + KIT.cenaIdx + ': sem foto, a cena virou herói'); return cenaHeroi(comp, P, d); }
|
|
969
|
+
var g = kPre(comp, P), W = g.W, H = g.H, u = g.u, cam = g.cam, v = g.v, T0 = 0.1, i, dur = comp.duration;
|
|
970
|
+
var mov = d.movimento || 'aproxima', sg = d.sentido || 1, recorte = !!F.recorte;
|
|
971
|
+
var ease = [60, 60];
|
|
972
|
+
// 1. o plano de trás: a própria foto desfocada, ampliada, com um véu da cor da cena; anda ao contrário da foto
|
|
973
|
+
var itB = F.fundo ? kFotoImp(F.fundo) : null;
|
|
974
|
+
if (itB) {
|
|
975
|
+
var bg = comp.layers.add(itB); bg.name = 'foto-fundo'; // sem pai: a câmera encolhe o quadro (88%) e deixaria borda; o fundo tem o movimento dele
|
|
976
|
+
var kb = Math.max(W / itB.width, H / itB.height) * 100;
|
|
977
|
+
kP(bg).setValue([g.cx, g.cy]);
|
|
978
|
+
curva(kS(bg), [[0, [kb * 1.32, kb * 1.32], ease[0], ease[1]], [dur, [kb * 1.5, kb * 1.5], ease[0], ease[1]]]);
|
|
979
|
+
curva(kP(bg), [[0, [g.cx + sg * W * 0.035, g.cy], ease[0], ease[1]], [dur, [g.cx - sg * W * 0.035, g.cy - H * 0.01], ease[0], ease[1]]]);
|
|
980
|
+
var veu = comp.layers.addSolid(kCor(P.bg), 'foto-veu', W, H, 1); kO(veu).setValue(40);
|
|
981
|
+
}
|
|
982
|
+
// 2. a foto: o tamanho da caixa respeita a proporção dela (nada cortado) e a zona do texto
|
|
983
|
+
var fw = recorte ? (F.rw || F.w) : F.w, fh = recorte ? (F.rh || F.h) : F.h; // o recorte já vem aparado: só a pessoa
|
|
984
|
+
var LY = d.layout || null; // o plano da GUARDA (maquina-guarda.js): foto grande, título sem encostar, ícones só no espaço livre
|
|
985
|
+
var bx = v ? W * (recorte ? 0.9 : 0.8) : W * 0.4, by = v ? H * (recorte ? 0.5 : 0.46) : H * (recorte ? 0.84 : 0.74);
|
|
986
|
+
var cwf = Math.min(bx, by * fw / fh), chf = cwf * fh / fw;
|
|
987
|
+
var px = v ? g.cx : W * 0.3, py = recorte ? (v ? H * 0.64 - chf / 2 : H * 0.9 - chf / 2) : (v ? H * 0.38 : g.cy);
|
|
988
|
+
var corte = 1; // a parte da altura que aparece (foto alta cortada em 4:5 pela guarda)
|
|
989
|
+
if (LY && LY.foto) { cwf = LY.foto.w; chf = LY.foto.h; px = LY.foto.x; py = LY.foto.y; corte = LY.foto.corte || 1; }
|
|
990
|
+
var halo;
|
|
991
|
+
if (LY && LY.halo && LY.halo.d) halo = forma(comp, 'circulo', { x: LY.halo.x, y: LY.halo.y, w: LY.halo.d, cor: P.ac, alfa: 70, parent: cam.no, entrada: 'cresce', t0: T0, nome: 'halo' });
|
|
992
|
+
else if (LY && LY.halo) halo = forma(comp, 'retangulo', { x: LY.halo.x, y: LY.halo.y, w: LY.halo.w, h: LY.halo.h, r: 46 * u, cor: P.ac, alfa: 34, parent: cam.no, entrada: 'cresce', t0: T0, nome: 'halo' });
|
|
993
|
+
else halo = forma(comp, 'circulo', { x: px, y: py, w: Math.max(cwf, chf) * (recorte ? 0.95 : 1.05), cor: P.ac, alfa: recorte ? 70 : 26, parent: cam.no, entrada: 'cresce', t0: T0, nome: 'halo' });
|
|
994
|
+
var card, kBase0;
|
|
995
|
+
if (recorte) {
|
|
996
|
+
card = comp.layers.add(itF); card.name = 'foto-recorte'; kPai(card, cam.no);
|
|
997
|
+
kBase0 = cwf / itF.width * 100;
|
|
998
|
+
kA(card).setValue([itF.width / 2, itF.height * corte / 2]);
|
|
999
|
+
// o corte da foto (ombros e braços na beira, ou o corpo abaixo do 4:5) some num degradê: a pessoa não termina numa linha reta
|
|
1000
|
+
try { var mk = card.property('ADBE Mask Parade').addProperty('ADBE Mask Atom'); mk.property('ADBE Mask Shape').setValue(kRetShape(itF.width * 0.02, -itF.height, itF.width * 0.98, itF.height * corte * 0.96, 0)); mk.property('ADBE Mask Feather').setValue([itF.width * 0.05, itF.height * corte * 0.12]); } catch (eM) { }
|
|
1001
|
+
} else {
|
|
1002
|
+
var inner = novaComp('foto-int ' + KIT.cenaIdx, Math.round(cwf), Math.round(chf), dur, KIT.fps);
|
|
1003
|
+
var im = inner.layers.add(itF); im.name = 'foto-img';
|
|
1004
|
+
var ki = Math.max(cwf / itF.width, chf / itF.height) * 100;
|
|
1005
|
+
kP(im).setValue([cwf / 2, chf / 2]);
|
|
1006
|
+
// o passeio DENTRO da moldura (ease, nunca linear): escala e deslocamento por movimento
|
|
1007
|
+
var z0 = 1, z1 = 1.2, x0 = 0, x1 = 0, y0 = 0, y1 = 0, pan = 0.8;
|
|
1008
|
+
if (mov == 'aproxima') { z0 = 1.0; z1 = 1.3; y0 = 0; y1 = -0.06; }
|
|
1009
|
+
else if (mov == 'passeio') { z0 = 1.26; z1 = 1.26; x0 = -sg * 0.5; x1 = sg * 0.5; y0 = 0.25; y1 = -0.25; }
|
|
1010
|
+
else if (mov == 'revela') { z0 = 1.45; z1 = 1.05; x0 = sg * 0.2; x1 = 0; y0 = 0.3; y1 = 0; }
|
|
1011
|
+
else if (mov == 'orbita') { z0 = 1.08; z1 = 1.22; x0 = -sg * 0.25; x1 = sg * 0.25; }
|
|
1012
|
+
else if (mov == 'afasta') { z0 = 1.34; z1 = 1.0; y0 = -0.12; y1 = 0.0; }
|
|
1013
|
+
curva(kS(im), [[0, [ki * z0, ki * z0], ease[0], ease[1]], [T0 + 0.9 * dur / 3, [ki * (z0 + (z1 - z0) * 0.5), ki * (z0 + (z1 - z0) * 0.5)], ease[0], ease[1]], [dur, [ki * z1, ki * z1], ease[0], ease[1]]]);
|
|
1014
|
+
curva(kP(im), [[0, kFotoPonto(cwf, chf, pan, z0, x0, y0), ease[0], ease[1]], [dur, kFotoPonto(cwf, chf, pan, z1, x1, y1), ease[0], ease[1]]]);
|
|
1015
|
+
card = comp.layers.add(inner); card.name = 'foto-moldura'; kPai(card, cam.no);
|
|
1016
|
+
kMascaraRect(card, 0, 0, cwf, chf, 38 * u);
|
|
1017
|
+
kBase0 = 100;
|
|
1018
|
+
}
|
|
1019
|
+
kP(card).setValue([px, py]);
|
|
1020
|
+
kS(card).setValue([kBase0, kBase0]);
|
|
1021
|
+
if (recorte) { // o recorte anda e cresce no próprio plano (a foto inteira não tem moldura onde passear)
|
|
1022
|
+
// com a guarda (LY) o passeio é mais curto na escala e no deslocamento: a foto fica GRANDE e o 3D (rotação) leva o movimento
|
|
1023
|
+
var rzA = LY ? 0.97 : 0.94, rzB = LY ? 1.06 : 1.12, rzC = LY ? 1.06 : 1.1, dxF = LY ? 0.025 : 0.04, dyF = LY ? 0.015 : 0.03;
|
|
1024
|
+
var rz1 = mov == 'afasta' || mov == 'revela' ? rzA : rzC, rz0 = mov == 'afasta' || mov == 'revela' ? rzB : 1.0;
|
|
1025
|
+
curva(kS(card), [[0, [kBase0 * rz0, kBase0 * rz0], ease[0], ease[1]], [dur, [kBase0 * rz1, kBase0 * rz1], ease[0], ease[1]]]);
|
|
1026
|
+
if (mov == 'passeio' || mov == 'orbita') curva(kP(card), [[0, [px - sg * W * dxF, py], ease[0], ease[1]], [dur, [px + sg * W * dxF, py], ease[0], ease[1]]]);
|
|
1027
|
+
else curva(kP(card), [[0, [px, py + H * dyF], ease[0], ease[1]], [dur, [px, py - H * dyF / 3], ease[0], ease[1]]]);
|
|
1028
|
+
}
|
|
1029
|
+
// sombra no chão e entrada: a foto chega girando e assenta (a rotação é o 3D; a mola é a entrada)
|
|
1030
|
+
var sombra = LY ? sombraChao(comp, px, py + chf * 0.5 - 30 * u, cwf * 0.5, { parent: cam.no, t0: T0 + 0.25, alfa: 22 }) // com a guarda: a sombra fica no envelope da foto
|
|
1031
|
+
: sombraChao(comp, px, py + chf * 0.5 + 18 * u, cwf * 0.7, { parent: cam.no, t0: T0 + 0.25, alfa: 28 });
|
|
1032
|
+
curva(kO(card), [[T0, 0, null, 30], [T0 + 0.3, 100, 60, null]]);
|
|
1033
|
+
kMarcaEntrada(T0 + 0.3);
|
|
1034
|
+
try {
|
|
1035
|
+
card.threeDLayer = true;
|
|
1036
|
+
var A = (mov == 'aproxima') ? [[-22, -7, 5], [8, 3, -2]] : (mov == 'passeio') ? [[-12, 0, 0], [12, 4, 0]] : (mov == 'revela') ? [[60, 0, 16], [0, 0, 0]] : (mov == 'orbita') ? [[-34, 0, 4], [34, 0, -2]] : [[14, 0, -12], [0, 0, 0]];
|
|
1037
|
+
var tm = Math.min(dur * 0.55, T0 + 0.95);
|
|
1038
|
+
curva(kRot(card, 'Y'), [[0, A[0][0] * sg, ease[0], ease[1]], [mov == 'passeio' || mov == 'orbita' ? dur : tm, (mov == 'passeio' || mov == 'orbita' ? A[1][0] : (A[0][0] + A[1][0]) / 2 * 0.4) * sg, ease[0], ease[1]], [dur, A[1][0] * sg, ease[0], ease[1]]]);
|
|
1039
|
+
curva(kRot(card, 'X'), [[0, A[0][2], ease[0], ease[1]], [dur, A[1][2], ease[0], ease[1]]]);
|
|
1040
|
+
} catch (e) { KIT.avisos.push('cena ' + KIT.cenaIdx + ': 3D da foto indisponível: ' + e); }
|
|
1041
|
+
som(T0, 'impacto', 0.6); som(T0 + 0.5, 'sobe', 0.45);
|
|
1042
|
+
// 3. na frente: elementos reais do assunto, que andam mais que a foto (parallax)
|
|
1043
|
+
var nEl = Math.min(KIT.elementos.length, v ? 3 : 2), S = Math.min(W, H) * (v ? 0.2 : 0.24);
|
|
1044
|
+
var posV = [[W * 0.2, H * 0.17], [W * 0.84, H * 0.5], [W * 0.18, H * 0.58]], posH = [[W * 0.54, H * 0.2], [W * 0.5, H * 0.8]];
|
|
1045
|
+
var ics = [];
|
|
1046
|
+
if (LY && LY.icones) { for (i = 0; i < LY.icones.length; i++) if (!LY.icones[i].fora) ics.push({ i: LY.icones[i].i, x: LY.icones[i].x, y: LY.icones[i].y, w: LY.icones[i].w }); }
|
|
1047
|
+
else for (i = 0; i < nEl; i++) ics.push({ i: i, x: (v ? posV[i] : posH[i])[0], y: (v ? posV[i] : posH[i])[1], w: S });
|
|
1048
|
+
for (i = 0; i < ics.length; i++) {
|
|
1049
|
+
var ph = ics[i].i * 1.9, a = 12 * u, kx = (ics[i].i % 2 ? -1 : 1) * W * 0.05;
|
|
1050
|
+
// o envelope do balanço vai pra caixa (folga): a guarda do kit reserva o caminho inteiro do ícone
|
|
1051
|
+
var el = elemento(comp, ics[i].i, { x: ics[i].x, y: ics[i].y, w: ics[i].w, parent: cam.no, entrada: 'pop', t0: T0 + 0.55 + i * 0.18, quique: 0.7, folgaX: a + Math.abs(kx), folgaY: a * 1.1 });
|
|
1052
|
+
kP(el).expression = 'value + [Math.sin(time*1.7+' + ph.toFixed(1) + ')*' + a.toFixed(1) + ' + ' + (sg * kx).toFixed(1) + ' * (time / ' + dur.toFixed(2) + ' - 0.5) * 2, Math.cos(time*1.3+' + ph.toFixed(1) + ')*' + (a * 1.1).toFixed(1) + ']';
|
|
1053
|
+
}
|
|
1054
|
+
if (d.titulo) {
|
|
1055
|
+
var TY = LY && LY.titulo;
|
|
1056
|
+
kT(g, comp, P, d.titulo, TY ? TY.y : (v ? H * 0.79 : g.cy), { x: TY ? TY.x : (v ? g.cx : W * 0.73), largura: TY ? TY.largura : (v ? W * 0.86 : W * 0.42), maxLinhas: 3, tam: TY ? TY.tam : (v ? 86 : 74), t0: T0 + 0.7 });
|
|
1057
|
+
}
|
|
1058
|
+
// a foto entra na guarda do kit (fecha → kGuarda) com a caixa do envelope: se o texto real encostar, ela sobe ou encolhe
|
|
1059
|
+
if (LY && LY.particulas) {
|
|
1060
|
+
var ec = LY.particulas;
|
|
1061
|
+
KIT.rects.push({ espaco: 'c', cena: KIT.cenaIdx, x0: ec[0], y0: ec[1], x1: ec[2], y1: ec[3], t0: 0, t1: 1, texto: false, livre: true, sobrepoe: true, guarda: 'foto', nome: 'a foto', camadas: [card, halo, sombra], infla: (ec[2] - ec[0]) / Math.max(1, cwf) });
|
|
1062
|
+
}
|
|
1063
|
+
var pa = LY && LY.particulas ? [LY.particulas[0], LY.particulas[1], LY.particulas[2], LY.particulas[3]] : [px - cwf * 0.6, py - chf * 0.6, px + cwf * 0.6, py + chf * 0.5];
|
|
1064
|
+
particulas(comp, { n: 10, cor: P.ac, parent: cam.no, tipo: 'flutua', raio: 8, area: pa, alfa: 70, t0: T0 + 0.4 });
|
|
1065
|
+
cam.empurra(0.8, 0, 0, 1.0).empurra(comp.duration - 0.2, 0, 0, 1.06);
|
|
1066
|
+
fecha(comp);
|
|
1067
|
+
}
|
|
@@ -58,12 +58,18 @@ const PRIMITIVAS = {
|
|
|
58
58
|
split: { fam: 'comparacao', entra: 2.6, papeis: ['problema', 'virada'], dur: 3.2, elemento: true },
|
|
59
59
|
ondas: { fam: 'som', entra: 1.0, papeis: ['gancho', 'processo', 'virada'], dur: 2.8, elemento: true },
|
|
60
60
|
estrelas: { fam: 'social', entra: 2.7, papeis: ['prova'], dur: 3.2, elemento: true },
|
|
61
|
+
// a foto do pedido (maquina-foto.js): só entra quando há foto; o sorteio comum nunca a escolhe
|
|
62
|
+
foto: { fam: 'foto', entra: 1.6, papeis: ['gancho', 'virada', 'prova', 'processo'], dur: 3.4, foto: true },
|
|
61
63
|
};
|
|
62
64
|
const TIPOS = Object.keys(PRIMITIVAS);
|
|
63
65
|
|
|
64
66
|
const TRANSICOES = ['encolhe', 'empurra', 'zoom', 'persiana', 'chicote', 'desfoque', 'cortina', 'giro', 'tremor', 'abre', 'dissolve', 'corte']; // sem íris/pontos: o círculo claro crescendo parecia flash
|
|
65
67
|
const CAMERAS = ['deriva', 'pulso', 'trilho', 'orbita', 'push', 'chicote', 'cinema']; // sem câmera na mão: tremedeira fora
|
|
66
68
|
|
|
69
|
+
/** Os passeios pela foto (Ken Burns com ease, nunca linear) e qual deles cada câmera do diretor pede. */
|
|
70
|
+
const MOVIMENTOS_FOTO = ['aproxima', 'passeio', 'revela', 'orbita', 'afasta'];
|
|
71
|
+
const CAMERA_FOTO = { push: 'aproxima', pulso: 'aproxima', deriva: 'passeio', trilho: 'passeio', orbita: 'orbita', chicote: 'revela', cinema: 'afasta' };
|
|
72
|
+
|
|
67
73
|
/** Sistemas tipográficos: fontes + como a palavra entra + como a palavra-chave é realçada. */
|
|
68
74
|
const TIPOGRAFIAS = {
|
|
69
75
|
editorial: { fontes: { titulo: 'Poppins', texto: 'Plus Jakarta Sans', destaque: 'Playfair Display' }, entrada: 'palavra', realce: 'italico', passo: 0.1 },
|
|
@@ -229,7 +235,11 @@ function marcarChave(titulo) {
|
|
|
229
235
|
return ps.join(' ');
|
|
230
236
|
}
|
|
231
237
|
const primeirasPalavras = (s, n) => String(s || '').replace(/\*/g, '').split(/\s+/).filter(Boolean).slice(0, n).join(' ');
|
|
232
|
-
|
|
238
|
+
/** A chave de um item pra achar repetido: sem caixa, acento, espaço nem pontuação. */
|
|
239
|
+
const chaveItem = (s) => String(s || '').toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9]/g, '');
|
|
240
|
+
/** Os itens de uma lista: limpos, sem vazio e SEM REPETIR (faltou item, a lista fica menor). */
|
|
241
|
+
const itensDe = (v, n, m) => (Array.isArray(v) ? v : []).map((x) => limpa(typeof x === 'object' && x ? (x.titulo || x.texto || x.nome || '') : x, m))
|
|
242
|
+
.filter((x, i, a) => x && a.findIndex((y) => chaveItem(y) === chaveItem(x)) === i).slice(0, n);
|
|
233
243
|
|
|
234
244
|
/** Põe em `c` o que a primitiva `tipo` precisa e o modelo não mandou. `ctx`: {assunto, meta, proxima}. */
|
|
235
245
|
function completar(c, tipo, ctx) {
|
|
@@ -239,7 +249,7 @@ function completar(c, tipo, ctx) {
|
|
|
239
249
|
out.titulo = marcarChave(base);
|
|
240
250
|
out.sub = limpa(c.sub, 70) || undefined;
|
|
241
251
|
let it = itensDe(c.itens, 6, 28);
|
|
242
|
-
if (spec.itens && it.length < spec.itens) it = (it.length ? it.concat(ctx.meta.itens) : ctx.meta.itens
|
|
252
|
+
if (spec.itens && it.length < spec.itens) it = itensDe(it.length ? it.concat(ctx.meta.itens) : ctx.meta.itens, Math.max(spec.itens, it.length), 28); // completa sem repetir
|
|
243
253
|
out.itens = it;
|
|
244
254
|
out.valor = limpa(c.valor, 12) || (tipo === 'relogio' ? '7:00' : tipo === 'medidor' ? '82%' : tipo === 'estrelas' ? '4,9' : '100');
|
|
245
255
|
out.rotulo = limpa(c.rotulo, 60) || undefined;
|
|
@@ -251,7 +261,7 @@ function completar(c, tipo, ctx) {
|
|
|
251
261
|
out.toques = itensDe(c.toques, 4, 24);
|
|
252
262
|
if (ctx.proxima) { out.prox = limpa(ctx.proxima.titulo || ctx.proxima.texto, 40).replace(/\*/g, ''); }
|
|
253
263
|
out.fala = c.fala ? String(c.fala) : undefined;
|
|
254
|
-
out.dur = Math.max(1.4, Math.min(tipo === 'celular' || tipo === 'prompt' ? 5 : 4.2, Number(c.dur || c.duracao) || spec.dur));
|
|
264
|
+
out.dur = Math.max(1.4, Math.min(tipo === 'celular' || tipo === 'prompt' ? 5 : tipo === 'foto' ? 4.8 : 4.2, Number(c.dur || c.duracao) || spec.dur));
|
|
255
265
|
return out;
|
|
256
266
|
}
|
|
257
267
|
|
|
@@ -269,8 +279,8 @@ function escolherPrimitiva(papel, ctx, rnd) {
|
|
|
269
279
|
const recentes = new Map();
|
|
270
280
|
ctx.historico.slice(-5).forEach((h, i, arr) => (h.primitivas || []).forEach((p) => recentes.set(p, (recentes.get(p) || 0) + 1 + i / arr.length)));
|
|
271
281
|
const nao = new Set(ctx.meta.nao || []);
|
|
272
|
-
const cand = TIPOS.filter((t) => PRIMITIVAS[t].papeis.includes(papel) && !usados.has(t) && !nao.has(t) && (!PRIMITIVAS[t].elemento || ctx.temElemento));
|
|
273
|
-
const lista = (cand.length ? cand : TIPOS.filter((t) => !usados.has(t) && PRIMITIVAS[t].papeis.includes(papel))).map((t) => {
|
|
282
|
+
const cand = TIPOS.filter((t) => !PRIMITIVAS[t].foto && PRIMITIVAS[t].papeis.includes(papel) && !usados.has(t) && !nao.has(t) && (!PRIMITIVAS[t].elemento || ctx.temElemento));
|
|
283
|
+
const lista = (cand.length ? cand : TIPOS.filter((t) => !PRIMITIVAS[t].foto && !usados.has(t) && PRIMITIVAS[t].papeis.includes(papel))).map((t) => {
|
|
274
284
|
let peso = 1;
|
|
275
285
|
peso *= ctx.meta.prefere[t] != null ? ctx.meta.prefere[t] : 1;
|
|
276
286
|
peso *= Math.pow(0.55, recentes.get(t) || 0);
|
|
@@ -326,24 +336,28 @@ function montarDirecao({ args, assunto, meta, duracao, hist, rnd, temElemento })
|
|
|
326
336
|
while (papeis.length > n + 1 && papeis.includes('processo')) papeis.splice(papeis.lastIndexOf('processo'), 1);
|
|
327
337
|
pedidas = papeis.map((papel) => ({ papel }));
|
|
328
338
|
}
|
|
339
|
+
const nFotosPedido = Array.isArray(args.fotos) ? args.fotos.length : (Number(args.nFotos) || 0);
|
|
329
340
|
const papeisUsados = [];
|
|
330
341
|
const cenas = [];
|
|
331
342
|
pedidas.forEach((c, i) => {
|
|
332
343
|
let tipo = normTipo(c.tipo);
|
|
333
344
|
const papel = c.papel || (i === 0 ? 'gancho' : i === pedidas.length - 1 ? 'cta' : ['problema', 'processo', 'prova', 'virada'][i % 4]);
|
|
334
345
|
papeisUsados.push(papel);
|
|
346
|
+
if (tipo === 'foto' && !nFotosPedido) tipo = ''; // "foto" sem foto: o diretor escolhe outra peça
|
|
335
347
|
if (!PRIMITIVAS[tipo]) tipo = papel === 'cta' ? 'cta' : escolherPrimitiva(papel, ctx, rnd); // todo vídeo termina num CTA de verdade (botão grande)
|
|
336
348
|
ctx.usados.add(tipo);
|
|
337
349
|
ctx.ultimaFam = PRIMITIVAS[tipo].fam;
|
|
338
350
|
cenas.push({ c, tipo, papel });
|
|
339
351
|
});
|
|
352
|
+
// a FOTO do pedido: pelo menos uma cena "foto" (a de abertura e/ou a de destaque), nunca duas coladas
|
|
353
|
+
if (nFotosPedido > 0) colocarFotos(cenas, nFotosPedido);
|
|
340
354
|
// o assunto aparece em OBJETOS: pelo menos 2 cenas com primitiva que usa o elemento real (as que o modelo fixou ficam como estão)
|
|
341
355
|
if (temElemento) {
|
|
342
356
|
const nao = new Set(meta.nao || []);
|
|
343
357
|
const conta = () => cenas.filter((x) => PRIMITIVAS[x.tipo].elemento).length;
|
|
344
358
|
for (let i = 0; i < cenas.length && conta() < 2; i++) {
|
|
345
359
|
const x = cenas[(i * 2 + 1) % cenas.length];
|
|
346
|
-
if (PRIMITIVAS[x.tipo].elemento || (x.c && PRIMITIVAS[normTipo(x.c.tipo)])) continue;
|
|
360
|
+
if (x.tipo === 'foto' || PRIMITIVAS[x.tipo].elemento || (x.c && PRIMITIVAS[normTipo(x.c.tipo)])) continue;
|
|
347
361
|
const cand = TIPOS.filter((t) => PRIMITIVAS[t].elemento && PRIMITIVAS[t].papeis.includes(x.papel) && !nao.has(t) && !cenas.some((y) => y.tipo === t));
|
|
348
362
|
if (cand.length) { ctx.usados.delete(x.tipo); x.tipo = sortear(rnd, cand.map((t) => [t, meta.prefere[t] != null ? meta.prefere[t] : 1])); ctx.usados.add(x.tipo); }
|
|
349
363
|
}
|
|
@@ -373,6 +387,7 @@ function montarDirecao({ args, assunto, meta, duracao, hist, rnd, temElemento })
|
|
|
373
387
|
const camera = CAMERAS.includes(args.camera) ? args.camera : sortear(rnd, CAMERAS.map((x) => [x, (meta.cameras.includes(x) ? 3 : 1) * Math.pow(0.45, recC.get(x) || 0) * gm('cameras', x)]));
|
|
374
388
|
const camera2 = sortear(rnd, CAMERAS.filter((x) => x !== camera).map((x) => [x, (meta.cameras.includes(x) ? 2 : 1) * gm('cameras', x)]));
|
|
375
389
|
out.forEach((c, i) => { c.camera = c.camera && CAMERAS.includes(c.camera) ? c.camera : (i % 3 === 2 ? camera2 : camera); });
|
|
390
|
+
movimentosDasFotos(out);
|
|
376
391
|
|
|
377
392
|
// tipografia
|
|
378
393
|
const recTi = new Map(); hist.slice(-3).forEach((h) => recTi.set(h.tipografia, (recTi.get(h.tipografia) || 0) + 1));
|
|
@@ -391,7 +406,46 @@ function montarDirecao({ args, assunto, meta, duracao, hist, rnd, temElemento })
|
|
|
391
406
|
return { metafora: meta, cenas: out, trocas, camera, tipografia, ritmo, paleta, ordemPal, assinatura };
|
|
392
407
|
}
|
|
393
408
|
|
|
409
|
+
/**
|
|
410
|
+
* Põe a primitiva "foto" nas cenas: a de abertura primeiro, depois as de destaque (prova, virada, processo), nunca coladas,
|
|
411
|
+
* nunca no CTA, no máximo 3 cenas. Cena que o modelo já fixou como "foto" conta; cena fixada com outro tipo só cede se não
|
|
412
|
+
* sobrar nenhuma livre. Cada cena "foto" recebe `foto` (o índice da foto em args.fotos).
|
|
413
|
+
*/
|
|
414
|
+
function colocarFotos(cenas, nFotos) {
|
|
415
|
+
const max = Math.max(1, Math.min(3, nFotos, Math.ceil(cenas.length / 2)));
|
|
416
|
+
const ehFoto = (x) => x.tipo === 'foto';
|
|
417
|
+
const fixa = (x) => !!(x.c && x.c.tipo && PRIMITIVAS[normTipo(x.c.tipo)] && normTipo(x.c.tipo) !== 'foto');
|
|
418
|
+
const vizinhaDeFoto = (i) => (cenas[i - 1] && ehFoto(cenas[i - 1])) || (cenas[i + 1] && ehFoto(cenas[i + 1]));
|
|
419
|
+
const podeSer = (i, livre) => i < cenas.length && !ehFoto(cenas[i]) && cenas[i].papel !== 'cta' && !(i === cenas.length - 1 && cenas.length > 1) && !vizinhaDeFoto(i) && (!livre || !fixa(cenas[i]));
|
|
420
|
+
const poe = (i) => { cenas[i].tipo = 'foto'; cenas[i].c = { ...cenas[i].c, tipo: 'foto' }; };
|
|
421
|
+
let n = cenas.filter(ehFoto).length;
|
|
422
|
+
const ordem = [0, ...cenas.map((x, i) => i).filter((i) => i > 0 && ['prova', 'virada', 'processo', 'problema'].includes(cenas[i].papel)), ...cenas.map((x, i) => i)];
|
|
423
|
+
for (const livre of [true, false]) {
|
|
424
|
+
for (const i of ordem) { if (n >= max) break; if (podeSer(i, livre)) { poe(i); n++; } }
|
|
425
|
+
if (n > 0) break; // a foto entrou: o resto das fixadas pelo modelo fica como está
|
|
426
|
+
}
|
|
427
|
+
if (!n && cenas.length) { poe(0); n = 1; } // uma cena só: a foto vira a cena
|
|
428
|
+
let k = 0;
|
|
429
|
+
cenas.forEach((x) => { if (ehFoto(x)) { x.c = { ...x.c, foto: x.c.foto != null ? x.c.foto : k % nFotos }; k++; } });
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/** O passeio de cada foto: o que a câmera da cena pede, sem repetir o de nenhuma outra foto do vídeo (e o sentido alterna). */
|
|
433
|
+
function movimentosDasFotos(out) {
|
|
434
|
+
const usados = [];
|
|
435
|
+
let sentido = 1;
|
|
436
|
+
out.forEach((c) => {
|
|
437
|
+
if (c.tipo !== 'foto') return;
|
|
438
|
+
let mov = MOVIMENTOS_FOTO.includes(c.movimento) && !usados.includes(c.movimento) ? c.movimento : CAMERA_FOTO[c.camera] || 'aproxima';
|
|
439
|
+
if (usados.includes(mov)) mov = MOVIMENTOS_FOTO[(MOVIMENTOS_FOTO.indexOf(mov) + 1 + usados.length) % MOVIMENTOS_FOTO.length];
|
|
440
|
+
for (let g = 0; usados.includes(mov) && g < MOVIMENTOS_FOTO.length; g++) mov = MOVIMENTOS_FOTO[(MOVIMENTOS_FOTO.indexOf(mov) + 1) % MOVIMENTOS_FOTO.length];
|
|
441
|
+
usados.push(mov);
|
|
442
|
+
c.movimento = mov;
|
|
443
|
+
c.sentido = sentido;
|
|
444
|
+
sentido = -sentido;
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
|
|
394
448
|
/** Quantos itens do vocabulário (para o teste e para o relatório). */
|
|
395
449
|
const VOCABULARIO = () => ({ primitivas: TIPOS.length, transicoes: TRANSICOES.length, cameras: CAMERAS.length, tipografias: Object.keys(TIPOGRAFIAS).length });
|
|
396
450
|
|
|
397
|
-
module.exports = { PRIMITIVAS, TIPOS, TRANSICOES, CAMERAS, TIPOGRAFIAS, METAFORAS, PALETAS, achar, dirigir, similaridade, lerHistorico, registrar, completar, marcarChave, normTipo, escolherPrimitiva, VOCABULARIO, LIMITE_PARECIDO, hashTexto, mulberry, arquivoHistorico };
|
|
451
|
+
module.exports = { itensDe, PRIMITIVAS, TIPOS, TRANSICOES, CAMERAS, MOVIMENTOS_FOTO, CAMERA_FOTO, colocarFotos, movimentosDasFotos, TIPOGRAFIAS, METAFORAS, PALETAS, achar, dirigir, similaridade, lerHistorico, registrar, completar, marcarChave, normTipo, escolherPrimitiva, VOCABULARIO, LIMITE_PARECIDO, hashTexto, mulberry, arquivoHistorico };
|