JavaScript for dynamic text onDrop

Twine Version: Sugarcube (but this is really a JavaScript question)

I’m getting into the weeds with my JavaScript, trying to create dynamic text onDrop().
My goal is to have the player drag some text from one side of the screen to the other, drop the text in the new field, and then see a new message appear below the dropped text.

I’ve gotten pretty close to this goal with a little help from AI, and a few tweeks of my own, but the following code still has some problems I’m trying to address.

  1. The printed outputarea message always appears above the dropped text. I’d like those to be reversed. so the dropped text (and any additional dropped text added later) appears above the outputarea division.
  2. If the message has already been printed, then the printed message becomes a sort of “blackhole”— when text is dropped into outputarea division, the dropped text disappears permanently.
  3. In rare cases, the drag function picks up both items, instead of selectively one or the other.

My code so far
Javascript


/* --- Drag and Drop Functions --- */
window.allowDrop = function (ev) {
    ev.preventDefault();
};

window.drag = function (ev) {
    // Store the ID of the dragged element
    ev.dataTransfer.setData("text", ev.target.id);
};

window.drop = function (ev) {
    ev.preventDefault();
    // Get the ID of the dragged element
    var data = ev.dataTransfer.getData("text");
    // Append the dragged element to the drop target
    ev.target.append(document.getElementById(data));
    const newtext="I dropped something"
    const outputArea = document.getElementById('outputArea');
  	$(outputarea).text(newtext);
};


My passage

<div class='parent interrogate-win'>

<div id="interrogate-win-child1" class="win-child" ondrop="window.drop(event)" ondragover="window.allowDrop(event)">
    <div id="item1" class="draggable-item" draggable="true" ondragstart="window.drag(event)">[[Item 1]]</div>
    <div id="item2" class="draggable-item" draggable="true" ondragstart="window.drag(event)">[[Item 2]]</div>
	</div>


	<div id="interrogate-win-child2" class="win-child" ondrop="window.drop(event)" ondragover="window.allowDrop(event)">
		<div id="outputarea"></div>	
    
	</div>

</div>


My CSS

.interrogate-win {
        display: flex;
        justify-content: center;
}

    .win-child {
  display: inline-block; 
  text-align: left;
  width: 45%;
  margin: 10px; 
  border: 2px solid #000; 
  padding: 10px; 
    }

    .draggable-item {
        width: flex;
        height: 50px;
     //   background-color: lightblue;
        margin: 5px;
        cursor: grab;
        text-align: center;
        line-height: 50px;
    }

.draggable {
  cursor: grab;
  position: relative; /* Essential for positioning during drag */
  display: inline-block; /* Allows the element to move freely */
}

.draggable:active {
  cursor: grabbing;
}

.passage{
  background: white;
  color:black;
}
1 Like

Update: After extensive debugging at the console.log level, I realized that the reason the screen was going dark was that Twine was doing what Twine does, advancing to a passage when I clicked on a link, a passage which didn’t have any content. Well that was embarrassing. I’ll mark this as solved.

Earlier message:
One step closer. I added an “inputarea” to my passage, and rewrote the ondrop function below.
this solved the problems 1 and 2.

Biggest problem now is that if I drop the text upon itself (click, drop) the whole screen goes dark!
Also, now it is no longer possible to drag the text back to the left side, although I’m not sure I really want that anyway.


window.drop = function (ev) {
    ev.preventDefault();
    // Get the ID of the dragged element
    var data = ev.dataTransfer.getData("text");
    //ev.target.append(document.getElementById(data));	
  	const inputarea = document.getElementById('inputarea');
  
    // Now instead of dragged element to the drop target,it appends on inputarea div. 
  	inputarea.append(document.getElementById(data));
    const newtext="I dropped something";
    const outputArea = document.getElementById('outputArea');
  	$(outputarea).text(newtext);
};
2 Likes