feat: Der Zuschnitt ist ein Rahmen, den man aufzieht
Zoomen war das falsche Werkzeug. Man konnte nur naeher heran, aber nicht sagen, WAS man behalten will – und das Ergebnis war immer quadratisch, auch wenn das Logo breit ist. Jetzt liegt ein Rahmen auf dem Bild: ziehen zum Verschieben, acht Griffe zum Aufziehen. Aussen abgedunkelt, Drittel-Linien zum Ausrichten, und darunter steht, wie gross der Ausschnitt gerade ist. "Ganzes Bild" setzt zurueck. Das Seitenverhaeltnis des Ausschnitts bleibt. Ein breites Logo wird ein breites Logo, kein quadratisches mit Luft an den Seiten. Der Ausschnitt wird in BILDPUNKTEN gefuehrt, nicht in Bildschirmpunkten – umgerechnet wird nur fuer die Anzeige. So trifft das Ergebnis genau den Bereich im Rahmen, ohne dass sich ueber viele Zieh-Bewegungen Rundungsfehler aufaddieren. Am Bildrand haelt die gegenueberliegende Kante still, statt dass der Rahmen beim Anschlag mitwandert; zieht man einen Griff ueber die eigene Kante hinaus, bleibt sie stehen, statt sich umzustuelpen. Auf dem Telefon sind die Griffe groesser – mit dem Finger waeren vierzehn Pixel nicht zu treffen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9b9ce77267
commit
26718b1301
+70
-20
@@ -1774,38 +1774,88 @@ tr.row-dup {
|
||||
|
||||
/* --- Logo zuschneiden ---------------------------------------------------- */
|
||||
|
||||
/* Der Rahmen IST der Ausschnitt: Was hier steht, wird gespeichert. Deshalb
|
||||
nichts abdunkeln und keine Hilfslinien – man soll das Ergebnis sehen, nicht
|
||||
eine Vorschau davon. */
|
||||
.zuschnitt-rahmen {
|
||||
.zuschnitt-flaeche {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 0 auto var(--sp-3);
|
||||
border: 1px solid var(--border-strong);
|
||||
margin: 0 auto var(--sp-2);
|
||||
border-radius: var(--radius);
|
||||
/* Schachbrett: zeigt, wo das Bild durchsichtig ist. Bei einem freigestellten
|
||||
Logo ist das der Unterschied zwischen "weisser Kasten" und "nichts da". */
|
||||
background:
|
||||
repeating-conic-gradient(var(--border) 0% 25%, transparent 0% 50%) 50% / 16px 16px;
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.zuschnitt-rahmen.beweglich { cursor: grab; }
|
||||
.zuschnitt-rahmen.beweglich:active { cursor: grabbing; }
|
||||
.zuschnitt-rahmen img {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -50%;
|
||||
margin-top: 0;
|
||||
translate: 0 -50%;
|
||||
max-width: none;
|
||||
.zuschnitt-flaeche img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.zuschnitt-regler {
|
||||
.zuschnitt-rahmen {
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #fff;
|
||||
cursor: move;
|
||||
/* Alles ausserhalb abdunkeln – mit EINEM Schatten statt vier Kacheln.
|
||||
So bleibt der Ausschnitt das Helle, und man sieht sofort, was bleibt. */
|
||||
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
/* Drittel-Linien: helfen beim Ausrichten, ohne den Ausschnitt zuzustellen. */
|
||||
.zuschnitt-rahmen::before,
|
||||
.zuschnitt-rahmen::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0.35;
|
||||
}
|
||||
.zuschnitt-rahmen::before {
|
||||
border-left: 1px solid #fff;
|
||||
border-right: 1px solid #fff;
|
||||
left: 33.33%;
|
||||
right: 33.33%;
|
||||
}
|
||||
.zuschnitt-rahmen::after {
|
||||
border-top: 1px solid #fff;
|
||||
border-bottom: 1px solid #fff;
|
||||
top: 33.33%;
|
||||
bottom: 33.33%;
|
||||
}
|
||||
|
||||
.zuschnitt-griff {
|
||||
position: absolute;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: #fff;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
.griff-nw { left: -7px; top: -7px; cursor: nwse-resize; }
|
||||
.griff-n { left: calc(50% - 7px); top: -7px; cursor: ns-resize; }
|
||||
.griff-ne { right: -7px; top: -7px; cursor: nesw-resize; }
|
||||
.griff-w { left: -7px; top: calc(50% - 7px); cursor: ew-resize; }
|
||||
.griff-e { right: -7px; top: calc(50% - 7px); cursor: ew-resize; }
|
||||
.griff-sw { left: -7px; bottom: -7px; cursor: nesw-resize; }
|
||||
.griff-s { left: calc(50% - 7px); bottom: -7px; cursor: ns-resize; }
|
||||
.griff-se { right: -7px; bottom: -7px; cursor: nwse-resize; }
|
||||
|
||||
.zuschnitt-fuss {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
margin-bottom: var(--sp-2);
|
||||
}
|
||||
.zuschnitt-regler input[type="range"] { flex: 1; width: auto; }
|
||||
.zuschnitt-regler .icon { color: var(--muted); flex: none; }
|
||||
.zuschnitt-fuss span { flex: 1; font-variant-numeric: tabular-nums; }
|
||||
|
||||
/* Auf dem Telefon sind die Griffe mit dem Finger sonst nicht zu treffen. */
|
||||
@media (pointer: coarse) {
|
||||
.zuschnitt-griff { width: 20px; height: 20px; }
|
||||
.griff-nw, .griff-w, .griff-sw { left: -10px; }
|
||||
.griff-ne, .griff-e, .griff-se { right: -10px; }
|
||||
.griff-nw, .griff-n, .griff-ne { top: -10px; }
|
||||
.griff-sw, .griff-s, .griff-se { bottom: -10px; }
|
||||
.griff-n, .griff-s { left: calc(50% - 10px); }
|
||||
.griff-w, .griff-e { top: calc(50% - 10px); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user