Editor teks di atas gambar. Satu komponen, dipakai banyak apps. Menerima satu objek setelan, mengembalikan satu objek hasil, dan tidak tahu apa-apa soal bisnis apps yang memakainya.
Tempel ini di halamanmu. Tidak ada yang perlu dipasang, tidak ada setelan yang wajib, dan tidak ada kunci yang perlu diminta.
<iframe src="https://editor.mataanginproperti.com/v2/"
style="width:100%;height:100%;border:0"
title="Editor teks di atas gambar"></iframe>
Sudah itu saja. Yang muncul editor lengkap: pilih ukuran kanvas, ganti latar, susun teks, simpan, unduh PNG atau PDF.
Editor mengabari halaman induknya lewat postMessage. Dengarkan,
dan simpan hasil.spec ke tempat apa pun yang kamu pakai.
window.addEventListener('message', function(e){
var d = e.data; if(!d || !d.tie) return;
if(d.tie === 'siap') console.log('editor v' + d.versi + ' siap');
if(d.tie === 'selesai') simpan(d.hasil.spec); // tombol Simpan
if(d.tie === 'final') simpan(d.hasil.spec); // keluar sambil menyimpan
if(d.tie === 'tutup') tutupBingkai(); // pemakai menekan silang
});
Kalau kamu mau memberi judul, daftar latar milikmu, atau membuka satu gambar
langsung — kirim sesudah bingkainya mengabarkan siap.
bingkai.contentWindow.postMessage({
tie: 'setelan',
cfg: {
judul : 'Studio Teks',
asal : window.location.origin, // disarankan, lihat Keamanan
storageKey : 'apps_ku_draf', // pisahkan draf antar apps
pustaka : [ { id:'g1', nama:'Latar 1',
thumb:'https://…/kecil.jpg',
gambar:'https://…/besar.jpg' } ]
}
}, 'https://editor.mataanginproperti.com');
Ini pola kedua, dan yang paling sering ditanyakan: pemakai sedang melihat satu gambar di galerimu, menekan sebuah ikon, dan editor terbuka langsung di atas gambar itu — tanpa layar pilih ukuran.
Tombolnya milikmu, di jendela preview-mu. Yang dikerjakan editor cuma menerima satu pesan:
// di jendela preview-mu, pada tombol Edit
function edit(gambar){
bukaBingkaiEditor(); // pasang <iframe> seperti di atas
// tunggu 'siap' dari editor, lalu:
bingkai.contentWindow.postMessage({
tie : 'buka',
opsi : { desain: { id: gambar.id, nama: gambar.nama,
gambar: [ gambar.url ] } }
}, 'https://editor.mataanginproperti.com');
}
Kalau bingkainya baru dipasang saat itu juga, kamu boleh melewatkan
buka sama sekali dan menaruh desainnya di cfg
langsung — {tie:'setelan', cfg:{ desain:{…} }} berperilaku sama:
desain yang disebut berarti "buka ini", dan layar pilih ukuran dilewati.
Keduanya sengaja dibuat setara supaya kamu tidak perlu tahu bingkainya sudah
hidup berapa lama.
gambar boleh satu alamat ('https://…') atau
larik. Keduanya diterima.
Setelan susulan yang datang sesudah pemakai mulai menyunting tidak
akan membuang pekerjaannya: editor tidak membuka ulang kanvas yang sedang
dipakai. Jadi aman mengirim ulang cfg begitu daftar dari
penyimpananmu tiba — daftar pustaka yang tiba belakangan juga
mengisi layar Background yang kebetulan sedang terbuka.
Kamu tidak perlu mengirim format atau ukuran. Kanvas mengambil
rasio dari gambar yang kamu berikan, dan seluruh spec yang
dikembalikan berupa persen — jadi ia bisa digambar ulang di ukuran berapa
pun. Tidak ada kosakata preset yang perlu kamu hafal.
Ekspor dibatasi 4000 px sisi terpanjang (bisa diatur lewat
maksDim pada pesan ekspor), dan tidak pernah
memperbesar melebihi resolusi asli gambarmu. Mengirim berkas 8000 px karena
itu tidak menambah apa pun ke hasil akhir — ia cuma memakan memori peramban
di ponsel. Kirim yang setara 4000 px; simpan yang besar di tempatmu.
Sesudah editor membuka sebuah desain, ia mengabarkan hasilnya. Ini yang membedakan "gagal" dari "berhasil tapi kanvasnya kosong" — dua hal yang dari mata pemakai terlihat sama persis.
{ tie: 'dibuka', id: 'FILEID', ok: true, ekspor: true }
{ tie: 'dibuka', id: 'FILEID', ok: false, ekspor: false,
sebab: 'gambar-gagal-dimuat' }
ekspor dijawab terpisah dari ok, dan itu
bukan kelebihan. Gambar lintas-asal yang tidak mengirim izin CORS tetap
tampil dengan sempurna — editor sengaja memuatnya ulang tanpa
crossOrigin supaya pemakai tetap bisa menyunting — tapi kanvasnya
jadi ternoda dan ekspornya akan gagal. Tanpa ladang ini, bedanya baru
kelihatan waktu pemakai menekan Simpan.
Jadi: kamu tidak perlu menyiapkan CORS untuk menyunting. Kamu perlu
memikirkannya hanya kalau ekspor:false datang dan kamu memang
butuh hasil gambarnya. Kalau itu terjadi, kirim gambarnya sebagai
data: URI — bentuk itu selalu sealasan. Batas amannya sekitar
8 MB untuk satu postMessage; di atas itu gunakan
Blob.
Pesan ekspor juga selalu dijawab, termasuk waktu
gagal:
{ tie: 'gambar', ok: true, jpg: 'data:image/jpeg;base64,…', sebab: '' }
{ tie: 'gambar', ok: false, jpg: '', sebab: 'kanvas-ternoda' }
Ini kontraknya. Nama-nama di bawah tidak akan pernah diganti — lihat Janji di bawah.
| Dari editor | Artinya |
|---|---|
| siap | bingkai hidup. Membawa versi. |
| selesai | pemakai menekan Simpan. Membawa hasil. |
| final | pemakai keluar sambil menyimpan. Membawa hasil. |
| tutup | pemakai menekan silang. Lepas bingkainya. |
| muat | minta isi satu desain rak. Membawa id. |
| gambar | jawaban atas ekspor. Membawa jpg,
ok, sebab. Selalu dikirim, gagal sekalipun. |
| setting | pemakai menekan Setting (mode cetak). |
| hardproof | pemakai menekan Hardproof (mode cetak). |
| dibuka | desain selesai dibuka. Membawa id,
ok, ekspor, sebab. |
| Ke editor | Artinya |
|---|---|
| setelan | oper cfg. Boleh kapan saja. |
| buka | buka desain tanpa memuat ulang. Membawa opsi. |
| mulai | kembali ke layar pertama. |
| desain | jawaban atas muat. Membawa isi. |
| ekspor | minta gambar jadi. Boleh maksDim. |
| tutup | tutup editornya. |
Yang disimpan ke basis datamu adalah hasil.spec. Semuanya persen,
jadi bisa digambar ulang di ukuran berapa pun — cetak sekalipun.
| Bidang | Satuan |
|---|---|
| x, y | persen kanvas, 0–100. Titik tengah teks. |
| sizePct | persen tinggi kanvas |
| w | persen lebar kanvas. 0 = otomatis. |
| color | hex |
| align | left · center · right |
| tingkat | display · heading · subheading · body · caption |
Satu-satunya alamat luar yang dihubungi editor adalah Google Fonts. Tidak ada server kami, tidak ada kunci API, tidak ada backend. Halamanmu tidak mengirim apa pun ke mana pun kecuali yang kamu tulis sendiri.
Kalau Google Fonts diblokir — aturan CSP yang ketat, jaringan kantor, atau wilayah tertentu — editornya tetap bekerja: kanvas, susunan, ekspor, semuanya jalan. Yang berubah cuma hurufnya, jatuh ke huruf cadangan sistem. Karena tipografi justru alasan orang memakai editor ini, sebaiknya kedua alamat ini diizinkan:
Content-Security-Policy:
font-src https://fonts.gstatic.com;
style-src https://fonts.googleapis.com;
frame-src https://editor.mataanginproperti.com;
Sebutkan asal di setelanmu. Tanpa itu editor menerima pesan dari
halaman mana pun yang bisa menjangkaunya — termasuk yang ikut menyematkannya.
Dan di sisimu, periksa e.origin sebelum memercayai pesan yang masuk:
if(e.origin !== 'https://editor.mataanginproperti.com') return;
Draf dan rak "Desain Saya" tersimpan di localStorage milik alamat
editor, bukan milikmu. Artinya: hasil kerja pemakai bertahan antar kunjungan,
tapi tidak ikut berpindah kalau alamat editornya berubah, dan tidak
terlihat dari apps lain. Kalau kamu butuh arsip yang sungguhan, simpan
hasil.spec di tempatmu sendiri.
Nama yang sudah dibagikan tidak akan diganti. Alamat, nama pesan, kunci
setelan, dan bidang spec di halaman ini terkunci — ada pemeriksaan
di dalam uji terima kami yang gagal kalau salah satunya dihapus atau berganti
nama. Nama baru boleh bertambah kapan saja; yang lama tinggal.
Alasannya sederhana: sekali seratus apps memakai alamat ini, tiap nama jadi milik bersama. Yang menggantinya bukan yang menanggung akibatnya.
Pesan siap membawa versi. Pakai itu kalau kamu perlu
tahu berkas mana yang benar-benar termuat — peramban kadang menjawab dari
simpanannya sendiri. Kalau kamu ingin memaksa berkas segar, tambahkan penanda di
alamatnya: /v2/?v=2.31.1.
/v1/ masih menjawab dan memuat pustaka yang sama, untuk apps yang
sudah tayang lebih dulu.