<div class="tinder">
	<div class="tinder--status">
		<i class="fa fa-arrow-right"></i>
		<i class="fa fa-info"></i>
		<i class="fa fa-arrow-left"></i>
	</div>

	<div class="tinder--cards">
		<div class="tinder--card cover">
			<img class="limitImg" src="https://assets.codepen.io/652/shania-pinnata-7E-vKgzahd8-unsplash.jpg" alt="spaghetti with pesto sauce and cherry tomatoes." title="Photo by Shania Pinnata">
			<h3>Pasta with Pesto and Tomatoes</h3>
			<div class="deets">
				<div class="servings">
					<i class="fbr fas fa-utensils"></i> <i class="fas fa-user"></i> <i class="fas fa-user"></i> <i class="fas fa-user"></i> <i class="fas fa-user"></i> <i class="fbr fas fa-utensils"></i>
				</div>
				<br />
				<div class="cookTime">
					<i class="fbr fas fa-hourglass-half"></i> 25 min <i class="fbr fas fa-hourglass-half"></i>
				</div>
			</div>
		</div>
		<div class="tinder--card about">
			<h2>About</h2>
			<p class="whyCook">This quick and delicious pasta dish is the perfect way to use up a summer bounty of basil and tomatoes!</p>
			<br />
			<br />
			<img class="tomatos" src="https://assets.codepen.io/652/tamanna-rumee-nswz6tIpgZk-unsplash.jpg" alt="tomato halves surrounded by basil leaves and peppercorns." title="Photo by Tamanna Rume">
			<p class="whyCook">Don't have a green thumb? Never fear! You can knock out this classic pasta dish in no time with a jar of prepared pesto sauce.</p>
		</div>

		<div class="tinder--card ingredients">
			<h2>Ingredients</h2>
			<ul class="fa-ul ingredients">
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>8 oz. spaghetti or linguine pasta</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>2 cups fresh basil leaves, plus 4-8 reserved leaves for garnish</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>2 cloves garlic</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>2 tbsp. pine nuts or blanched almonds</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>1/2 cup olive oil</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>1/2 cup grated Parmesan cheese, plus 2 tbsp. for garnish.</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>1/8 tsp salt</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>1 pint cherry tomatoes</li>
				<li><span class="fa-li"><i class="fas fa-seedling"></i></span>1 tsp olive oil</li>
			</ul>
			<br />
			<div class="variation">
				Variation: Got no time, or no fresh basil? Use a 6 ounce jar of prepared pesto instead.
				<!-- 				<br />
				<i class="ingInfo fas fa-info-circle fa-spin"></i>
				<br />
				<i class="ingInfoArr fas fa-arrow-down"></i> -->
			</div>
		</div>

		<div class="tinder--card process">
			<h2>Process</h2>
			<ul class="fa-ul process">
				<li><span class="fa-li"><i class="fas fa-thermometer-three-quarters"></i></span>Bring 4 quarts of water to a rolling boil in a large pot. Salt the water generously and add the pasta.</li>
				<li><span class="fa-li"><i class="fas fa-clock"></i></span>While the pasta cooks, make the pesto. <i class="white fas fa-info-circle fa-spin"></i></li>
				<li><span class="fa-li"><i class="fas fa-thermometer-quarter"></i></span>Heat a large skillet over medium heat.</li>
				<li><span class="fa-li"><i class="fas fa-plus"></i></span>Add the 1/2 tsp. olive oil to the heated skillet.</li>
				<li><span class="fa-li"><i class="fas fa-plus"></i></span>Add the cherry tomatoes to the skillet and let them blister, stirring occasionally and gently so they don't burst.</li>
				<li><span class="fa-li"><i class="fas fa-minus"></i></span>Remove tomatoes from the pan and set aside.</li>
				<li><span class="fa-li"><i class="fas fa-tint"></i></span>Drain the pasta, reserving 1/4 cup of the cooking water.</li>
				<li><span class="fa-li"><i class="fas fa-undo-alt"></i></span>Return the pasta to the pot</li>
				<li><span class="fa-li"><i class="fas fa-plus"></i></span>Add the reserved cooking water and pesto to the pasta and stir to mix</li>
				<li><span class="fa-li"><i class="fas fa-circle"></i></span>Plate the pasta and add 6-8 tomatoes to each plate</li>
				<li><span class="fa-li"><i class="fas fa-leaf"></i></span>Garnish with reserved basil leaves and Parmesean and serve. Buon Appetito!</li>
			</ul>
		</div>

	</div>

	<div class="tinder--buttons">
		<button id="nope"><i class="fa fa-arrow-left"></i></button>
		<button id="info" title="How to make Pesto!"><i class="fa fa-info"></i></button>
		<button id="love"><i class="fa fa-arrow-right"></i></button>
	</div>

	<div class="tinder--info">
		<div class="bg">
			<i class="infoIcon fas fa-info-circle"></i>
			<h2>Make Pesto</h2>
		</div>

		<br />
		<ul class="fa-ul info">
			<li><span class="fa-li"><i class="fas fa-minus"></i></span>Remove stems from basil leaves.</li>
			<li><span class="fa-li"><i class="fas fa-blender"></i></span>Put the basil, garlic, and pine nuts or almonds into the bowl of a food processor and pulse it a few times to chop them up.</li>
			<li><span class="fa-li"><i class="fas fa-blender"></i></span>Then, turn the food processor on and <b>slowly</b> pour the olive oil through the feeder tube to blend with the chopped herbs and nuts.</li>
			<li><span class="fa-li"><i class="fas fa-plus"></i></span>Process until all ingredients are fully blended, stopping the food processor to scrape down the sides occasionally to get it all mixed.</li>
			<li><span class="fa-li"><i class="fas fa-power-off"></i></span>Turn off the food processor, and add the salt and Parmesean, then pulse a few times to blend.</li>
		</ul>
		<button class="closeMe">
			<i class="fas fa-times"></i>
		</button>
		<div class="covering"></div>
	</div>

