Image on top of dialogue box (Twine 2.1.3 SugarCube 2.18.0)

0 votes
asked Nov 11 by CyberCoder (130 points)
edited 6 days ago by CyberCoder

Hello, I'm trying to find a way to put an image on top of my dialogue box if that's possible.

My Story StyleSheet looks like this:

div.message {
	border-style: solid;
	border-width: 3px;
	border-radius: 1em;
	padding: 10px;
} 

And my passage looks like this:

<div class="message"> <img src="https://screenshots.firefoxusercontent.com/images/0b5d922c-e2a2-4527-814b-7bad2d9bd9c2.png"> //Hello world!//</div> 

And my javascript:

// dialog API macro set, by chapel; for sugarcube 2
// version 1.0
// see the documentation: https://github.com/ChapelR/custom-macros-for-sugarcube-2#dialog-api-macros

// <<dialog>> macro
Macro.add('dialog', {
	   tags : null,
	handler : function () {

		var content = this.payload[0].contents;
		
		if (this.args.length > 1) {
			var title = this.args[0];
			this.args.deleteAt(0);
			this.args.push('macro-' + this.name);
			var classNames = this.args.join(' ');
		} else if (this.args.length === 1) {
			var title = this.args[0];
			var classNames = 'macro-' + this.name;
		} else {
			var title = '';
			var classNames = 'macro-' + this.name;
		}
		
		Dialog.setup(title, classNames);
		Dialog.wiki(content);
		Dialog.open();
		
	}

});

// <<popup>> macro
Macro.add('popup', {
	handler : function () {
		
		if (this.args.length > 2) {
			var passageName = this.args[0];
			var title = this.args[1];
			this.args.deleteAt(0, 1);
			this.args.push('macro-' + this.name);
			var classNames = this.args.join(' ');
		} else if (this.args.length === 2) {
			var passageName = this.args[0];
			var title = this.args[1];
			var classNames = 'macro-' + this.name;
		} else if (this.args.length === 1) {
			var passageName = this.args[0];
			var title = '';
			var classNames = 'macro-' + this.name;
		} else {
			return this.error('need at least one argument; the passage to display');
		}
		
		Dialog.setup(title, classNames);
		Dialog.wiki(Story.get(passageName).processText());
		Dialog.open();
		
	}

});

However, I want the image to be over the box, not in it. If this isn't possible, I could just go with the way it is, except I need the dialogue to be located at the top of the box, not at the bottom. Is there a way to do this?

1 Answer

+1 vote
answered 6 days ago by Chapel (30,050 points)

Can we see more passage code? How are using the dialog macros in the passage? Im having trouble figuring out exactly how they fit in. Is the html code you posted meant to appear inside the box created by one of those macros? I'm thinking you mean something like this: 

-----------------------
| web page 
| 
|   ---------------
|   | dialog box
|   | image
|   | text
|   |

But I'm not clear on what you've already tried and what exactly that is generating. 

commented 6 days ago by CyberCoder (130 points)

Okay so after reviewing my post I realized how vague it was. Sorry! My thought process in approaching my twine story is that I wanted my players to be able to interact with the characters in the game, by clicking on their names and having a tiny dialogue box pop up with their face included. 

So for example I wanted the appearance to look like so: https://rpgmaker.net/media/content/games/3827/screenshots/OhCitrus.png

I did a little bit of researching and concluded to using:

 

//as the code appears in the passage//

<div class="message"
style="position: absolute; left: 10; top: 50; width: 650px; height: 100px"><img src="https://screenshots.firefoxusercontent.com/images/0b5d922c-e2a2-4527-814b-7bad2d9bd9c2.png" style="position: absolute; left: -250; top: -50; width: 100px; height: 100px"><blockquote><blockquote><blockquote><div class="typed-speed3-delay800">@@.white; Could you clean this up on your own? I'd rather get this done as soon as possible.@@  </div></blockquote></blockquote></blockquote>



//spaced out//

<div class="message"

style="position: absolute; left: 10; top: 50; width: 650px; height: 100px">

<img src="https://screenshots.firefoxusercontent.com/images/0b5d922c-e2a2-4527-814b-7bad2d9bd9c2.png" 

style="position: absolute; left: -250; top: -50; width: 100px; height: 100px">

<blockquote><blockquote><blockquote><div class="typed-speed3-delay800">@@.white; Could you clean this up on your own? I'd rather get this done as soon as possible.@@</div></blockquote></blockquote></blockquote>


The only HTML addition currently is both the type-writer macro and the dialogue box border. Link to the full HTML is shown in the next comment below.

commented 6 days ago by CyberCoder (130 points)
// dialog API macro set, by chapel; for sugarcube 2
// version 1.0
// see the documentation: https://github.com/ChapelR/custom-macros-for-sugarcube-2#dialog-api-macros

