0 votes
in SoSci Survey (dt.) by s109993 (10.3k points)

Guten Morgen,

ich habe eine Zeichenfläche in dem Fragetyp "Datei-Inhalt übertragen", welche die Zeichnung als Bild abspeichert. Das funktioniert auch super. Nur nicht auf Geräten mit Touchscreen. Es zeichnet zwar Punkte, wo ich mein Finger aufsetze, aber es sind keine Linien möglich. Wenn ich den Code richtig verstehe, sollte er doch Toucscreen unterstützen?!

Pre-Testlink auf direkte Seite:
https://ofb.iea-hamburg.de/coactiv_pck/?act=DhF4KyZV6RAxqkXDCSfwdR74

Viele Grüße

Ich nutze folgenden Code:

<div style="text-align: center;">
  <canvas id="%q.id%canvas" width="600" height="600" style="border: 1px solid #CCCCCC;">
</canvas>

    <textarea placeholder="Hier können Sie Ihrer Zeichnung einen Kommentar hinzufügen" id="I001_01" name="I001_01"></textarea>


</div>
<!-- Note: Remove buttons as required -->
<div style="display: flex; justify-content: space-between; width: 300px; margin: 1em auto 2em;">
    <button type="button" id="%q.id%btnUndo"  title="Rückgängig">◀ Rückgängig</button>
    <button type="button" id="%q.id%btnClear"  title="Bild löschen">Nochmal von vorne</button>
    <button type="button" id="%q.id%btnSend" >Fertig, Weiter</button>
</div>


<style>
textarea {

 background: transparent;  
    width: 600px;
    height: 100px;
    outline: none;
box-shadow: inset 2px 2px 2px #ddd;

 
}

   

</style>

<script>
function Scribbler(qID, canvas) {
  var state = "new";  // new, init, changed, sent
  var ctx = canvas.getContext('2d');
  // Start white
  ctx.fillStyle = "#FFFFFF";
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  var isDrawing = false;
  var btnClear = document.getElementById("%q.id%btnClear");
  var btnSend = document.getElementById("%q.id%btnSend");
  var btnUndo = document.getElementById("%q.id%btnUndo");
  var steps = [];

  function getPos(e) {
    var org = SoSciTools.getNodePos(canvas);
    var pos = SoSciTools.getMousePos(e);
    return {
      x : pos.x - org.x,
      y : pos.y - org.y
    };
  }

  function onDown(e) {
    state = "changed";
    storeStep();
    isDrawing = true;
    ctx.beginPath();
    ctx.lineWidth = 1;
    ctx.shadowBlur = 1;
    ctx.lineJoin = ctx.lineCap = 'round';
    ctx.shadowColor = 'rgb(0, 0, 0)';
    var pos = getPos(e);
    ctx.moveTo(pos.x, pos.y);
    // Draw first dot
    onMove(e);
  }

  function onMove(e) {
    if (!isDrawing) {
      return;
    }
    var pos = getPos(e);
    ctx.lineTo(pos.x, pos.y);
    ctx.stroke();
  };

  function onUp() {
    isDrawing = false;
  };

  function onStop() {
    isDrawing = false;
  }

  function onClear() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  }

  function storeStep() {
    steps.push(canvas.toDataURL());
  }

  function onUndo() {
    // based on https://www.codicode.com/art/undo_and_redo_to_the_html5_canvas.aspx
    if (steps.length === 0) {
      return;
    }
    var recent = steps.pop();
    var canvasPic = new Image();
    canvasPic.addEventListener("load", function () {
      ctx.drawImage(canvasPic, 0, 0);
    });
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    canvasPic.src = recent;
  }

  // Enable all the events
  if (Modernizr.pointerevents) {
    canvas.addEventListener("pointerdown", onDown, false);
    canvas.addEventListener("pointermove", onMove, false);
    canvas.addEventListener("pointerup", onUp, false);
    canvas.addEventListener("pointerout", onStop, false);
  } else {
    SoSciTools.attachEvent(canvas, ["mousedown", "touchstart"], onDown);
    SoSciTools.attachEvent(canvas, ["mousemove", "touchmove"], onMove);
    SoSciTools.attachEvent(canvas, ["mouseup", "touchend"], onUp);
    SoSciTools.attachEvent(canvas, ["mouseout", "touchcancel"], onStop);
  }

  if (btnClear) {
    btnClear.addEventListener("click", function() {
      if (confirm("Möchten Sie das Bild löschen?")) {
        onClear();
      }
    });
  }

  if (btnUndo) {
    btnUndo.addEventListener("click", onUndo);
  }
  
  // File transfer part
  function sendImage() {
    var imageBlob = canvas.toBlob(%q.id%.sendBLOB);
    state = "sent";
    return true;
  }

  // Function to be called when the blob is to be send
  function blobGetter(blobHandler) {
    // Only send something when changed since init or sent
    if (state !== "changed") {
      return false;
    }
    canvas.toBlob(blobHandler);
    state = "sent";
    return true;
  }

  // Use custom send button
  if (btnSend) {
    // Use custom submit button
    btnSend.addEventListener("click", sendImage);
    // Hide original button
    SoSciTools.submitButtonsHide();
  }

  // Alway send on form submission
  window.addEventListener("load", function() {
    %q.id%.registerOnSubmit(blobGetter);
  });
}

new Scribbler("%q.id%", document.getElementById("%q.id%canvas"));
</script>

1 Answer

0 votes
by SoSci Survey (306k points)
selected by s109993
 
Best answer

Wenn man ganz schnell ist, bekommt man nicht nur einen Punkt, sondern auch einen kleinen Strich :)

Das Problem ist, dass die Seite zu scrollen beginnt, sobald man auf dem Mobilgerät eine vertikale Bewegung ausführt. Um das zu verhindern sind zwei Änderungen erforderlich. Erstens ganz oben im Code wird der style

  <canvas id="%q.id%canvas" width="300" height="300" style="border: 1px solid #CCCCCC;"></canvas>

wie folgt ergänzt

  <canvas id="%q.id%canvas" width="300" height="300" style="border: 1px solid #CCCCCC; touch-action: none;"></canvas>

Und damit es auch auf älteren Browsern funktioniert, ist unten bei onMove() noch ein SoSciTools.stopEvent() erforderlich.

  function onMove(e) {
    if (!isDrawing) {
      return;
    }
    var pos = getPos(e);
    ctx.lineTo(pos.x, pos.y);
    ctx.stroke();
    return SoSciTools.stopEvent(e);
  };

Wir aktualisieren die Vorlage natürlich auch gleich noch.

by s109993 (10.3k points)
Funktioniert- super Sache. Danke für die schnelle Hilfe!

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...