CUSTOM SPECIAL: CHAT-DIALOG

A dialog with some options and animated typewriting, that can fit at the bottom of the chat or overlay the screen

SCRIPT


$quiz.on('trigger-chat-dialog',p=>{
	// chat-dialog $text:string
	// chat-dialog $duration:int:0:30
	// chat-dialog $delay:int:1:1000
	// chat-dialog $overlay:bool
	// chat-dialog $class:string
	if($scope.dialog && $scope.dialog.t) clearTimeout($scope.dialog.t);
	p.text = p.text.split("\\n").join("\n");
	p.mount = e=>{
		p.e=e;
		$(p.overlay ? 'body' : 'chat').append(e);
		animate(e.find('div'),p.text,p.delay||1);
		$timeout(t=>$chat.scrollToBottom());
	};
	if($scope.dialog) p.mount($scope.dialog.e);
	$scope.dialog = p;
	if(p.duration){
		p.t = $timeout(()=>{
			$scope.dialog=p.t=0;
			p.e.detach();
		},p.duration*1000);
	}
});
function animate(e,t,d){
	var s = '<span>';
	var L = t.length;
	t.split(' ').forEach(w=>{
		s+='<b class="q-word">';		
		for(var i=0;i<w.length;i++){
			var c = w.charAt(i);
			if(c=='"') c = '"';
			if(c=='-') s+='<b class="q-c q-dash">_</b>';
			else if(c=='\n') s+='<br class="q-c">';
			else s+='<b class="q-c">'+c+'</b>';
		}
		s+='</b><b> </b>';
	});
	s+='</span>';
	e.html(s);
	e = e.find('span');
	var ja = e.find('.q-c');
	var k=0;
	ja.each((i,b)=>{
		if(b.tagName=='BR') k+=d*5/1000;
		b.style.opacity=0;
		TweenMax.to(b,0.3,{alpha:1,delay:k});
		k+=d*1/1000;
	});
}
			

TEMPLATE


<line class="chat-dialog {{dialog.class}}" ng-if="dialog" mount="dialog" ng-class="{overlay:dialog.overlay}">
    <div class="chat-sticky"></div>
</line>
			

CSS


line.chat-dialog.red {
	color:red;
}
line.chat-dialog.overlay {
	position:absolute;
	top:100px;
	left:120px;
	width:calc(100% - 290px);
	height:calc(100% - 100px);
	pointer-events:none;
	filter: drop-shadow(0px 0px 1px black) drop-shadow(0px 0px 1px black);
}
line.chat-dialog {
	padding:5px;
	border-radius:10px;
	background:rgba(0,0,0,0);
	color:white;
	font-weight:bold;
	font-size:80px;
	overflow: hidden;
	transition:max-height .5s linear;
}
line.chat-dialog div {
	white-space:pre-line;
	text-align:center;
}