// <<dialog>> macro
Macro.add('dialog', {
	   tags : null,
	handler : function () {

		var content = this.payload[0].contents;
		
		if (this.args.length > 1) {
			var title = this.args[0];
			this.args.deleteAt(0);
			this.args.push('macro-' + this.name);
			var classNames = this.args.join(' ');
		} else if (this.args.length === 1) {
			var title = this.args[0];
			var classNames = 'macro-' + this.name;
		} else {
			var title = '';
			var classNames = 'macro-' + this.name;
		}
		
		Dialog.setup(title, classNames);
		Dialog.wiki(content);
		Dialog.open();
		
	}

});

// <<popup>> macro
Macro.add('popup', {
	handler : function () {
		
		if (this.args.length > 2) {
			var passageName = this.args[0];
			var title = this.args[1];
			this.args.deleteAt(0, 1);
			this.args.push('macro-' + this.name);
			var classNames = this.args.join(' ');
		} else if (this.args.length === 2) {
			var passageName = this.args[0];
			var title = this.args[1];
			var classNames = 'macro-' + this.name;
		} else if (this.args.length === 1) {
			var passageName = this.args[0];
			var title = '';
			var classNames = 'macro-' + this.name;
		} else {
			return this.error('need at least one argument; the passage to display');
		}
		
		Dialog.setup(title, classNames);
		Dialog.wiki(Story.get(passageName).processText());
		Dialog.open();
		
	}

});

