add: core (01) драфт... работает!! Генерация SVG проходит!!!
This commit is contained in:
@@ -110,9 +110,21 @@ val=>{if(val)document.documentElement.classList.add('dark');else document.docume
|
||||
{% endblock EXTRA_LD_JSON %}</script>
|
||||
<script src="{% static 'js/alpine.min.js' %}" defer></script>
|
||||
<script src="{% static 'js/htmx.min.js' %}" defer></script>
|
||||
<script>
|
||||
document.addEventListener('htmx:configRequest', function(evt) {
|
||||
var token = '{{ csrf_token }}';
|
||||
if (!token) {
|
||||
var match = document.cookie.match(/csrftoken=([^;]+)/);
|
||||
if (match) token = match[1];
|
||||
}
|
||||
if (token) {
|
||||
evt.detail.headers['X-CSRFToken'] = token;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% block EXTRA_HEAD %}{% endblock EXTRA_HEAD %}
|
||||
</head>
|
||||
<body class="bg-stone-50 text-emerald-700 dark:bg-zinc-950 dark:text-emerald-100 font-mono">{% block ADD_CSS1 %}{% endblock %}{% block ADD_CSS2 %}{% endblock %}{% block ADD_CSS3 %}{% endblock %}{% block BODY %}
|
||||
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}' class="bg-stone-50 text-emerald-700 dark:bg-zinc-950 dark:text-emerald-100 font-mono">{% block ADD_CSS1 %}{% endblock %}{% block ADD_CSS2 %}{% endblock %}{% block ADD_CSS3 %}{% endblock %}{% block BODY %}
|
||||
{% include "block/header.html" %}
|
||||
<main id="main-content" class="mx-auto min-h-screen max-w-7xl px-4 py-8">
|
||||
{% block CONTENT %}{% endblock CONTENT %}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
{% if error %}
|
||||
<div class="text-rose-500 flex flex-col items-center gap-4 text-center px-6">
|
||||
<svg class="w-16 h-16 text-rose-500 opacity-80 animate-pulse" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
||||
</svg>
|
||||
<p class="font-mono text-sm font-bold uppercase tracking-wider text-rose-600 dark:text-rose-400">
|
||||
{{ error }}
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="w-full h-full flex items-center justify-center p-4 select-none overflow-hidden" id="svg-canvas-container">
|
||||
{{ svg_content|safe }}
|
||||
</div>
|
||||
|
||||
<!-- Плавающие кнопки действий -->
|
||||
<div class="absolute bottom-6 right-6 flex items-center gap-3 translate-y-20 group-hover:translate-y-0 transition-transform duration-300 pointer-events-none">
|
||||
<button id="like-to-gallery" type="button" title="Нравится!"
|
||||
class="pointer-events-auto flex items-center gap-2 bg-emerald-600/90 hover:bg-emerald-600 text-white text-xs font-bold uppercase tracking-wide backdrop-blur-md px-4 py-2.5 rounded-full shadow-xl transition-all hover:scale-105 active:scale-95 cursor-pointer">
|
||||
<span>Кандидат в галерею транса</span>
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -23,6 +23,7 @@
|
||||
hasChanges: true, /* Флаг наличия правок в форме для активности кнопки */
|
||||
hasImage: false, /* Флаг загрузки пользовательского файла */
|
||||
timer: null, /* Ссылка на таймер удержания анимации размышления */
|
||||
copied: false, /* Флаг успешного копирования в буфер */
|
||||
|
||||
/* Метод запуска состояния размышления (8 секунд) */
|
||||
startThinking() {
|
||||
@@ -32,6 +33,29 @@
|
||||
this.isLoading = false;
|
||||
this.hasChanges = false;
|
||||
}, 8000);
|
||||
},
|
||||
|
||||
copySvg() {
|
||||
const svg = document.querySelector('#preview svg');
|
||||
if (!svg) return;
|
||||
navigator.clipboard.writeText(svg.outerHTML).then(() => {
|
||||
this.copied = true;
|
||||
setTimeout(() => this.copied = false, 2000);
|
||||
});
|
||||
},
|
||||
|
||||
downloadSvg() {
|
||||
const svg = document.querySelector('#preview svg');
|
||||
if (!svg) return;
|
||||
const blob = new Blob([svg.outerHTML], {type: 'image/svg+xml;charset=utf-8'});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'hypn0-art.svg';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
}">
|
||||
|
||||
@@ -45,7 +69,9 @@
|
||||
@change="hasChanges = true"
|
||||
@input="hasChanges = true"
|
||||
@htmx:before-request="startThinking()"
|
||||
@htmx:after-request="isLoading = false; hasChanges = false"
|
||||
class="relative bg-white dark:bg-zinc-900 p-6 rounded-2xl shadow-sm border border-stone-200 dark:border-zinc-800 overflow-hidden">
|
||||
{% csrf_token %}
|
||||
|
||||
<!-- Фоновая спираль размышления при генерации (прижата снизу на всю левую панель) -->
|
||||
<div x-show="isLoading"
|
||||
@@ -65,6 +91,7 @@
|
||||
<label class="block text-sm font-bold mb-2 uppercase tracking-wider text-stone-500 dark:text-zinc-400">Источник</label>
|
||||
<div class="relative group">
|
||||
<input type="file" name="image" accept="image/*"
|
||||
@change="hasImage = $el.files.length > 0; hasChanges = true"
|
||||
class="absolute inset-0 w-full h-full opacity-0 cursor-pointer z-10">
|
||||
<div
|
||||
class="border-2 border-dashed border-stone-300 dark:border-zinc-700 group-hover:border-emerald-500 rounded-xl p-8 flex flex-col items-center justify-center text-center transition-colors">
|
||||
@@ -410,13 +437,17 @@
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<button
|
||||
class="bg-stone-800 text-white dark:bg-zinc-800 py-3.5 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-stone-700 transition-colors">
|
||||
type="button"
|
||||
@click="copySvg()"
|
||||
class="bg-stone-800 text-white dark:bg-zinc-800 py-3.5 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-stone-700 transition-colors cursor-pointer active:scale-95">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
|
||||
КОПИРОВАТЬ SVG
|
||||
<span x-text="copied ? 'СКОПИРОВАНО В БУФЕР!' : 'КОПИРОВАТЬ SVG'"></span>
|
||||
</button>
|
||||
<button
|
||||
class="bg-emerald-600 text-white py-3.5 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-emerald-500 transition-colors shadow-lg shadow-emerald-900/20">
|
||||
type="button"
|
||||
@click="downloadSvg()"
|
||||
class="bg-emerald-600 text-white py-3.5 rounded-xl font-bold flex items-center justify-center gap-2 hover:bg-emerald-500 transition-colors shadow-lg shadow-emerald-900/20 cursor-pointer active:scale-95">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M4 16v1a2 2 0 002 2h12a2 2 0 002-2v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
|
||||
СКАЧАТЬ
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user