Google Maps custom popup

by PhilQ

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="maps-popup">
	<div class="bg"></div>
	<button></button>
	<div class="content">Test<br/>weskfsdjfdsjfdsfgskj</div>
</div>

<div class="target">Hoi!</div>

SCSS

body {
	background-color: #eee;
}

*, *::before, *::after {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

.target {
	width: 500px;
	height: 300px;
	display: inline-block;
	background: blue;
	position: absolute;
	top: 200px;
	left: 200px;
	margin-top: 50px;
}

.maps-popup {
	position: absolute;
	display: inline-block;
	padding: 15px;
	color: #000;
	background-color: #fff;
	border-radius: 8px;

	.bg {
		z-index: -1;
		position: absolute;
		top: 0px;
		left: 0px;
		display: inline-block;
		width: 100%;
		height: 100%;
		background-color: transparent;
		border-radius: 8px;
		box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.3);
	}

	&::before, &::after {
		content: '';
		display: inline-block;
		z-index: 0;
		position: absolute;
		border-color: transparent;
		border-style: solid;
		border-width: 8px;
	}

	&::after {
		z-index: -1;
		filter: blur(1px);
		opacity: 0.3;
	}


	&.top, &.bottom {
		&::before, &::after {
			left: 50%;
			margin-left: -8px;
		}
	}

	&.top, &.top-left, &.top-right {
		margin-top: -8px;

		&::before {
			top: 100%;
			border-top: 8px solid #fff;
			border-bottom: 0px;
		}

		&::after {
			top: 100%;
			border-top: 8px solid #000;
			border-bottom: 0px;
		}
	}

	&.bottom, &.bottom-left, &.bottom-right {
		margin-top: 8px;

		&::before {
			bottom: 100%;
			border-bottom: 8px solid #fff;
			border-top: 0px;
		}

		&::after {
			bottom: 100%;
			border-bottom: 8px solid #000;
			border-top: 0px;
		}
	}

	&.top-left, &.bottom-left {
		margin-left: 16px;

		&::before, &::after {
			right: 8px;
		}
	}

	&.top-right, &.bottom-right {
		margin-left: -16px;

		&::before, &::after {
			left: 8px;
		}
	}


	&.left, &.right {
		&::before, &::after {
			top: 50%;
			margin-top: -8px;
		}
	}

	&.left, &.left-top, &.left-bottom {
		margin-left: -8px;

		&::before {
			left: 100%;
			border-left: 8px solid #fff;
			border-right: 0px;
		}

		&::after {
			left: 100%;
			border-left: 8px solid #000;
			border-right: 0px;
		}
	}

	&.right, &.right-top,...

JavaScript

$(document).ready(function(){

	var places = [
		'top-left','top','top-right',
		'left-top','left','left-bottom',
		'right-top','right','right-bottom',
		'bottom-left','bottom','bottom-right',
	];

	var $target = $('.target');
	var targetPosition = $target.offset();
	var targetW = $target.outerWidth();
	var targetH = $target.outerHeight();
	console.log(targetPosition, targetW, targetH);

	var w = $('.maps-popup').outerWidth();
	var h = $('.maps-popup').outerHeight();
	var $tpl = $('.maps-popup').clone();
	$('.maps-popup').remove();
	console.log(w, h);

	for (var i = 0; i < places.length; i++) {
		var x = 0;
		var y = 0;
		if (places[i].match(/^top/g)) {
			y = targetPosition.top - h;
		} else if (places[i].match(/^bottom/g)) {
			y = targetPosition.top + targetH;
		} else {
			y = targetPosition.top + 0.5 * (targetH - h);
		}
		if (places[i].match(/^left/g)) {
			x = targetPosition.left - w;
		} else if (places[i].match(/^right/g)) {
			x = targetPosition.left + targetW;
		} else {
			x = targetPosition.left + 0.5 * (targetW - w);
		}
		if (places[i].match(/-left$/g)) {
			x -= 0.5 * w;
		}
		if (places[i].match(/-right$/g)) {
			x += 0.5 * w;
		}
		if (places[i].match(/-top$/g)) {
			y -= 0.5 * h;
		}
		if (places[i].match(/-bottom$/g)) {
			y += 0.5 * h;
		}
		console.log(places[i], x, y);
		$('body').append(
			$tpl.clone()
			.addClass( places[i] )
			.css({
				top: Math.round(y) + 'px',
				left: Math.round(x) + 'px',
			})
			//.find('.content').html( places[i] ).end()
		);
	//return;
	}

});