/*! typed.js integration module for SugarCube */
!function(){"use strict";function getInlineOptions(classNames){var match,options={},typedRe=/^typed(?:-(\w+))+\b$/,parseRe=/-(speed|delay)(\d+)\b/g;if("typed"!==classNames){classNames=classNames.toLowerCase().split(/\s+/);for(var i=0;i<classNames.length;i++)if(typedRe.test(classNames[i])){for(;null!==(match=parseRe.exec(classNames[i]));)switch(match[1]){case"speed":options.typeSpeed=+match[2];break;case"delay":options.startDelay=+match[2]}break}}return options}function typedCallbackFactory(el,callback){return function(){var $outer=jQuery(el),$inner=jQuery('<div class="typedjs-text-wrapper" style="display:block;position:absolute;left:0;top:0;"><span class="typed"></span></div>'),$source=$outer.children('[class|="typed"]'),options=jQuery.extend({typeSpeed:40,startDelay:400},getInlineOptions($source.attr("class")),{strings:[$source.html()]});"function"==typeof callback&&(options.callback=callback),$outer.append($inner),$inner.children().typed(options)}}postrender.typedSetupHandler=function(content){jQuery('[class|="typed"]',content).addClass("typed").css("visibility","hidden").wrap('<div class="typedjs-outer-wrapper" style="display:block;position:relative;"></div>')},postdisplay.typedAnimationHandler=function(){for(var $elements=jQuery("#passages .typedjs-outer-wrapper"),callback=null,i=$elements.length-1;i>=0;--i)callback=typedCallbackFactory($elements[i],callback);"function"==typeof callback&&callback()}}();
/*! Typed.js | (c) 2014 Matt Boldt | MIT License */
!function(t){"use strict";var s=function(s,e){this.el=t(s),this.options=t.extend({},t.fn.typed.defaults,e),this.isInput=this.el.is("input"),this.attr=this.options.attr,this.showCursor=this.isInput?!1:this.options.showCursor,this.elContent=this.attr?this.el.attr(this.attr):this.el.text(),this.contentType=this.options.contentType,this.typeSpeed=this.options.typeSpeed,this.startDelay=this.options.startDelay,this.backSpeed=this.options.backSpeed,this.backDelay=this.options.backDelay,this.stringsElement=this.options.stringsElement,this.strings=this.options.strings,this.strPos=0,this.arrayPos=0,this.stopNum=0,this.loop=this.options.loop,this.loopCount=this.options.loopCount,this.curLoop=0,this.stop=!1,this.cursorChar=this.options.cursorChar,this.shuffle=this.options.shuffle,this.sequence=[],this.build()};s.prototype={constructor:s,init:function(){var t=this;t.timeout=setTimeout(function(){for(var s=0;s<t.strings.length;++s)t.sequence[s]=s;t.shuffle&&(t.sequence=t.shuffleArray(t.sequence)),t.typewrite(t.strings[t.sequence[t.arrayPos]],t.strPos)},t.startDelay)},build:function(){var s=this;if(this.showCursor===!0&&(this.cursor=t('<span class="typed-cursor">'+this.cursorChar+"</span>"),this.el.after(this.cursor)),this.stringsElement){s.strings=[],this.stringsElement.hide();var e=this.stringsElement.find("p");t.each(e,function(e,i){s.strings.push(t(i).html())})}this.init()},typewrite:function(t,s){if(this.stop!==!0){var e=Math.round(70*Math.random())+this.typeSpeed,i=this;i.timeout=setTimeout(function(){var e=0,r=t.substr(s);if("^"===r.charAt(0)){var o=1;/^\^\d+/.test(r)&&(r=/\d+/.exec(r)[0],o+=r.length,e=parseInt(r)),t=t.substring(0,s)+t.substring(s+o)}if("html"===i.contentType){var n=t.substr(s).charAt(0);if("<"===n||"&"===n){var a="",h="";for(h="<"===n?">":";";t.substr(s).charAt(0)!==h;)a+=t.substr(s).charAt(0),s++;s++,a+=h}}i.timeout=setTimeout(function(){if(s===t.length){if(i.options.onStringTyped(i.arrayPos),i.arrayPos===i.strings.length-1&&(i.options.callback(),i.curLoop++,i.loop===!1||i.curLoop===i.loopCount))return;i.timeout=setTimeout(function(){i.backspace(t,s)},i.backDelay)}else{0===s&&i.options.preStringTyped(i.arrayPos);var e=t.substr(0,s+1);i.attr?i.el.attr(i.attr,e):i.isInput?i.el.val(e):"html"===i.contentType?i.el.html(e):i.el.text(e),s++,i.typewrite(t,s)}},e)},e)}},backspace:function(t,s){if(this.stop!==!0){var e=Math.round(70*Math.random())+this.backSpeed,i=this;i.timeout=setTimeout(function(){if("html"===i.contentType&&">"===t.substr(s).charAt(0)){for(var e="";"<"!==t.substr(s).charAt(0);)e-=t.substr(s).charAt(0),s--;s--,e+="<"}var r=t.substr(0,s);i.attr?i.el.attr(i.attr,r):i.isInput?i.el.val(r):"html"===i.contentType?i.el.html(r):i.el.text(r),s>i.stopNum?(s--,i.backspace(t,s)):s<=i.stopNum&&(i.arrayPos++,i.arrayPos===i.strings.length?(i.arrayPos=0,i.shuffle&&(i.sequence=i.shuffleArray(i.sequence)),i.init()):i.typewrite(i.strings[i.sequence[i.arrayPos]],s))},e)}},shuffleArray:function(t){var s,e,i=t.length;if(i)for(;--i;)e=Math.floor(Math.random()*(i+1)),s=t[e],t[e]=t[i],t[i]=s;return t},reset:function(){var t=this;clearInterval(t.timeout);var s=this.el.attr("id");this.el.after('<span id="'+s+'"/>'),this.el.remove(),"undefined"!=typeof this.cursor&&this.cursor.remove(),t.options.resetCallback()}},t.fn.typed=function(e){return this.each(function(){var i=t(this),r=i.data("typed"),o="object"==typeof e&&e;r||i.data("typed",r=new s(this,o)),"string"==typeof e&&r[e]()})},t.fn.typed.defaults={strings:["These are the default values...","You know what you should do?","Use your own!","Have a great day!"],stringsElement:null,typeSpeed:0,startDelay:0,backSpeed:0,shuffle:!1,backDelay:500,loop:!1,loopCount:!1,showCursor:!0,cursorChar:"|",attr:null,contentType:"html",callback:function(){},preStringTyped:function(){},onStringTyped:function(){},resetCallback:function(){}}}(window.jQuery);

 


CSS in the next comment.
 

commented 6 days ago by CyberCoder (130 points)


 





div.message {
	border-style: solid;
	border-width: 3px;
	border-radius: 1em;
	padding: 10px;
} 

.john {
	color:#5c9cff;
}

.jane {
	color: blue;
}


.typed, .typed-cursor {
	font-family: monospace, monospace;
	color: white;
}

/* Typed.js animated cursor styling. */
.typed-cursor {
	opacity: 1;
	-webkit-animation: blink 0.7s infinite;
	-moz-animation: blink 0.7s infinite;
	animation: blink 0.7s infinite;
}
@keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 0; }
	100% { opacity: 1; }
}
@-webkit-keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 0; }
	100% { opacity: 1; }
}
@-moz-keyframes blink {
	0% { opacity: 1; }
	50% { opacity: 0; }
	100% { opacity: 1; }
}






 

 

 

I think with what I have right now is nice, and it works considerably well. However it isn't exactly what I wanted, because I couldn't quite figure out how to input a proper slot for the character name, and include a smooth character image positioning. 

Hope this cleared it up!

commented 6 days ago by CyberCoder (130 points)
With the whole list of HTML and CSS used, it should appear like this in the passage.

https://puu.sh/ykdhq/9c94dc9279.png

(In case you just want the visuals)
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...