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
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="pt-BR"><head><meta charset="UTF-8"/><title>k3d · tela (vídeo ou imagem da pessoa num aparelho 3D)</title></head>
|
|
3
|
+
<body>
|
|
4
|
+
<!--
|
|
5
|
+
Kit 3D (d): um aparelho de verdade em 3D (notebook ou celular, com espessura, teclado e borda chanfrada) com o
|
|
6
|
+
vídeo ou a imagem da pessoa na tela. Abre parado de frente (parece o vídeo normal), gira um pouco na palavra
|
|
7
|
+
combinada para mostrar o corpo do aparelho e termina parado.
|
|
8
|
+
HONESTIDADE: a tela é um plano chapado com o vídeo colado. O aparelho tem volume; a pessoa na tela não ganha
|
|
9
|
+
volume nenhum quando gira (de lado, a imagem só fica mais estreita). Diga isso na entrega. Guia: references/3d.md.
|
|
10
|
+
Vídeo: o <video id="k3dt-midia"> abaixo. Ponha em data-media-start o segundo do corte em que a cena começa (o
|
|
11
|
+
"de" dela no projeto.json) para a boca bater com a voz, e em data-duration a duração da cena. Para uma imagem,
|
|
12
|
+
troque o <video> por <img id="k3dt-midia" src="assets/foto.jpg" alt=""/> (mesmo id).
|
|
13
|
+
Para usar: copie para compositions/cenas/<nome>.html, troque "k3d_tela" (template, raiz e ID) e o prefixo
|
|
14
|
+
"k3dt-", mude os PARÂMETROS e ligue no projeto.json em "cenas_proprias".
|
|
15
|
+
-->
|
|
16
|
+
<template id="k3d_tela-template">
|
|
17
|
+
<style>
|
|
18
|
+
@font-face{font-family:Montserrat;src:url("assets/fontes/Montserrat.ttf") format("truetype");font-weight:100 900;font-display:block}
|
|
19
|
+
#root{position:absolute;inset:0;overflow:hidden;font-family:Montserrat}
|
|
20
|
+
#k3dt-palco{position:absolute;inset:0;opacity:0}
|
|
21
|
+
#k3dt-tela{position:absolute;left:0;top:0;width:100%;height:100%;display:block}
|
|
22
|
+
#k3dt-rotulos{position:absolute;inset:0}
|
|
23
|
+
#k3dt-midia{position:absolute;left:0;top:0;width:320px;height:568px;object-fit:cover;opacity:0}
|
|
24
|
+
</style>
|
|
25
|
+
<div id="root" data-composition-id="k3d_tela" data-width="1080" data-height="1920" data-duration="5">
|
|
26
|
+
<video id="k3dt-midia" src="assets/cut.mp4" muted playsinline data-start="0" data-duration="5" data-media-start="0" data-track-index="0"></video>
|
|
27
|
+
<div id="k3dt-palco"><canvas id="k3dt-tela" width="1080" height="1920"></canvas><div id="k3dt-rotulos"></div></div>
|
|
28
|
+
</div>
|
|
29
|
+
<script>
|
|
30
|
+
(function () {
|
|
31
|
+
const ID = "k3d_tela";
|
|
32
|
+
// ------------------------------------------------------------------ PARÂMETROS (troque aqui)
|
|
33
|
+
const PARAM = {
|
|
34
|
+
aparelho: "notebook", // "notebook" ou "celular"
|
|
35
|
+
encaixe: "conter", // "conter" (a imagem inteira, com fundo borrado) ou "cobrir" (preenche e corta)
|
|
36
|
+
foco: 0.35, // "cobrir": que altura da imagem fica na tela (0 = topo, 0.5 = meio)
|
|
37
|
+
corCorpo: null, // cor do aparelho (null = base do estilo)
|
|
38
|
+
gira: { palavra: "computador", padrao: 2.4 }, // quando o giro começa
|
|
39
|
+
duracaoGiro: 1.2,
|
|
40
|
+
cameraInicio: { azim: 0, elev: null }, // de frente para a tela (elev null = na altura da tela)
|
|
41
|
+
cameraFim: { azim: 38, elev: 26 }, // onde para: mostra a espessura e o corpo do aparelho
|
|
42
|
+
rotulo: null, // {texto: "roda aqui", palavra: "roda"}: rótulo preso ao aparelho
|
|
43
|
+
fundo: "papel", // "papel", "#rrggbb" ou null (transparente)
|
|
44
|
+
area: null, // [x0, y0, x1, y1] em px onde fica o 3D; null = zona segura
|
|
45
|
+
recorte: true, // com area: o 3D só aparece dentro dela (janela de cantos redondos)
|
|
46
|
+
sombras: true, // sombra das luzes (false deixa o render mais leve; a sombra de contato fica)
|
|
47
|
+
entrada: 0.2,
|
|
48
|
+
saida: 0.2,
|
|
49
|
+
};
|
|
50
|
+
// ------------------------------------------------------------------ dados do build.py (padrões para abrir sozinha)
|
|
51
|
+
const C = Object.assign({ palavras: [], duracao: 5, largura: 1080, altura: 1920, seguro: [140, 230, 940, 1530], rosto: null,
|
|
52
|
+
cores: { papel: "#fffdfd", linha: "#e6ddf8", base: "#c7b7ef", destaque: "#665080", tinta: "#352c40", verde: "#2e9e5b", vermelho: "#e5484d" } },
|
|
53
|
+
(window.__cenas || {})[ID] || {});
|
|
54
|
+
const DUR = C.duracao;
|
|
55
|
+
|
|
56
|
+
async function construir(K, P) {
|
|
57
|
+
const THREE = K.THREE;
|
|
58
|
+
const corpo = PARAM.corCorpo || C.cores.base;
|
|
59
|
+
const lados = "#" + new THREE.Color(corpo).multiplyScalar(0.78).getHexString();
|
|
60
|
+
P.luzes({ chave: [4, 8, 7], alvo: [0, 0.8, 0], area: 5 });
|
|
61
|
+
P.chao({ tamanho: 22 });
|
|
62
|
+
const el = document.getElementById("k3dt-midia");
|
|
63
|
+
if (el.tagName === "IMG" && !(el.complete && el.naturalWidth)) await new Promise((ok) => { el.onload = ok; el.onerror = ok; });
|
|
64
|
+
const notebook = PARAM.aparelho !== "celular";
|
|
65
|
+
const tamTela = notebook ? [2.72, 1.7] : [0.92, 1.96];
|
|
66
|
+
const px = notebook ? [1280, 800] : [540, 1150];
|
|
67
|
+
const midia = P.texturaDeMidia(el, { largura: px[0], altura: px[1], foco: PARAM.foco, encaixe: PARAM.encaixe });
|
|
68
|
+
const telaMat = new THREE.MeshBasicMaterial({ map: midia.textura, toneMapped: false });
|
|
69
|
+
const aparelho = new THREE.Group();
|
|
70
|
+
let centroTela, normalTela, telaMalha;
|
|
71
|
+
if (notebook) {
|
|
72
|
+
// base com teclado e trackpad
|
|
73
|
+
const base = P.placa({ largura: 3.0, altura: 0.11, profundidade: 2.0, raio: 0.14, chanfro: 0.03, cor: corpo, lados });
|
|
74
|
+
aparelho.add(base);
|
|
75
|
+
const teclado = P.placa({ largura: 2.6, altura: 0.012, profundidade: 0.95, raio: 0.05, chanfro: 0.004, cor: C.cores.tinta });
|
|
76
|
+
teclado.position.set(0, 0.105, -0.38);
|
|
77
|
+
aparelho.add(teclado);
|
|
78
|
+
const teclas = new THREE.InstancedMesh(new THREE.BoxGeometry(0.16, 0.02, 0.16), P.material("#f4f1fb", { rugosidade: 0.7, verniz: 0 }), 13 * 5);
|
|
79
|
+
const m = new THREE.Matrix4();
|
|
80
|
+
let n = 0;
|
|
81
|
+
for (let r = 0; r < 5; r++) for (let c = 0; c < 13; c++) { m.makeTranslation(-1.14 + c * 0.19, 0.122, -0.76 + r * 0.19); teclas.setMatrixAt(n++, m); }
|
|
82
|
+
teclas.castShadow = true;
|
|
83
|
+
aparelho.add(teclas);
|
|
84
|
+
const pad = P.placa({ largura: 0.95, altura: 0.006, profundidade: 0.55, raio: 0.06, chanfro: 0.002, cor: lados });
|
|
85
|
+
pad.position.set(0, 0.108, 0.55);
|
|
86
|
+
aparelho.add(pad);
|
|
87
|
+
// tampa articulada no fundo da base, aberta a 108 graus, com a tela na face de dentro
|
|
88
|
+
const dobra = new THREE.Group();
|
|
89
|
+
dobra.position.set(0, 0.11, -1.0);
|
|
90
|
+
dobra.rotation.x = -THREE.MathUtils.degToRad(108);
|
|
91
|
+
const tampa = P.placa({ largura: 3.0, altura: 0.07, profundidade: 2.0, raio: 0.14, chanfro: 0.025, cor: corpo, lados });
|
|
92
|
+
tampa.position.set(0, 0, 1.0);
|
|
93
|
+
dobra.add(tampa);
|
|
94
|
+
const moldura = P.placa({ largura: 2.9, altura: 0.004, profundidade: 1.9, raio: 0.1, chanfro: 0.001, cor: C.cores.tinta });
|
|
95
|
+
moldura.position.set(0, -0.003, 1.0);
|
|
96
|
+
dobra.add(moldura);
|
|
97
|
+
const tela = new THREE.Mesh(new THREE.PlaneGeometry(tamTela[0], tamTela[1]), telaMat);
|
|
98
|
+
tela.rotation.x = Math.PI / 2; // de frente para fora da tampa
|
|
99
|
+
tela.position.set(0, -0.006, 1.02);
|
|
100
|
+
dobra.add(tela);
|
|
101
|
+
aparelho.add(dobra);
|
|
102
|
+
telaMalha = tela;
|
|
103
|
+
aparelho.updateMatrixWorld(true);
|
|
104
|
+
centroTela = tela.getWorldPosition(new THREE.Vector3());
|
|
105
|
+
normalTela = new THREE.Vector3(0, 0, 1).applyQuaternion(tela.getWorldQuaternion(new THREE.Quaternion()));
|
|
106
|
+
} else {
|
|
107
|
+
// celular em pé: corpo com espessura e a tela na frente
|
|
108
|
+
const corpoCel = P.placa({ largura: 1.02, altura: 0.1, profundidade: 2.1, raio: 0.16, chanfro: 0.03, cor: corpo, lados });
|
|
109
|
+
const frente = P.placa({ largura: 0.98, altura: 0.004, profundidade: 2.06, raio: 0.14, chanfro: 0.001, cor: C.cores.tinta });
|
|
110
|
+
frente.position.y = 0.1;
|
|
111
|
+
const tela = new THREE.Mesh(new THREE.PlaneGeometry(tamTela[0], tamTela[1]), telaMat);
|
|
112
|
+
tela.rotation.x = -Math.PI / 2;
|
|
113
|
+
tela.position.y = 0.106;
|
|
114
|
+
const deitado = new THREE.Group();
|
|
115
|
+
deitado.add(corpoCel, frente, tela);
|
|
116
|
+
deitado.rotation.x = Math.PI / 2; // fica em pé, tela para a câmera
|
|
117
|
+
deitado.position.set(0, 1.05, 0);
|
|
118
|
+
aparelho.add(deitado);
|
|
119
|
+
telaMalha = tela;
|
|
120
|
+
aparelho.updateMatrixWorld(true);
|
|
121
|
+
centroTela = tela.getWorldPosition(new THREE.Vector3());
|
|
122
|
+
normalTela = new THREE.Vector3(0, 0, 1).applyQuaternion(tela.getWorldQuaternion(new THREE.Quaternion()));
|
|
123
|
+
}
|
|
124
|
+
P.cena.add(aparelho);
|
|
125
|
+
P.solido(aparelho, PARAM.aparelho);
|
|
126
|
+
const tam = new THREE.Box3().setFromObject(aparelho).getSize(new THREE.Vector3());
|
|
127
|
+
P.sombraDeContato({ largura: tam.x, profundidade: notebook ? 2.1 : 0.3, forca: 0.5 }).colocar(0, notebook ? 0 : 0.05, 0);
|
|
128
|
+
// câmera: começa perpendicular à tela (parece o vídeo chapado) e termina num 3/4 que mostra o corpo
|
|
129
|
+
const elevTela = THREE.MathUtils.radToDeg(Math.asin(K.lim(normalTela.y, -1, 1)));
|
|
130
|
+
const ini = { alvo: centroTela.toArray(), azim: PARAM.cameraInicio.azim, elev: PARAM.cameraInicio.elev == null ? elevTela : PARAM.cameraInicio.elev };
|
|
131
|
+
ini.dist = P.distanciaQueCabe(new THREE.Box3().setFromObject(telaMalha), ini, 1.1);
|
|
132
|
+
const caixaTudo = new THREE.Box3().setFromObject(aparelho);
|
|
133
|
+
const fim = { alvo: caixaTudo.getCenter(new THREE.Vector3()).toArray(), azim: PARAM.cameraFim.azim, elev: PARAM.cameraFim.elev };
|
|
134
|
+
fim.dist = P.distanciaQueCabe(caixaTudo, fim, 1.08);
|
|
135
|
+
const tGira = K.momento(C, PARAM.gira, 2.4);
|
|
136
|
+
const rot = PARAM.rotulo ? P.rotulos([{ texto: PARAM.rotulo.texto, lado: "cima" }]) : null;
|
|
137
|
+
const tRot = PARAM.rotulo ? K.momento(C, PARAM.rotulo, tGira) : 0;
|
|
138
|
+
return (t) => {
|
|
139
|
+
P.orbita(K.misturaPose(ini, fim, K.trecho(t, tGira, PARAM.duracaoGiro)));
|
|
140
|
+
if (rot) rot.atualizar([{ ponto: [0, tam.y + 0.05, notebook ? -1.0 : 0], opacidade: K.trecho(t, tRot, 0.25) }]);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ------------------------------------------------------------------ ligação com o HyperFrames (não precisa mexer)
|
|
145
|
+
const palco = document.getElementById("k3dt-palco");
|
|
146
|
+
const tl = gsap.timeline({ paused: true });
|
|
147
|
+
const relogio = { t: 0 };
|
|
148
|
+
let desenhar = null;
|
|
149
|
+
tl.fromTo(relogio, { t: 0 }, { t: DUR, duration: DUR, ease: "none", onUpdate: () => desenhar && desenhar(relogio.t) }, 0);
|
|
150
|
+
if (PARAM.entrada > 0) tl.fromTo(palco, { opacity: 0 }, { opacity: 1, duration: PARAM.entrada, ease: "power1.out" }, 0);
|
|
151
|
+
else tl.set(palco, { opacity: 1 }, 0);
|
|
152
|
+
if (PARAM.saida > 0) tl.fromTo(palco, { opacity: 1 }, { opacity: 0, duration: PARAM.saida, ease: "power1.in", immediateRender: false }, Math.max(0, DUR - PARAM.saida));
|
|
153
|
+
window.__timelines["k3d_tela"] = tl;
|
|
154
|
+
window.addEventListener("hf-seek", () => { if (desenhar) desenhar(relogio.t); });
|
|
155
|
+
const src = typeof __hfCompositionSrc === "string" ? __hfCompositionSrc : "";
|
|
156
|
+
const RAIZ = src.includes("/compositions/") ? src.slice(0, src.lastIndexOf("/compositions/") + 1) : document.baseURI;
|
|
157
|
+
const fundo = PARAM.fundo === "papel" ? C.cores.papel : PARAM.fundo;
|
|
158
|
+
(window.__hf = window.__hf || {}).buildReady = window.__hf.buildReady || {};
|
|
159
|
+
window.__hf.buildReady[ID] = import(new URL("compositions/cenas/3d/motor-three.js", RAIZ).href)
|
|
160
|
+
.then((K) => K.iniciar({ id: ID, C, raiz: RAIZ, canvas: document.getElementById("k3dt-tela"), camada: document.getElementById("k3dt-rotulos"),
|
|
161
|
+
fundo, area: PARAM.area, recorte: PARAM.area && PARAM.recorte ? PARAM.area : null, fov: 30, sombras: PARAM.sombras, construir: (P) => construir(K, P) }))
|
|
162
|
+
.then((d) => { desenhar = d; desenhar(relogio.t); })
|
|
163
|
+
.catch((e) => console.error(`[cena 3D ${ID}] não carreguei o motor 3D: ${e && e.message ? e.message : e}`));
|
|
164
|
+
})();
|
|
165
|
+
</script>
|
|
166
|
+
</template>
|
|
167
|
+
</body></html>
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="pt-BR"><head><meta charset="UTF-8"/><title>k3d · volume (texto ou objeto em volume girando)</title></head>
|
|
3
|
+
<body>
|
|
4
|
+
<!--
|
|
5
|
+
Kit 3D (c): uma palavra (ou um objeto) em volume de verdade, parada no começo, que gira um pouco na palavra
|
|
6
|
+
combinada para mostrar a espessura e as laterais, com luz de estúdio e sombra no chão, e termina parada.
|
|
7
|
+
Serve quando o volume é a mensagem (o objeto tem corpo, o texto "salta" do plano). Querer só que "pareça caro"
|
|
8
|
+
não justifica: aí 2D serve melhor. Guia: references/3d.md da skill.
|
|
9
|
+
Para usar: copie para compositions/cenas/<nome>.html, troque "k3d_volume" (template, raiz e ID) e o prefixo
|
|
10
|
+
"k3dv-", mude os PARÂMETROS abaixo e ligue no projeto.json em "cenas_proprias".
|
|
11
|
+
-->
|
|
12
|
+
<template id="k3d_volume-template">
|
|
13
|
+
<style>
|
|
14
|
+
@font-face{font-family:Montserrat;src:url("assets/fontes/Montserrat.ttf") format("truetype");font-weight:100 900;font-display:block}
|
|
15
|
+
#root{position:absolute;inset:0;overflow:hidden;font-family:Montserrat}
|
|
16
|
+
#k3dv-palco{position:absolute;inset:0;opacity:0}
|
|
17
|
+
#k3dv-tela{position:absolute;left:0;top:0;width:100%;height:100%;display:block}
|
|
18
|
+
#k3dv-rotulos{position:absolute;inset:0}
|
|
19
|
+
</style>
|
|
20
|
+
<div id="root" data-composition-id="k3d_volume" data-width="1080" data-height="1920" data-duration="5">
|
|
21
|
+
<div id="k3dv-palco"><canvas id="k3dv-tela" width="1080" height="1920"></canvas><div id="k3dv-rotulos"></div></div>
|
|
22
|
+
</div>
|
|
23
|
+
<script>
|
|
24
|
+
(function () {
|
|
25
|
+
const ID = "k3d_volume";
|
|
26
|
+
// ------------------------------------------------------------------ PARÂMETROS (troque aqui)
|
|
27
|
+
const PARAM = {
|
|
28
|
+
objeto: "texto", // "texto" (letras em volume), "caixa" (sólido simples) ou "modelo" (.glb/.gltf da pessoa)
|
|
29
|
+
texto: "UMA VEZ\nSÓ", // objeto "texto": o que vira volume (\n quebra a linha; acento serve)
|
|
30
|
+
modelo: "assets/modelo.glb", // objeto "modelo": arquivo liberado para uso, a partir da pasta do projeto
|
|
31
|
+
cor: null, // cor da frente (null = destaque do estilo)
|
|
32
|
+
corLados: null, // cor das laterais e da espessura (null = tinta do estilo): é o que aparece no giro
|
|
33
|
+
espessura: 0.34, // profundidade das letras, em alturas de letra
|
|
34
|
+
gira: { palavra: "uma", padrao: 0.8 }, // quando o giro começa: palavra da fala (ou segundos da cena)
|
|
35
|
+
duracaoGiro: 1.3, // segundos do giro (preso à fala: começa na palavra)
|
|
36
|
+
anguloInicio: -34, // graus: como a peça abre, parada (já mostrando um pouco da lateral)
|
|
37
|
+
anguloFim: 18, // graus: onde termina parada (o ângulo que mais mostra o volume)
|
|
38
|
+
elevacao: 13, // graus da câmera acima do chão
|
|
39
|
+
fundo: "papel", // "papel" (cor do estilo), "#rrggbb" ou null (transparente: o vídeo aparece por baixo)
|
|
40
|
+
area: null, // [x0, y0, x1, y1] em px onde a peça fica; null = zona segura
|
|
41
|
+
recorte: true, // com area: o 3D só aparece dentro dela (janela de cantos redondos)
|
|
42
|
+
rotulo: null, // {texto: "tem espessura", palavra: "vez"}: um rótulo preso à lateral da peça
|
|
43
|
+
sombras: true, // sombra das luzes (false deixa o render mais leve; a sombra de contato fica)
|
|
44
|
+
entrada: 0.2, // segundos para a cena surgir (0 = corte seco)
|
|
45
|
+
saida: 0.2, // segundos para sumir no fim
|
|
46
|
+
};
|
|
47
|
+
// ------------------------------------------------------------------ dados do build.py (padrões para abrir sozinha)
|
|
48
|
+
const C = Object.assign({ palavras: [], duracao: 5, largura: 1080, altura: 1920, seguro: [140, 230, 940, 1530], rosto: null,
|
|
49
|
+
cores: { papel: "#fffdfd", linha: "#e6ddf8", base: "#c7b7ef", destaque: "#665080", tinta: "#352c40", verde: "#2e9e5b", vermelho: "#e5484d" } },
|
|
50
|
+
(window.__cenas || {})[ID] || {});
|
|
51
|
+
const DUR = C.duracao;
|
|
52
|
+
|
|
53
|
+
// o que acontece em cada t (s da cena): nada aqui depende do quadro anterior
|
|
54
|
+
async function construir(K, P) {
|
|
55
|
+
const THREE = K.THREE;
|
|
56
|
+
const cor = PARAM.cor || C.cores.destaque, lados = PARAM.corLados || C.cores.tinta;
|
|
57
|
+
P.luzes({ chave: [3.2, 7, 6.5], alvo: [0, 0.5, 0], area: 6 });
|
|
58
|
+
P.chao({ tamanho: 22 });
|
|
59
|
+
let peca, noTempo = null;
|
|
60
|
+
if (PARAM.objeto === "modelo") {
|
|
61
|
+
const m = await P.carregarModelo(PARAM.modelo, { altura: 1.6 });
|
|
62
|
+
peca = m.objeto;
|
|
63
|
+
noTempo = m.noTempo; // animação que vem dentro do modelo, posta no tempo da cena
|
|
64
|
+
}
|
|
65
|
+
else if (PARAM.objeto === "caixa") peca = P.caixa({ largura: 1.6, altura: 1.6, profundidade: 1.6, raio: 0.18, chanfro: 0.06, cor, lados });
|
|
66
|
+
else peca = await P.textoEmVolume(PARAM.texto, { altura: 1, espessura: PARAM.espessura, cor, lados });
|
|
67
|
+
const giro = new THREE.Group();
|
|
68
|
+
giro.add(peca);
|
|
69
|
+
P.cena.add(giro);
|
|
70
|
+
P.solido(peca, "a peça");
|
|
71
|
+
const tam = new THREE.Box3().setFromObject(peca).getSize(new THREE.Vector3());
|
|
72
|
+
const sombra = P.sombraDeContato({ largura: tam.x, profundidade: Math.max(tam.z, 0.35), forca: 0.5 });
|
|
73
|
+
// a câmera fica numa distância em que a peça cabe inteira em todos os ângulos do giro
|
|
74
|
+
const caixaGiro = new THREE.Box3();
|
|
75
|
+
for (let k = 0; k <= 8; k++) {
|
|
76
|
+
giro.rotation.y = THREE.MathUtils.degToRad(K.mistura(PARAM.anguloInicio, PARAM.anguloFim, k / 8));
|
|
77
|
+
giro.updateMatrixWorld(true);
|
|
78
|
+
caixaGiro.union(new THREE.Box3().setFromObject(peca));
|
|
79
|
+
}
|
|
80
|
+
const alvo = caixaGiro.getCenter(new THREE.Vector3()).toArray();
|
|
81
|
+
const dist = P.distanciaQueCabe(caixaGiro, { alvo, azim: 0, elev: PARAM.elevacao }, 1.0);
|
|
82
|
+
const tGira = K.momento(C, PARAM.gira, 0.8);
|
|
83
|
+
const rot = PARAM.rotulo ? P.rotulos([{ texto: PARAM.rotulo.texto, lado: "dir" }]) : null;
|
|
84
|
+
const tRot = PARAM.rotulo ? K.momento(C, PARAM.rotulo, tGira + PARAM.duracaoGiro) : 0;
|
|
85
|
+
const lateral = new THREE.Vector3();
|
|
86
|
+
return (t) => {
|
|
87
|
+
const k = K.trecho(t, tGira, PARAM.duracaoGiro);
|
|
88
|
+
const ang = THREE.MathUtils.degToRad(K.mistura(PARAM.anguloInicio, PARAM.anguloFim, k));
|
|
89
|
+
giro.rotation.y = ang;
|
|
90
|
+
if (noTempo) noTempo(t);
|
|
91
|
+
sombra.colocar(0, 0, 0, 1, ang);
|
|
92
|
+
P.orbita({ alvo, dist, azim: 0, elev: PARAM.elevacao });
|
|
93
|
+
if (rot) {
|
|
94
|
+
lateral.set(tam.x / 2, tam.y * 0.55, 0).applyAxisAngle(new THREE.Vector3(0, 1, 0), ang);
|
|
95
|
+
rot.atualizar([{ ponto: lateral, opacidade: K.trecho(t, tRot, 0.25) }]);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ------------------------------------------------------------------ ligação com o HyperFrames (não precisa mexer)
|
|
101
|
+
const palco = document.getElementById("k3dv-palco");
|
|
102
|
+
const tl = gsap.timeline({ paused: true });
|
|
103
|
+
const relogio = { t: 0 };
|
|
104
|
+
let desenhar = null;
|
|
105
|
+
// o relógio da cena é esta timeline: o HyperFrames posiciona o tempo e o 3D é desenhado para aquele t
|
|
106
|
+
tl.fromTo(relogio, { t: 0 }, { t: DUR, duration: DUR, ease: "none", onUpdate: () => desenhar && desenhar(relogio.t) }, 0);
|
|
107
|
+
if (PARAM.entrada > 0) tl.fromTo(palco, { opacity: 0 }, { opacity: 1, duration: PARAM.entrada, ease: "power1.out" }, 0);
|
|
108
|
+
else tl.set(palco, { opacity: 1 }, 0);
|
|
109
|
+
if (PARAM.saida > 0) tl.fromTo(palco, { opacity: 1 }, { opacity: 0, duration: PARAM.saida, ease: "power1.in", immediateRender: false }, Math.max(0, DUR - PARAM.saida));
|
|
110
|
+
window.__timelines["k3d_volume"] = tl;
|
|
111
|
+
window.addEventListener("hf-seek", () => { if (desenhar) desenhar(relogio.t); });
|
|
112
|
+
const src = typeof __hfCompositionSrc === "string" ? __hfCompositionSrc : "";
|
|
113
|
+
const RAIZ = src.includes("/compositions/") ? src.slice(0, src.lastIndexOf("/compositions/") + 1) : document.baseURI;
|
|
114
|
+
const fundo = PARAM.fundo === "papel" ? C.cores.papel : PARAM.fundo;
|
|
115
|
+
(window.__hf = window.__hf || {}).buildReady = window.__hf.buildReady || {};
|
|
116
|
+
window.__hf.buildReady[ID] = import(new URL("compositions/cenas/3d/motor-three.js", RAIZ).href)
|
|
117
|
+
.then((K) => K.iniciar({ id: ID, C, raiz: RAIZ, canvas: document.getElementById("k3dv-tela"), camada: document.getElementById("k3dv-rotulos"),
|
|
118
|
+
fundo, area: PARAM.area, recorte: PARAM.area && PARAM.recorte ? PARAM.area : null, fov: 28, sombras: PARAM.sombras, construir: (P) => construir(K, P) }))
|
|
119
|
+
.then((d) => { desenhar = d; desenhar(relogio.t); })
|
|
120
|
+
.catch((e) => console.error(`[cena 3D ${ID}] não carreguei o motor 3D: ${e && e.message ? e.message : e}`));
|
|
121
|
+
})();
|
|
122
|
+
</script>
|
|
123
|
+
</template>
|
|
124
|
+
</body></html>
|