</div>

<div class="promptBox">
	<div class="tapperoo"></div>
	<svg version="1.1" id="tap-gesture" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="140.2 0 293.8 500" enable-background="new 140.2 0 293.8 500" xml:space="preserve">
		<g>
			<path class="hand" fill="rgba(0,0,0,0.8)" d="M173.2,170.2l1.8,86.2c-3.3,1.8-8.3,5.1-14.7,10.9c-22.1,20-29.3,68.7-4.3,106.3
		c27.8,41.9,60.4,59.8,109,59.8c51.5,0,68.7-25.8,81.9-52.3c12.7-25.5,12.9-122.9,12.9-127.1c0-13-12.3-24.5-26.4-24.5
		c-1.7,0-5.9,0.6-10.2,1.9c-1.1-14.7-13.4-26.4-28.5-26.4c-6.8,0-13,2.4-17.9,6.3c-3.6-11-13.2-18.5-25-18.5
		c-7.8,0-14.8,3.2-19.8,8.5l-1.3-35.1l-0.6-15.9l-0.9-24.8c0-17.4-12.3-30.6-28.6-30.6S172,108,172,125.6l0.6,29.7L173.2,170.2z" />
		</g>
	</svg>
</div>
*,
*:before,
*:after {
	box-sizing: border-box;
	padding: 0;
	margin: 0;
}

body {
	background: #ccfbfe;
	overflow: hidden;
	font-family: sans-serif;
}
h1,
h2,
h3 {
	text-align: center;
	pointer-events: none;
}
h2 {
	margin-top: 2px;
	pointer-events: none;
}
.tinder {
	width: 100vw;
	height: 100vh;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	position: relative;
	opacity: 0;
	transition: opacity 0.1s ease-in-out;
}

.loaded.tinder {
	opacity: 1;
}

