0 votes
in SoSci Survey (dt.) by s214298 (175 points)
closed by SoSci Survey

Vielen Dank für die Antworten!

Dazu darf ich auf folgende Frage im Support verweisen:
https://support.soscisurvey.de/?qa=18380/zeichenfunktion-mit-bild-als-untergrund

Wenn ich denselben Code wie in der verlinkten Frage nutze, tritt bei mir das gleiche Problem auf wie in der Frage beschrieben: Ich kann die Zeichenfunktion auf dem in der Zeichenfläche hochgeladenen Bild nicht nutzen. Das Problem unter https://support.soscisurvey.de/?qa=18380/zeichenfunktion-mit-bild-als-untergrund scheint gelöst worden zu sein, leider wurde jedoch kein Lösungsweg hinterlegt.

Können Sie einen Fehler im folgenden Ausschnitt des Codes erkennen?

<div style="text-align: center;">
  <canvas id="%q.id%canvas" width="300" height="450" style="border: 1px solid #CCCCCC; "></canvas>
</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%btnLineWidth = 2" title="Dünne Linie">Dünne Linie</button>
    <button type="button" id="%q.id%btnLineWidth = 5" title="Dicke Linie">Dicke Linie</button>
    <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>


<script>
function Scribbler(qID, canvas) {
  var state = "new";  // new, init, changed, sent
  var ctx = canvas.getContext('2d');
  var img = new Image();
  img.src= "pro://Beispielbild-unsplash.jpg"
  img.onload = function () {
    var pattern = ctx.createPattern(img, "no-repeat");
    ctx.fillStyle = pattern;
    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 = 2;
    ctx.strokeStyle = 'blue';
    ctx.strokeLine(10, 10, 100, 100);
    ctx.shadowBlur = 0,5;
    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();
    return SoSciTools.stopEvent(e);
  };

  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 && 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>

Dort wo Sie im Code ctx.lineWidth = 2; finden, können Sie auch eine Farbe für den Strich definieren, vgl. https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle

Danke, das hat geklappt.

Ja, aber Sie werden dafür ein wenig JavaScript basteln müssen. Im Prinzip müssen Sie nur per Knopfdruck in einer Variable die gewünschte Strichstärke ablegen - und beim ctx.lineWidth = 2; ersetzen Sie die 2 dann durch die Variable mit der Strichstärke.

Das Erstellen der Knöpfe hat funktioniert. Nun weiß ich allerdings nicht, wie ich die verschiedenen Strichstärken mit dem entsprechenden Knopfdruck verknüpfen kann (siehe Code oben).

closed with the note: Die Antworten sind auf die Kommentare verstreut.
by SoSci Survey (343k points)
> Können Sie einen Fehler im folgenden Ausschnitt des Codes erkennen?

Möchten Sie bitte mal einen Pretest-Link direkt (!) zu der Seite mit Frage und Code posten? Dann kann ich mir das live ansehen.

> Das Erstellen der Knöpfe hat funktioniert. Nun weiß ich allerdings nicht, wie ich die verschiedenen Strichstärken mit dem entsprechenden Knopfdruck verknüpfen kann

Sie brauchen im JavaScript-Code eine gloable Variable, also außerhalb der Funktionen z.B.

var breite = 2;

Und dann ändern Sie das mit den Knöpfen:

document.getElementById("Knopf1").addEventListener("click", function() {
  breite = 4;
});

Und schließlich wird aus

ctx.lineWidth = 2;

der Code

ctx.lineWidth = breite;

Und ja, wenn Sie vorher noch nicht mit JavaScript gearbeitet oder generell nicht programmiert haben, dann ist das ein ambitionierter Einstieg. Aber es lohnt sich, ein wenig im Netz zu suchen, und den Code inhaltlich nachzuvollziehen!
by s214298 (175 points)
Hier der Pretest-Link: https://www.soscisurvey.de/test310497/?act=b4xN0E3i2ghOBoOi0mg5npPf

Danke auch für die Rückmeldung zur Erstellung der Knöpfe mit verschiedenen Strichstärken. Es hat noch nicht ganz geklappt, aber da ich tatsächlich zuvor noch nicht programmiert habe, hilft es sicherlich, wie Sie bereits vorgeschlagen haben, sich diesbezüglich noch ein wenig einzulesen.
by SoSci Survey (343k points)
Die Fehlerkonsole im Browser (Strg+Shift+Buchstabe I wie Ida) zeigt folgenden Fehler:

> Uncaught ReferenceError: btnClear is not define

Das bezieht sich auf dieses IF:

if (btnClear) {

Und das Problem liegt darin, dass die ganzen Befehle nicht mehr innerhalb von Scribbler() sind. Suchen Sie mal diese Stelle:

   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);

Die geschweifte Klammer hinter

var steps = [];

muss m.E. weg. Sodass die weiteren Funktionen innerhalb der Funktion (Klasse) Scribbler stehen. Denn in dieser ist btnClear definiert, vgl.

var btnClear = document.getElementById("%q.id%btnClear");
by s214298 (175 points)
Danke für den Hinweis. Ich habe es nun tatsächlich so gelöst, dass ich die geschweifte Klammer hinter

    var steps = [];

gelöscht und hinter

    ctx.fillRect(0, 0, canvas.width, canvas.height);

wiederum eingefügt habe.

Herzlichen Dank nochmals für Ihre 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

...