The finished version of this guide: https://canjs.com/doc/guides/recipes/tinder-carousel.html
- on GistRun
- on CodePen by Chasen Le Hara
All Code Pens by Frank Lemanschik
The finished version of this guide: https://canjs.com/doc/guides/recipes/tinder-carousel.html
All Code Pens by Frank Lemanschik
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="description" content="CanES 5 Tinder-Like Carousel"> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>CanES 5 Tinder-Like Carousel</title> | |
<link href="https://fonts.googleapis.com/css?family=Dosis:300,400" rel="stylesheet"> | |
<link href="style.css" rel="stylesheet"> | |
</head> | |
<body> | |
<!-- Script.JS is https://gist.github.com/frank-dspeed/32e6de3646c733c3099e72141c9ecd0a --> | |
<script type="module"> /* Here Goes the JS from the script.mjs */ | |
/* needed because not all platforms that display gists are supporting .mjs */ | |
fetch('./script.mjs') | |
.then(function(response) { | |
return response.text(); | |
}) | |
.then(function(myJson) { | |
var script = document.createElement("script"); | |
script.innerHTML = myJson; | |
script.setAttribute("type", "module") | |
document.head.appendChild(script); | |
}); | |
</script> | |
<evil-tinder></evil-tinder> | |
</body> | |
</html> |
import { Component } from "//unpkg.com/canes@5/dist/can-component.mjs"; | |
Component.extend({ | |
tag: "evil-tinder", | |
view: ` | |
<div class="header"></div> | |
<div class="result {{#if(liking)}}liking{{/if}} | |
{{#if(noping)}}noping{{/if}}"></div> | |
<div class="images"> | |
<div class="current" style="left: {{howFarWeHaveMoved}}px"> | |
<img src="{{currentProfile.img}}" | |
draggable="false" | |
touch-action="none"/> | |
</div> | |
<div class="next"> | |
<img src="{{nextProfile.img}}"/> | |
</div> | |
</div> | |
<div class="footer"> | |
<button class="dissBtn" | |
on:click="nope()">Dislike</button> | |
<button class="likeBtn" | |
on:click="like()">Like</button> | |
</div> | |
`, | |
ViewModel: { | |
profiles: { | |
default() { | |
return [{img: "https://user-images.githubusercontent.com/78602/40454685-5cab196e-5eaf-11e8-87ac-4af6792994ed.jpg", name: "gru"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454705-6bf4d3d8-5eaf-11e8-9562-2bd178485527.jpg", name: "hannibal"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454830-e71178dc-5eaf-11e8-80ee-efd64911e35f.png", name: "joker"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454681-59cffdb8-5eaf-11e8-94ac-4849ab08d90c.jpg", name: "darth"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454709-6fecc536-5eaf-11e8-9eb5-3da39730adc4.jpg", name: "norman"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454711-72b19d78-5eaf-11e8-9732-80155ff8bb52.jpg", name: "stapuft"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454672-566b4984-5eaf-11e8-808d-cb5afd445e89.jpg", name: "dalek"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454720-7c3d984c-5eaf-11e8-9fa7-f68ddd33e3f0.jpg", name: "wickedwitch"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454722-802ef694-5eaf-11e8-8964-ca648368720d.jpg", name: "zod"}, | |
{img: "https://user-images.githubusercontent.com/78602/40454716-76bef438-5eaf-11e8-9d29-5002260e96e1.jpg", name: "venom"}]; | |
} | |
}, | |
howFarWeHaveMoved: "number", | |
emptyProfile: { | |
default() { | |
return {img: "https://stickwix.com/wp-content/uploads/2016/12/Stop-Sign-NH.jpg"}; | |
} | |
}, | |
get currentProfile() { | |
return this.profiles.get(0) || this.emptyProfile; | |
}, | |
get nextProfile() { | |
return this.profiles.get(1) || this.emptyProfile; | |
}, | |
get liking() { | |
return this.howFarWeHaveMoved >= 100; | |
}, | |
get noping() { | |
return this.howFarWeHaveMoved <= -100; | |
}, | |
like() { | |
console.log("LIKED"); | |
this.profiles.shift(); | |
}, | |
nope() { | |
console.log("NOPED"); | |
this.profiles.shift(); | |
}, | |
connectedCallback(el) { | |
var current = el.querySelector(".current"); | |
var startingX; | |
this.listenTo(current, "pointerdown", (event) => { | |
startingX = event.clientX; | |
this.listenTo(document, "pointermove", (event) => { | |
this.howFarWeHaveMoved = event.clientX - startingX; | |
}); | |
this.listenTo(document, "pointerup", (event) => { | |
this.howFarWeHaveMoved = event.clientX - startingX; | |
if (this.liking) { | |
this.like() | |
} else if (this.noping) { | |
this.nope(); | |
} | |
this.howFarWeHaveMoved = 0; | |
this.stopListening(document); | |
}); | |
}); | |
} | |
} | |
}); |
@import 'https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css'; | |
@import url('https://fonts.googleapis.com/css?family=Montserrat'); | |
html { | |
overflow: hidden; | |
height: 100vh; | |
width: 100vw; | |
} | |
body { | |
overflow: hidden; | |
height: 100vh; | |
width: 100vw; | |
position: relative; | |
} | |
button:focus {outline:0;} | |
/* EVIL TINDER COMPONENT */ | |
evil-tinder { | |
display: flex; | |
justify-content: flex-start; | |
height: 100vh; | |
flex-direction: column; | |
font-family: 'Montserrat', sans-serif; | |
} | |
.header { | |
flex-shrink: 0; | |
height: 80px; | |
background: url('https://canjs.com/docs/can-guides/commitment/recipes/tinder-like-carousel/img/evil-tinder-logo.svg') no-repeat center; | |
background-size: auto 55%; | |
border-bottom: 1px dotted lightgray; | |
} | |
.images { | |
position: relative; | |
flex-grow: 1; | |
flex-shrink: 1; | |
display: flex; | |
} | |
.footer { | |
flex-shrink: 0; | |
margin: 25px 0 30px; | |
display: flex; | |
justify-content: center; | |
align-self: center; | |
height: 100px; | |
width: 100%; | |
background: #f7f7f7; | |
z-index: 9999; | |
} | |
.current, .next { | |
top: 0px; | |
z-index: 100; | |
} | |
.current { | |
position: absolute; | |
display: flex; | |
top: 0px; | |
bottom: 0px; | |
} | |
.next { | |
z-index: 99; | |
margin-top: 15px; | |
position: relative; | |
} | |
.current img, .next img { | |
object-fit: cover; | |
object-position: 50% 0%; | |
border-radius: 10px; | |
box-shadow: 0px 0px 0px 2px rgba(240,240,240,1); | |
} | |
.current img { | |
width: 96vw; | |
margin: 2vw; | |
} | |
.next img { | |
height: 100%; | |
width: 94vw; | |
margin: 1vw 3vw; | |
} | |
.result { | |
} | |
.liking:after { | |
font-size: 25vw; | |
content: "Like"; | |
padding: 10px 26px; | |
color: #73c998; | |
border: #73c998 2vw solid; | |
margin-top: 100px; | |
z-index: 9999; | |
display: inline-flex; | |
position: absolute; | |
border-radius: 30px; | |
text-shadow: 0px 0px 15px rgba(0, 0, 0, 0.75); | |
box-shadow: 0px 0px 15px 0px rgba(0,0,0,0.75); | |
opacity: 1; | |
transform: scale(1) rotate(-7deg); | |
animation: resultAnim .8s ease-in-out; | |
} | |
.noping:after { | |
font-size: 25vw; | |
content: "Nope"; | |
padding: 6px 26px 16px; | |
color: #ed7571; | |
border: #ed7571 2vw solid; | |
margin-top: 100px; | |
z-index: 9999; | |
display: inline-flex; | |
position: absolute; | |
border-radius: 30px; | |
text-shadow: 0px 0px 15px rgba(0, 0, 0, 0.75); | |
box-shadow: 0px 0px 15px 0px rgba(0,0,0,0.75); | |
opacity: 1; | |
transform: scale(1) rotate(-7deg); | |
animation: resultAnim .8s ease-in-out; | |
} | |
@keyframes resultAnim { | |
0% { | |
transform: scale(3) rotate(0deg); | |
opacity: 0.2; | |
} | |
100% { | |
transform: scale(1) rotate(-7deg); | |
opacity: 1; | |
} | |
} | |
.likeBtn { | |
border-radius: 50%; | |
height: 115px; | |
width: 115px; | |
box-shadow: 0px 0px 0px 20px rgba(240,240,240,1); | |
border: none; | |
padding: 20px; | |
margin: 0 10px; | |
background: url('https://canjs.com/docs/can-guides/commitment/recipes/tinder-like-carousel/img/heart.svg') no-repeat center; | |
background-size: auto 55px; | |
color : transparent; | |
font-size : 0; | |
} | |
.dissBtn { | |
border-radius: 50%; | |
height: 115px; | |
width: 115px; | |
box-shadow: 0px 0px 0px 20px rgba(240,240,240,1); | |
border: none; | |
padding: 50px; | |
margin: 0 10px; | |
background: url('https://canjs.com/docs/can-guides/commitment/recipes/tinder-like-carousel/img/close.svg') no-repeat center; | |
background-size: auto 50px; | |
color : transparent; | |
font-size : 0; | |
} | |
@media screen | |
and (min-width: 320px) | |
and (max-width: 890px) { | |
.undoBtn, .superBtn { | |
height: 40px; | |
width: 40px; | |
padding: 25px; | |
margin: 0 3px; | |
box-shadow: 0px 0px 0px 10px rgba(240,240,240,1); | |
background-size: auto 25px; | |
} | |
.likeBtn, .dissBtn { | |
height: 90px; | |
width: 90px; | |
padding: 25px; | |
margin: 0 6px; | |
box-shadow: 0px 0px 0px 10px rgba(240,240,240,1); | |
background-size: auto 50px; | |
} | |
} |