.tinder--status {
	position: absolute;
	top: 50%;
	margin-top: -30px;
	z-index: 2;
	width: 100%;
	text-align: center;
	pointer-events: none;
}

.tinder--status i {
	font-size: 100px;
	opacity: 0;
	transform: scale(0.3);
	transition: all 0.2s ease-in-out;
	position: absolute;
	width: 100px;
	margin-left: -50px;
}

.tinder_love .fa-arrow-right {
	opacity: 0.7;
	transform: scale(1);
}

.tinder_nope .fa-arrow-left {
	opacity: 0.7;
	transform: scale(1);
}

.tinder--cards {
	flex-grow: 1;
	padding-top: 40px;
	display: flex;
	justify-content: center;
	align-items: flex-end;
	z-index: 1;
}

.tinder--card {
	display: inline-block;
	width: 90vw;
	max-width: 380px;
	height: 65vh;
	padding-bottom: 30px;
	border-radius: 8px;
	overflow: hidden;
	position: absolute;
	will-change: transform;
	transition: all 0.3s ease-in-out;
	cursor: -webkit-grab;
	cursor: -moz-grab;
	cursor: grab;
	overflow-y: auto;
}

.moving.tinder--card {
	transition: none;
	cursor: -webkit-grabbing;
	cursor: -moz-grabbing;
	cursor: grabbing;
}

.tinder--card > .limitImg {
	max-width: 100%;
	height: 60%;
	width: 380px;
	object-fit: cover;
	pointer-events: none;
}
.tinder--card.cover {
	background: rgb(211, 150, 97);
}
.tinder--card.about {
	background-image: linear-gradient(
		to right,
		#f5f5f5,
		#f5f5f5,
		#f5f5f5,
		rgb(233, 235, 234),
		rgb(233, 235, 234)
	);
	background-color: #f5f5f5;
}
.tinder--card.ingredients {
	background: lightblue;
}
.tinder--card.process {
	background: lightpink;
}
.tinder--card img {
	max-width: 100%;
	pointer-events: none;
}

.tinder--card h3 {
	margin-top: 5%;
	font-size: 32px;
	padding: 0 16px;
	pointer-events: none;
}

.tinder--card p,
.tinder--card ul {
	pointer-events: none;
	padding: 10px;
}

.tinder--buttons {
	flex: 0 0 100px;
	text-align: center;
	padding-top: 20px;
	cursor: pointer;
}

.tinder--buttons button {
	border-radius: 50%;
	line-height: 60px;
	width: 60px;
	border: 0;
	background: #ffffff;
	display: inline-block;
	margin: 0 8px;
	cursor: pointer;
}

.tinder--buttons button:focus {
	outline: 0;
}

.tinder--buttons button:hover {
	opacity: 0.7;
}

.tinder--buttons i {
	font-size: 32px;
	vertical-align: middle;
}

.fa-arrow-left,
.fa-arrow-right {
	color: #cdd6dd;
}

