SVG 편집기는 그림과 코드를 나란히 보여 줍니다. 코드에서 바꾼 내용은 곧바로 미리 보기에 나타나고, 캔버스에서 옮기거나 크기나 색을 바꾼 것은 코드에 반영됩니다. 덕분에 큰 그래픽 프로그램을 열지 않고도 아이콘, 로고, 차트, 일러스트를 빠르게 손볼 수 있습니다.
모든 것이 브라우저에서 실행됩니다. 파일은 업로드되지 않으며 가입도 광고도 없습니다.
태그, 속성, 값이 각각의 색으로 표시되고, 줄 번호, Tab 들여쓰기, 태그 자동 닫기, 줄 번호가 붙은 알기 쉬운 오류 메시지가 있습니다.
클릭, 끌기, 핸들로 크기 조절, 회전, 뒤집기, 복제, 앞으로 가져오기와 뒤로 보내기 - 사각형, 원, 패스, 다각형, 텍스트, 그룹.
색 선택기나 값으로 채우기와 윤곽선, 불투명도, 윤곽선 두께, 파선, 둥근 선 끝이나 사각 선 끝.
그림 자체의 좌표로 원하는 격자 간격. 도형이 격자선에 정확히 붙습니다 - "맞춤"을 해제하면 자유롭게 움직입니다.
사각형, 타원, 원, 선, 자유 곡선, 텍스트 - 새 도형의 색은 원하는 대로.
SVG(쓴 그대로, 정리 또는 축소), 투명 배경 PNG, JPG, WebP, 데이터 URI, Base64, CSS, React 컴포넌트.
모든 https 페이지(와 localhost)는 <iframe>과 ?embed=1로 편집기를 삽입할 수 있습니다 - 가입도 키도 필요 없습니다. 삽입되면 편집기는 이 텍스트를 숨기고 저장 버튼을 보여 줍니다. 그림을 넣고 빼는 방법은 두 가지입니다.
src=는 파일을 열고(서버가 CORS를 허용해야 합니다), webhook=은 "저장"(Ctrl+S) 시 그림을 그 주소로 보내게 합니다. Authorization: Bearer … 헤더를 쓰려면 &token=…을, 변경할 때마다 저장하려면 &auto를 추가하세요.
<iframe src="https://svg.giit.ch/?embed=1&src=https://your-site.com/docs/logo.svg&webhook=https://your-site.com/save.php"
allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
웹훅은 JSON { editor, event: "save", id, name, content, updated }이 담긴 POST를 받습니다. 이를 저장하는 작은 PHP 스크립트:
<?php
header('Access-Control-Allow-Origin: https://svg.giit.ch');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
file_put_contents(__DIR__ . "/docs/$name.svg", $d['content']);
echo '{"ok":true}';
편집기가 svgeditor:ready를 보내면 페이지는 svgeditor:load로 답하고, 편집기는 svgeditor:loaded, 실제 편집 시 svgeditor:change, 사용자가 저장할 때 svgeditor:save를 알립니다. 페이지는 svgeditor:get(현재 상태)이나 svgeditor:save(저장 누르기)를 보낼 수 있습니다. 그러면 저장은 내 로그인과 세션을 거칩니다.
<iframe id="ed" src="https://svg.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
<script>
const ed = document.getElementById('ed');
const ORIGIN = 'https://svg.giit.ch';
addEventListener('message', async e => {
if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
const m = e.data;
if (m.type === 'svgeditor:ready') { // 편집기가 준비됨: 그림을 넘깁니다
ed.contentWindow.postMessage({
type: 'svgeditor:load',
name: 'Logo',
content: await (await fetch('/docs/logo.svg')).text(),
}, ORIGIN);
}
if (m.type === 'svgeditor:change') document.title = '● not saved'; // 실제 편집
if (m.type === 'svgeditor:save') { // 사용자가 "Save"를 클릭함
await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: m.name, content: m.content }) });
document.title = 'Saved';
}
});
// 내 페이지의 저장 버튼: 응답은 svgeditor:save로 옵니다
function saveNow() { ed.contentWindow.postMessage({ type: 'svgeditor:get' }, ORIGIN); }
</script>
내 페이지 안의 AI 도우미: 프레임 안에서도 작동합니다. iframe에 allow="clipboard-write"가 있으면 "프롬프트 복사"가 클립보드를 직접 사용합니다(없으면 편집기가 예전 복사 명령을 쓰거나 손으로 복사할 프롬프트를 보여 줍니다). AI가 보낸 링크는 다른 웹사이트 안의 편집기에 닿을 수 없으므로, 편집기는 AI와 사용자에게 AI의 답변 전체를 편집기에 붙여 넣거나 편집기를 별도의 창으로 열라고 안내합니다.
window.open("https://svg.giit.ch/?embed=window", "svgeditor-17")은 전체 편집기를 별도의 창으로 열고 window.opener와 같은 메시지를 주고받습니다. AI의 링크는 그 창에 닿습니다. svgeditor:load에는 context: { host, title, rules }도 담을 수 있으며(그러면 AI 프롬프트가 그림의 소속을 알리고 내 규칙을 따릅니다), hook: { url, token }, 즉 저장되지 않는 이 그림 전용 웹훅도 담을 수 있습니다. 저장하지 않은 변경이 있는 채로 창을 닫으면 svgeditor:closing을 보냅니다.
편집기에 내 프롬프트, 내 사이트의 주소, 이 편집기 세션용 키를 넘기세요. 그러면 AI 대화 상자에 내 사이트와 "연결됨", AI에게 전하는 내용, 현재 그림 변경 또는 새 그림 만들기 선택이 표시되고, 프롬프트 복사가 이를 모두 합칩니다. AI는 결과를 키와 함께 내 서버로 POST하고, 페이지가 이를 편집기에서 엽니다. 새 그림은 따로 열리며 사용자의 브라우저에 남습니다. 편집기 세션당 키 하나: 편집기가 열려 있는 동안 유효하며, 키가 없을 때만 편집기가 svgeditor:key-request로 요청합니다. 편집기는 키를 직접 보내거나 저장하지 않습니다. 주소는 내 호스트나 그 하위 도메인의 https여야 합니다.
const key = async () => (await fetch('/api/ai-key.php?doc=17')).json(); // 편집기 세션당 키 하나
const k = await key();
ed.contentWindow.postMessage({ type: 'svgeditor:load', name: 'Flyer', content, ai: {
label: 'My Site', prompt: 'Keep the [[placeholders]]. Write in German.',
endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
// svgeditor:loaded의 id를 기억하고 id가 다른 change/save/closing은 무시
// 편집기에 키가 없을 때만:
if (m.type === 'svgeditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'svgeditor:ai', key: k.key }, ORIGIN); }
// 편집기가 열려 있는 동안 매분 서버에 알림. 편집기나 페이지를 닫으면 키가 무효가 됨
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// 서버에 결과가 있음(폴링, SSE …): target은 "current" 또는 "new"
ed.contentWindow.postMessage({ type: 'svgeditor:load', name: 'Flyer', content: draft, from: 'ai', target }, ORIGIN);
<?php // api/ai-key.php - 로그인한 사용자의 이 편집기 세션 키 (페이지가 호출)
session_start(); // 사용자가 이 그림을 편집할 수 있는지 확인
$key = bin2hex(random_bytes(24));
$_SESSION['ai'][hash('sha256', $key)] = ['doc' => (int)$_GET['doc'], 'seen' => time()]; // 또는 데이터베이스에. ?alive=가 seen을 다시 설정
echo json_encode(['key' => $key]);
<?php // api/ai-result.php - AI가 여기로 POST (CORS 헤더 없음: AI는 서버에서 호출)
$key = preg_replace('/^Bearer\s+/', '', $_SERVER['HTTP_AUTHORIZATION'] ?? '');
$row = find_key(hash('sha256', $key)); // 데이터베이스: 무효가 아니고 최근 3분 안에 확인된 키
if (!$row) { http_response_code(401); exit('{"ok":false,"error":"key not valid"}'); }
$d = json_decode(file_get_contents('php://input', false, null, 0, 2000000), true);
save_draft($row['doc'], $d['content'], $d['target'] === 'new' ? 'new' : 'current'); // 페이지가 svgeditor:load로 표시
echo '{"ok":true}';
키는 최소 128비트의 무작위 값으로 만들고, 해시만 저장하고, 각각을 로그인한 사용자, 그림, 이 편집기 세션에 묶고, 세션마다 하나씩 만들고, 페이지가 세션이 열려 있다고 알리는 동안만 유효하게 하며, 편집기나 페이지가 닫히면 무효로 하세요.
전체 프로토콜은 llms.txt에 있습니다 - AI에게 주면 내 시스템에 맞는 연결을 만들어 줍니다. LaTeX 편집기도 접두사 latexeditor:로 똑같이 작동합니다 - latex.giit.ch.
아니요. 편집기는 전부 브라우저에서 실행됩니다. 연 파일과 코드는 어떤 서버로도 보내지지 않으며, 초안은 브라우저의 로컬 저장소에만 보관됩니다.
브라우저에만 저장됩니다. 편집기는 그림을 몇 개든 그곳에 보관합니다. 왼쪽 위의 폴더 버튼(내 그림)을 클릭해 열기, 이름 바꾸기, 복제, 다운로드, 삭제를 할 수 있습니다. 아무것도 업로드되지 않습니다. 브라우저의 사이트 데이터를 지우면 함께 삭제되므로 보관할 그림은 다운로드하세요.
SVG를 열거나 붙여 넣고 "내보내기"를 클릭한 뒤 PNG를 고르고 크기(1×, 2×, 4× 또는 사용자 지정)를 정해 "다운로드"를 클릭하세요. 색을 고르지 않으면 배경은 투명하게 유지됩니다.
네. 도형을 클릭하면 선택됩니다. 끌어서 옮기고, 작은 사각형으로 크기를 바꾸고, 회전, 뒤집기, 색 변경을 할 수 있습니다. 왼쪽 코드도 함께 바뀝니다.
격자는 그림 자체의 좌표로 안내선을 보여 줍니다. 켜져 있으면 옮기거나 그리는 도형이 격자선에 정확히 붙습니다. 격자는 보이게 두고 도형을 자유롭게 움직이려면 "맞춤"을 해제하세요.
네. 내보내기에서 "React 컴포넌트 (JSX)"를 고르세요. stroke-width 같은 속성은 strokeWidth로, class는 className으로 바뀌며, 컴포넌트는 추가 props도 받습니다.
네, 어떤 AI든 됩니다 - ChatGPT, Claude, Gemini, Copilot 또는 코딩 도구의 AI. "AI 도우미", 이어서 "프롬프트 복사"를 클릭하고 AI에 붙여 넣은 뒤 무엇을 그릴지 말해 주세요. AI가 링크로 답하면 클릭하세요. 그림이 편집기에 나타납니다. AI는 열린 그림을 바꾸거나 다른 그림 옆에 새 그림을 만들 수 있습니다. 설치할 것은 없으며 "실행 취소"로 모든 변경을 되돌릴 수 있습니다.
네. iframe으로 삽입하고 postMessage로 그림을 주고받거나, 저장한 모든 버전을 웹훅으로 내 서버에 보내게 하세요. 예제는 내 웹사이트에서 편집기 사용하기를 보세요.
아니요. 편집기는 무료이며 광고도 가입도 없습니다.