Technikecke

Wie viele andere Student*innen auch nutze ich die Open-Source Karteikartensoftware Anki, um effektiver auswendig zu lernen. Gerade für Gebiete wie Anatomie ist der Bildverdeckungs-Kartentyp sehr nützlich.

Doch es gibt ein Problem: Bei großen Bildern wird alles extrem klein. Deshalb habe ich den Kartentyp so angepasst, dass hochformatige Bilder breiter (–> größer) anzeigt werden. Dadurch entsteht dann ein vertikaler Scrollbalken, doch durch eine weitere Anpassung wird die gerade aktive Bildverdeckung automatisch in die Mitte des Bildschirms gescrollt:

Screenshot von Anki mit einer langen Bildverdeckungs-Karte zur Lactosesynthese, die aktive Bildverdeckung ist in der Bildschirmmitte.

Selber Ausprobieren

Probiert es doch gerne selber einmal aus! Entweder ihr ladet euch einfach dieses Stapelpaket mit dem Notiztypen herunter, oder ihr passt euren Bildverdeckungstyp selber an.

via Stapelpaket

  1. Ladet euch einfach dieses Stapelpaket herunter und öffnet es in Anki.
  2. Nun müsst ihr euren bestehenden Bildverdeckungskarten den neuen Typ zuordnen: Öffnet die Kartenverwaltung
  3. In der Kartenverwaltung wählt ihr links Notiztypen –> Bildverdeckung
  4. Jetzt markiert ihr alle angezeigten Notizen (Strg + A), macht einen Rechtsklick –> Notiztyp ändern
  5. Dort wählt ihr dann den gerade importierten Notiztypen, er müsste Bildverdeckung-[irgendwas] heißen.

Manuell

  1. Öffnet Anki
  2. Ruft Extras –> Notiztypen verwalten auf
  3. Wählt “Bildverdeckung” aus und geht auf “Karten ...”
  4. Ersetzt den kompletten Code bei “Vorlage für Vorderseite” mit:
{{#Kopfzeile}}<div>{{Kopfzeile}}</div>{{/Kopfzeile}}
<small>{{Deck}}</small>
<div style="display: none">{{cloze:Verdeckung}}</div>
<div id="err"></div>
<div id="image-occlusion-container">
    {{Bild}}
    <canvas id="image-occlusion-canvas"></canvas>
</div>
<script>
function scrollToActiveOcclusion() {
  const canvas = document.getElementById('image-occlusion-canvas');
  // Vorderseite: .cloze, Rückseite: .cloze-highlight
  const shapes = [...document.querySelectorAll('.cloze[data-shape], .cloze-highlight[data-shape]')];
  if (!canvas || !shapes.length) return;

  const top = Math.min(...shapes.map(s => +s.dataset.top));
  const bottom = Math.max(...shapes.map(s => +s.dataset.top + +s.dataset.height));
  const center = (top + bottom) / 2;

  const box = canvas.getBoundingClientRect();
  const y = box.top + window.scrollY + center * box.height;

  const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
  const target = y - window.innerHeight / 2;

  // Zentrieren lohnt sich nicht, wenn darunter kaum noch Platz ist -> ganz nach unten
  const toBottom = maxScroll - target < window.innerHeight / 4;
  window.scrollTo({ top: toBottom ? maxScroll : Math.max(0, target) });
}

try {
  const container = document.getElementById('image-occlusion-container');
  const img = container.querySelector('img');

  const imgReady = img.complete
    ? Promise.resolve()
    : new Promise(resolve => {
        img.addEventListener('load', resolve, { once: true });
        img.addEventListener('error', resolve, { once: true });
      });

  imgReady.then(() => {
    // 1. Klasse anhand der echten Bildmaße
    container.classList.toggle('tall', img.naturalHeight > img.naturalWidth);

    anki.imageOcclusion.setup();
    
    setTimeout(function(){
    requestAnimationFrame(scrollToActiveOcclusion);
    }, 10);
  });
} catch (exc) {
  document.getElementById("err").innerHTML = `Fehler beim Laden der Bildverdeckung. Ist Ihre Anki-Version aktuell?<br><br>${exc}`;
}
</script>
  1. Ersetzt den kompletten Code bei “Vorlage für Rückseite” mit:
{{#Kopfzeile}}<div>{{Kopfzeile}}</div>{{/Kopfzeile}}
<small>{{Deck}}</small>
<div style="display: none">{{cloze:Verdeckung}}</div>
<div id="err"></div>
<div id="image-occlusion-container">
    {{Bild}}
    <canvas id="image-occlusion-canvas"></canvas>
</div>
<script>
function scrollToActiveOcclusion() {
  const canvas = document.getElementById('image-occlusion-canvas');
  // Vorderseite: .cloze, Rückseite: .cloze-highlight
  const shapes = [...document.querySelectorAll('.cloze[data-shape], .cloze-highlight[data-shape]')];
  if (!canvas || !shapes.length) return;

  const top = Math.min(...shapes.map(s => +s.dataset.top));
  const bottom = Math.max(...shapes.map(s => +s.dataset.top + +s.dataset.height));
  const center = (top + bottom) / 2;

  const box = canvas.getBoundingClientRect();
  const y = box.top + window.scrollY + center * box.height;

  const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
  const target = y - window.innerHeight / 2;

  // Zentrieren lohnt sich nicht, wenn darunter kaum noch Platz ist -> ganz nach unten
  const toBottom = maxScroll - target < window.innerHeight / 4;
  window.scrollTo({ top: toBottom ? maxScroll : Math.max(0, target) });
}

try {
  const container = document.getElementById('image-occlusion-container');
  const img = container.querySelector('img');

  const imgReady = img.complete
    ? Promise.resolve()
    : new Promise(resolve => {
        img.addEventListener('load', resolve, { once: true });
        img.addEventListener('error', resolve, { once: true });
      });

  imgReady.then(() => {
    // 1. Klasse anhand der echten Bildmaße
    container.classList.toggle('tall', img.naturalHeight > img.naturalWidth);

    anki.imageOcclusion.setup();
    
    setTimeout(function(){
    requestAnimationFrame(scrollToActiveOcclusion);
    }, 10);
  });
} catch (exc) {
  document.getElementById("err").innerHTML = `Fehler beim Laden der Bildverdeckung. Ist Ihre Anki-Version aktuell?<br><br>${exc}`;
}
</script>

<div><button id="toggle">Verdeckungen ein/aus</button></div>
  1. Ersetzt den kompletten Code bei “Stil” mit:
#image-occlusion-canvas {
    --inactive-shape-color: #ffeba2;
    --active-shape-color: #ff8e8e;
    --inactive-shape-border: 1px #212121;
    --active-shape-border: 1px #212121;
}

.card {
    font-family: arial;
    font-size: 20px;
    text-align: center;
    color: black;
    background-color: white;
    margin-bottom: 75px;
}
img{
max-height: none !important;
max-width: none !important;
width: 100%;
height: auto;
}
#image-occlusion-container.tall{ 
		max-height: 150vh !important;
}

Fragen oder Probleme? Schreibt mir an blog@anghenfil.de!

#Anki #Flashcards #Karteikarten #Tipps #OpenSource