.photoBy {
	position: relative;
	bottom: 0%;
	left: 50%;
	transform: translate(-50%);
	color: lightgrey;
	padding: 5px;
	font-size: 0.7em;
	text-align: center;
}
.recipe_details {
	background: #f5f5f5;
}
.fa-ul.ingredients {
	margin-top: 10px;
}
.fa-ul.ingredients > li {
	padding: 8px;
}
.variation {
	padding: 15px;
	margin-left: 25px;
	margin-right: 25px;
	border-top: 2px dashed lightyellow;
	pointer-events: none;
}
.fbr {
	color: firebrick;
}
i.fbr {
	display: inline-block;
	border-radius: 60px;
	box-shadow: 0px 0px 0px 2px firebrick;
	padding: 0.2em 0.3em;
}
.fa-ul .cover {
	display: inline-block;
	margin-top: 15px;
	font-size: 1.5em;
}
.deets {
	margin-top: 25px;
	font-size: 1.3em;
	text-align: center;
}
.ingInfo {
	position: relative;
	left: calc(50% - 0.5em);
	transform: translate(-50%);
	margin-top: 20px;
	color: lightyellow;
	font-size: 2em;
}
.ingInfoArr {
	position: relative;
	left: 50%;
	transform: translate(-50%);
	margin-top: 7px;
	color: lightyellow;
	font-size: 1em;
}
ul.process,
ul.info {
	margin-top: 10px;
}
ul.process > li,
ul.info > li {
	padding-top: 10px;
}
ul.info {
	top: 50%;
	z-index: 5;
}
.white {
	color: white;
}
.whyCook {
	margin-left: 25px;
	margin-right: 25px;
	margin-top: 25px;
}
.tinder--info {
	position: absolute;
	top: 200vh;
	left: 50%;
	transform: translate(-50%, -50%);
	z-index: 10;
	width: 90vw;
	max-width: 380px;
	padding-top: 20px;
	padding-bottom: 40px;
	padding-left: 20px;
	padding-right: 20px;
	transition: 500ms;
}
.infoIcon {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	font-size: 20em;
	color: rgba(255, 255, 255, 0.2);
	z-index: 7;
}
.tinder--info > .covering {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	height: 100vh;
	width: 100vw;
	background: rgba(255, 255, 255, 0.5);
	z-index: -5;
}
.tinder--info > .bg {
	position: absolute;
	top: 50%;
	left: 50%;
	height: 100%;
	width: 100%;
	transform: translate(-50%, -50%);
	border-radius: 5px;
	background-color: lightgreen;
}
.closeMe {
	position: absolute;
	top: -8px;
	right: -8px;
	font-size: 2em;
	border-radius: 50%;
	width: 1.15em;
	background-color: #000;
	color: white;
	border: none;
	cursor: pointer;
}
.tomatos {
	max-height: 180px;
	position: relative;
	left: 50%;
	transform: translate(-50%);
}
.servings,
.cookTime {
	color: midnightblue;
}
/* width */
::-webkit-scrollbar {
	width: 10px;
}

/* Track */
::-webkit-scrollbar-track {
	box-shadow: inset 0 0 3px grey;
	border-radius: 10px;
}

/* Handle */
::-webkit-scrollbar-thumb {
	background: lightyellow;
	border-radius: 10px;
}

/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
	background: lightgoldenrodyellow;
}

.promptBox {
	height: 100px;
	width: 100px;
	transform: translate(-50%, -50%);
	position: absolute;
	top: 50%;
	left: 55%;
	opacity: 1;
	transition: 300ms;
	pointer-events: none;
	z-index: 1000;
}
.tapperoo {
	height: 25%;
	width: 25%;
	position: absolute;
	top: 20%;
	left: 33%;
	border-radius: 100px;
	background-color: #0095dd;
	z-index: -1;
	animation: tapperoo 3s infinite;
}
@keyframes tapperoo {
	0% {
		height: 25%;
		width: 25%;
	}
	50% {
		height: 5%;
		width: 35%;
		opacity: 0;
		transform: translate(-250%);
	}
	100% {
		opacity: 0;
	}
}

#tap-gesture {
	position: absolute;
	transform: rotate(30deg);
	animation: handMove 3s infinite;
}
@keyframes handMove {
	0% {
		transform: rotate(30deg);
	}
	50% {
		transform: translate(-60%, -10%) rotate(-30deg) scale(0.9);
	}
	100% {
		transform: rotate(30deg);
	}
}
"use strict";

//Random Number generator
function randomNumber(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

let tinderContainer = document.querySelector(".tinder");
let allCards = document.querySelectorAll(".tinder--card");
let currentCard;
const nope = document.getElementById("nope");
const love = document.getElementById("love");
let num = 5;

//create cards for page
function initCards(card, index) {
	//the cards that haven't been removed
	var newCards = document.querySelectorAll(".tinder--card:not(.removed)");

	newCards.forEach(function (card, index) {
		//put the card in front
		card.style.zIndex = allCards.length - index;
		//angle the card and make it smaller the further back it goes
		card.style.transform =
			"scale(" + (20 - index) / 20 + ") translateY(-" + 50 * index + "px)";
		//change how opaque it is depending where it is in the stack (index 0 is fully opaque). uses 5 so that anything loaded after 5 is fully transparent
		// card.style.opacity = (5 - index) / 5;
	});

	//give the ones that get initialized a "loaded" class
	tinderContainer.classList.add("loaded");
}

//run initialization
initCards();

function nodeToString(node) {
	var tmpNode = document.createElement("div");
	tmpNode.appendChild(node.cloneNode(true));
	var str = tmpNode.innerHTML;
	tmpNode = node = null; // prevent memory leaks in IE
	return str;
}

function cleanCurrentCard(thisCard) {
	let cleanedCard = nodeToString(thisCard)
		.replace(/(\r\n|\n|\r)/gm, "")
		.replace(" removed", "");
	return cleanedCard;
}

function removeRemoveClass() {
	var element = document.querySelector(".tinder--card");
	element.classList.remove("removed");
}

//my custom function
function addNewCard(thisCard) {
	console.log(thisCard);
	let cleanedCard = cleanCurrentCard(thisCard);

	//increment the number to be given to the card
	num++;

	//card area
	var allCardsArea = document.querySelector(".tinder--cards");

	//add a card to the end of the innerHTML
	setTimeout(function () {
		allCardsArea.innerHTML += cleanedCard;
		//remove the .removed ones
		const paras = document.getElementsByClassName("removed");
		while (paras[0]) {
			paras[0].parentNode.removeChild(paras[0]);
		}
		// removeRemoveClass();
	}, 300);

	//try to get newest card at back to fade in
	//ooor just add so many that the last one is completely transparent since the opacity changes by .10 each card

	//run these two after a delay that is slightly longer than the delay for adding the new card
	//this makes a new card at the back and then transitions it smoothly to the smaller size
	setTimeout(initCards, 301);
	setTimeout(addHammers, 301);
}

function addHammers() {
	//redefined to be able to reinitialize on new card add
	allCards = document.querySelectorAll(".tinder--card");

	allCards.forEach(function (el) {
		//initialize hammer on each card
		var hammertime = new Hammer(el);

		//add the moving class if the card is being panned
		hammertime.on("pan", function (event) {
			el.classList.add("moving");
		});

		//don't do anything if the movement hasn't changed
		hammertime.on("pan", function (event) {
			if (event.deltaX === 0) return;
			if (event.center.x === 0 && event.center.y === 0) return;

			//if it has been changed at all to the right, add the 'tinder-love' class
			tinderContainer.classList.toggle("tinder_love", event.deltaX > 0);
			//if it has been changed at all to the left, add the 'tinder-nope' class
			tinderContainer.classList.toggle("tinder_nope", event.deltaX < 0);

			//angle the further it goes right or left
			var xMulti = event.deltaX * 0.03;
			//angle the further it goes up or down
			var yMulti = event.deltaY / 80;

			//rotation is a combo of both
			var rotate = xMulti * yMulti;

			//apply the movement and rotation
			event.target.style.transform =
				"translate(" +
				event.deltaX +
				"px, " +
				event.deltaY +
				"px) rotate(" +
				rotate +
				"deg)";
		});

		//when you're done with the panning event
		hammertime.on("panend", function (event) {
			//remove the 'moving' class from the card
			el.classList.remove("moving");
			//remove the love and nope classes from the rest of the cards just in case something happened where they stayed
			tinderContainer.classList.remove("tinder_love");
			tinderContainer.classList.remove("tinder_nope");

			//set var for width of the body (including padding)
			var moveOutWidth = document.body.clientWidth;

			//determine if the card should be kept on screen. (Gotta be changed by a certain amount and be moving)
			var keep = Math.abs(event.deltaX) < 80 || Math.abs(event.velocityX) < 0.5;

			//toggle the removed class if the keep var has not evaluated to true
			event.target.classList.toggle("removed", !keep);

			//if the keep value evaluates true, set transform to nothing
			if (keep) {
				event.target.style.transform = "";
			} else {
				//if it's not being kept onscreen, move it on out
				//calculate all of the movements and whatnot
				var endX = Math.max(Math.abs(event.velocityX) * moveOutWidth, moveOutWidth);
				var toX = event.deltaX > 0 ? endX : -endX;
				var endY = Math.abs(event.velocityY) * moveOutWidth;
				var toY = event.deltaY > 0 ? endY : -endY;
				var xMulti = event.deltaX * 0.03;
				var yMulti = event.deltaY / 80;
				var rotate = xMulti * yMulti;

				event.target.style.transform =
					"translate(" +
					toX +
					"px, " +
					(toY + event.deltaY) +
					"px) rotate(" +
					rotate +
					"deg)";

				//add the card to the back
				addNewCard(event.target);
			}
		});
	});
}

//run the addHammers to allow card movement
addHammers();

//function for the love and hate buttons
function createButtonListener(love) {
	return function (event) {
		//if the card is not given the removed class
		var cards = document.querySelectorAll(".tinder--card:not(.removed)");

		//the body width (including padding) multiplied by 1.5
		var moveOutWidth = document.body.clientWidth * 1.5;

		//if there are no more cards, do nothing
		// if (!cards.length) return false;

		//only operate on the current card
		var card = cards[0];

		//add the removed class to the current card
		card.classList.add("removed");

		//if love (true) has been passed in,
		if (love) {
			//move the card right and rotate it
			card.style.transform =
				"translate(" + moveOutWidth + "px, -100px) rotate(-30deg)";
			//if nope (false) has been passed in,
		} else {
			//move the card left and rotate it
			card.style.transform =
				"translate(-" + moveOutWidth + "px, -100px) rotate(30deg)";
		}

		//intitialize cards again to determine the top card (and add a new one)
		addNewCard(card);

		//prevent the default action from happening for the button
		event.preventDefault();
	};
}

//create love and nope button listeners
var nopeListener = createButtonListener(false);
var loveListener = createButtonListener(true);

//add click events to love and nope buttons
nope.addEventListener("click", nopeListener);
love.addEventListener("click", loveListener);

document.querySelector(".closeMe").addEventListener("click", function () {
	toggleInfoClose(true);
});
document.querySelector(".covering").addEventListener("click", function () {
	toggleInfoClose(true);
});
document.querySelector("#info").addEventListener("click", function () {
	toggleInfoClose(false);
});

function toggleInfoClose(bool) {
	if (!bool) {
		document.querySelector(".tinder--info").style.top = "50%";
	} else {
		document.querySelector(".tinder--info").style.top = "200vh";
	}
}

//stuff to prompt the user to swipe
//Shows the animation if your mouse is still for 15 seconds/hides it when you move
let fadein = null;

const myFunction = (fadeOutTime, fadeInAfterTime) => {
	document.querySelector(".promptBox").style.transition = fadeOutTime + "ms";
	document.querySelector(".promptBox").style.opacity = "0";
	if (fadein != null) {
		clearTimeout(fadein);
	}
	fadein = setTimeout(showMe, fadeInAfterTime);
};

const showMe = () => {
	document.querySelector(".promptBox").style.opacity = "1";
};

document.querySelector("body").addEventListener("mousemove", function () {
	myFunction(300, 15000);
});
document.querySelector("body").addEventListener("click", function () {
	myFunction(300, 15000);
});
document.querySelector("body").addEventListener("touchstart", function () {
	myFunction(300, 15000);
});
document.querySelector("body").addEventListener("touchmove", function () {
	myFunction(300, 15000);
});

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css

External JavaScript

  1. https://hammerjs.github.io/dist/hammer.min.js