├── classicv2x.png:Zone.Identifier ├── README.md ├── classicv2.png ├── classicv2.png:Zone.Identifier ├── classicv2x.png ├── index.html ├── style.css └── script.js /classicv2x.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sliderparallaxcard 2 | -------------------------------------------------------------------------------- /classicv2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/closeresty/sliderparallaxcard/HEAD/classicv2.png -------------------------------------------------------------------------------- /classicv2.png:Zone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | HostUrl=about:internet 4 | -------------------------------------------------------------------------------- /classicv2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/closeresty/sliderparallaxcard/HEAD/classicv2x.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sliderparallaxcard 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 |
16 |
17 |
18 |
New Look
19 | 20 | 21 | ₱1500 22 | 23 |

VAPE 1

24 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 25 | 26 |
27 | 28 |
29 | 30 |
Wish List
31 | 32 | Woman type 33 |
34 |
35 | 36 | 37 |
38 |
39 | 40 |
41 |
New Look
42 | 43 | 44 | ₱1500 45 | 46 |

Vape 2

47 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 48 | 49 |
50 | 51 |
52 | 53 |
Wish List
54 | 55 | Woman type 56 |
57 |
58 | 59 | 60 |
61 |
62 |
63 |
New Look
64 | 65 | 66 | ₱1400 67 | 68 |

Vape 3

69 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. 70 | 71 |
72 | 73 |
74 | 75 |
Wish List
76 | 77 | Man type 78 |
79 |
80 | 81 |
82 | 83 |
84 |
85 |
86 |
87 |
88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | height: 100%; 4 | width: 100%; 5 | margin: 0; 6 | padding: 0; 7 | 8 | font-family: "Roboto", "Helvetica", sans-serif; 9 | 10 | transition: background-color 0.2s; 11 | will-change: background-color; 12 | } 13 | 14 | .inspired-by { 15 | display: block; 16 | position: relative; 17 | margin-bottom: 15px; 18 | text-align: center; 19 | color: #fff; 20 | font-size: 14px; 21 | } 22 | 23 | .wrapper { 24 | position: relative; 25 | overflow-x: hidden; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | 30 | .card { 31 | display: block; 32 | position: absolute; 33 | top: 50px; 34 | margin: 0 auto; 35 | width: 280px; 36 | background-color: #fff; 37 | border-radius: 15px; 38 | 39 | box-shadow: 0 30 50 rgba(0, 0, 0, 0.2); 40 | 41 | transform: translateX(-50%); 42 | transition: left 0.5s ease-out; 43 | will-change: left; 44 | 45 | -webkit-user-select: none; 46 | -moz-user-select: none; 47 | -ms-user-select: none; 48 | -o-user-select: none; 49 | user-select: none; 50 | } 51 | 52 | .card--19 { 53 | left: 50%; 54 | } 55 | 56 | .card--solstice, 57 | .card--huarache { 58 | left: 150%; 59 | } 60 | 61 | .card__header { 62 | position: relative; 63 | height: 170px; 64 | padding: 30px 30px 300px; 65 | border-top-right-radius: 15px; 66 | border-top-left-radius: 15px; 67 | color: #fff; 68 | } 69 | 70 | .card__header--19 { 71 | background-color: #F72648; 72 | background-image: linear-gradient(#F72648, #FCCB3C); 73 | 74 | background: #F72648; 75 | background: linear-gradient(#F72648, #FCCB3C); 76 | } 77 | 78 | .card__header--solstice { 79 | background-color: #3CA3FC; 80 | background-image: linear-gradient(#3CA3FC, #FFD300); 81 | 82 | background: #3CA3FC; 83 | background: linear-gradient(#3CA3FC, #FFD300); 84 | } 85 | 86 | .card__header--huarache { 87 | background-color: #26C9F7; 88 | background-image: linear-gradient(#26C9F7, #DFFC3C); 89 | 90 | background: #26C9F7; 91 | background: linear-gradient(#26C9F7, #DFFC3C); 92 | } 93 | 94 | .card__watermark { 95 | overflow: hidden; 96 | position: absolute; 97 | bottom: 10px; 98 | left: 0; 99 | width: 100%; 100 | } 101 | 102 | .card__watermark::after { 103 | content: attr(data-watermark); 104 | position: relative; 105 | left: -20px; 106 | color: rgba(0, 0, 0, .3); 107 | font-size: 240px; 108 | font-weight: 700; 109 | text-transform: uppercase; 110 | } 111 | 112 | .card__logo { 113 | width: 50px; 114 | height: auto; 115 | } 116 | 117 | .card__price { 118 | float: right; 119 | font-size: 16px; 120 | font-weight: 300; 121 | } 122 | 123 | .card__title { 124 | margin: 35px 0 20px; 125 | font-size: 15px; 126 | line-height: 1.1em; 127 | text-transform: uppercase; 128 | letter-spacing: 1.5px; 129 | } 130 | 131 | .card__subtitle { 132 | display: block; 133 | font-size: 13px; 134 | font-weight: 300; 135 | } 136 | 137 | .card__body { 138 | position: relative; 139 | padding: 40px 30px 20px; 140 | } 141 | 142 | .card__image { 143 | z-index: 1; 144 | position: absolute; 145 | top: -290px; 146 | left: -30px; 147 | width: 125%; 148 | 149 | user-select: none; 150 | -moz-user-select: none; 151 | -webkit-user-drag: none; 152 | -webkit-user-select: none; 153 | -ms-user-select: none; 154 | } 155 | 156 | .card__wish-list { 157 | display: block; 158 | width: 50%; 159 | margin: 0 auto 15px; 160 | padding: 15px; 161 | border: 2px solid #fff; 162 | border-radius: 20px; 163 | text-align: center; 164 | text-transform: uppercase; 165 | font-size: 14px; 166 | } 167 | 168 | .card__wish-list--19 { 169 | color: #8850FF; 170 | border-color: #8850FF; 171 | } 172 | 173 | .card__wish-list--solstice { 174 | color: #FFBA00; 175 | border-color: #FFBA00; 176 | } 177 | 178 | .card__wish-list--huarache { 179 | color: #26C9F7; 180 | border-color: #26C9F7; 181 | } 182 | 183 | .card__category { 184 | display: block; 185 | font-size: 12px; 186 | color: #AEAEAE; 187 | text-transform: uppercase; 188 | text-align: center; 189 | } 190 | 191 | .card__will-animate { 192 | will-change: transform; 193 | } 194 | 195 | .cards-placeholder { 196 | display: block; 197 | position: relative; 198 | margin-bottom: 15px; 199 | text-align: center; 200 | } 201 | 202 | .cards-placeholder__item { 203 | opacity: 0.3; 204 | display: inline-block; 205 | margin-right: 10px; 206 | background-color: #fff; 207 | width: 30px; 208 | height: 5px; 209 | border-radius: 5px; 210 | 211 | transition: opacity 0.2s; 212 | will-change: opacity; 213 | } 214 | 215 | .cards-placeholder__item--active { 216 | opacity: 1; 217 | } -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var BODY_BACKGROUNDS = [ 5 | '#8850FF', 6 | '#FFBA00', 7 | '#4054FF' 8 | ]; 9 | 10 | function Slider() { 11 | this.cards = document.querySelectorAll('.card'); 12 | this.currentIndex = 0; 13 | 14 | this.isDragging = false; 15 | this.startX = 0; 16 | this.currentX = 0; 17 | 18 | this.initEvents(); 19 | this.setActivePlaceholder(); 20 | } 21 | 22 | // initialize drag events 23 | Slider.prototype.initEvents = function () { 24 | document.addEventListener('touchstart', this.onStart.bind(this)); 25 | document.addEventListener('touchmove', this.onMove.bind(this)); 26 | document.addEventListener('touchend', this.onEnd.bind(this)); 27 | 28 | document.addEventListener('mousedown', this.onStart.bind(this)); 29 | document.addEventListener('mousemove', this.onMove.bind(this)); 30 | document.addEventListener('mouseup', this.onEnd.bind(this)); 31 | 32 | }; 33 | 34 | // set active placeholder 35 | Slider.prototype.setActivePlaceholder = function () { 36 | var placeholders = document.querySelectorAll('.cards-placeholder__item'); 37 | var activePlaceholder = document.querySelector('.cards-placeholder__item--active') 38 | 39 | if (activePlaceholder) { 40 | activePlaceholder.classList.remove('cards-placeholder__item--active'); 41 | } 42 | 43 | placeholders[this.currentIndex].classList.add('cards-placeholder__item--active'); 44 | 45 | var bodyEl = document.querySelector('body'); 46 | bodyEl.style.backgroundColor = BODY_BACKGROUNDS[this.currentIndex]; 47 | }; 48 | 49 | // mousedown event 50 | Slider.prototype.onStart = function (evt) { 51 | this.isDragging = true; 52 | 53 | this.currentX = evt.pageX || evt.touches[0].pageX; 54 | this.startX = this.currentX; 55 | 56 | var card = this.cards[this.currentIndex]; 57 | 58 | // calculate ration to use in parallax effect 59 | this.windowWidth = window.innerWidth; 60 | this.cardWidth = card.offsetWidth; 61 | this.ratio = this.windowWidth / (this.cardWidth / 4); 62 | }; 63 | 64 | // mouseup event 65 | Slider.prototype.onEnd = function (evt) { 66 | this.isDragging = false; 67 | 68 | var diff = this.startX - this.currentX; 69 | var direction = (diff > 0) ? 'left' : 'right'; 70 | this.startX = 0; 71 | 72 | if (Math.abs(diff) > this.windowWidth / 4) { 73 | if (direction === 'left') { 74 | this.slideLeft(); 75 | } else if (direction === 'right') { 76 | this.slideRight(); 77 | } else { 78 | this.cancelMoveCard(); 79 | } 80 | 81 | } else { 82 | this.cancelMoveCard(); 83 | 84 | } 85 | 86 | }; 87 | 88 | // mousemove event 89 | Slider.prototype.onMove = function (evt) { 90 | 91 | if (!this.isDragging) return; 92 | 93 | this.currentX = evt.pageX || evt.touches[0].pageX; 94 | var diff = this.startX - this.currentX; 95 | diff *= -1; 96 | 97 | // don't let drag way from the center more than quarter of window 98 | if (Math.abs(diff) > this.windowWidth / 4) { 99 | if (diff > 0) { 100 | diff = this.windowWidth / 4; 101 | } else { 102 | diff = - this.windowWidth / 4; 103 | } 104 | } 105 | 106 | this.moveCard(diff); 107 | }; 108 | 109 | // slide to left direction 110 | Slider.prototype.slideLeft = function () { 111 | // if last don't do nothing 112 | if (this.currentIndex === this.cards.length - 1) { 113 | this.cancelMoveCard(); 114 | return; 115 | } 116 | 117 | var self = this; 118 | var card = this.cards[this.currentIndex]; 119 | var cardWidth = this.windowWidth / 2; 120 | 121 | card.style.left = '-50%'; 122 | 123 | this.resetCardElsPosition(); 124 | 125 | this.currentIndex += 1; 126 | this.setActivePlaceholder(); 127 | card = this.cards[this.currentIndex]; 128 | 129 | card.style.left = '50%'; 130 | 131 | this.moveCardEls(cardWidth * 3); 132 | 133 | // add delay to resetting position 134 | setTimeout(function () { 135 | self.resetCardElsPosition(); 136 | }, 50); 137 | }; 138 | 139 | // slide to right direction 140 | Slider.prototype.slideRight = function () { 141 | // if last don't do nothing 142 | if (this.currentIndex === 0) { 143 | this.cancelMoveCard(); 144 | return; 145 | } 146 | 147 | var self = this; 148 | var card = this.cards[this.currentIndex]; 149 | var cardWidth = this.windowWidth / 2; 150 | 151 | card.style.left = '150%'; 152 | 153 | this.resetCardElsPosition(); 154 | 155 | this.currentIndex -= 1; 156 | this.setActivePlaceholder(); 157 | card = this.cards[this.currentIndex]; 158 | 159 | card.style.left = '50%'; 160 | 161 | this.moveCardEls(-cardWidth * 3); 162 | 163 | // add delay to resetting position 164 | setTimeout(function () { 165 | self.resetCardElsPosition(); 166 | }, 50); 167 | }; 168 | 169 | // put active card in original position (center) 170 | Slider.prototype.cancelMoveCard = function () { 171 | var self = this; 172 | var card = this.cards[this.currentIndex]; 173 | 174 | card.style.transition = 'transform 0.5s ease-out'; 175 | card.style.transform = ''; 176 | 177 | this.resetCardElsPosition(); 178 | }; 179 | 180 | // reset to original position elements of card 181 | Slider.prototype.resetCardElsPosition = function () { 182 | var self = this; 183 | var card = this.cards[this.currentIndex]; 184 | 185 | var cardLogo = card.querySelector('.card__logo'); 186 | var cardPrice = card.querySelector('.card__price'); 187 | var cardTitle = card.querySelector('.card__title'); 188 | var cardSubtitle = card.querySelector('.card__subtitle'); 189 | var cardImage = card.querySelector('.card__image'); 190 | var cardWishList = card.querySelector('.card__wish-list'); 191 | var cardCategory = card.querySelector('.card__category'); 192 | var cardWillAnimate = card.querySelectorAll('.card__will-animate'); 193 | 194 | // move card elements to original position 195 | cardWillAnimate.forEach(function (el) { 196 | el.style.transition = 'transform 0.5s ease-out'; 197 | }); 198 | 199 | cardLogo.style.transform = ''; 200 | cardPrice.style.transform = ''; 201 | 202 | cardTitle.style.transform = ''; 203 | cardSubtitle.style.transform = ''; 204 | 205 | cardImage.style.transform = ''; 206 | cardWishList.style.transform = ''; 207 | cardCategory.style.transform = ''; 208 | 209 | // clear transitions 210 | setTimeout(function () { 211 | card.style.transform = ''; 212 | card.style.transition = ''; 213 | 214 | cardWillAnimate.forEach(function (el) { 215 | el.style.transition = ''; 216 | }); 217 | }, 500); 218 | 219 | }; 220 | 221 | // slide card while dragging 222 | Slider.prototype.moveCard = function (diff) { 223 | 224 | var card = this.cards[this.currentIndex]; 225 | 226 | card.style.transform = 'translateX(calc(' + diff + 'px - 50%))'; 227 | diff *= -1; 228 | 229 | this.moveCardEls(diff); 230 | }; 231 | 232 | // create parallax effect on card elements sliding them 233 | Slider.prototype.moveCardEls = function (diff) { 234 | var card = this.cards[this.currentIndex]; 235 | 236 | var cardLogo = card.querySelector('.card__logo'); 237 | var cardPrice = card.querySelector('.card__price'); 238 | var cardTitle = card.querySelector('.card__title'); 239 | var cardSubtitle = card.querySelector('.card__subtitle'); 240 | var cardImage = card.querySelector('.card__image'); 241 | var cardWishList = card.querySelector('.card__wish-list'); 242 | var cardCategory = card.querySelector('.card__category'); 243 | var cardWillAnimate = card.querySelectorAll('.card__will-animate'); 244 | 245 | cardLogo.style.transform = 'translateX(' + (diff / this.ratio) + 'px)'; 246 | cardPrice.style.transform = 'translateX(' + (diff / this.ratio) + 'px)'; 247 | 248 | cardTitle.style.transform = 'translateX(' + (diff / (this.ratio * 0.90)) + 'px)'; 249 | cardSubtitle.style.transform = 'translateX(' + (diff / (this.ratio * 0.85)) + 'px)'; 250 | 251 | cardImage.style.transform = 'translateX(' + (diff / (this.ratio * 0.35)) + 'px)'; 252 | 253 | cardWishList.style.transform = 'translateX(' + (diff / (this.ratio * 0.85)) + 'px)'; 254 | cardCategory.style.transform = 'translateX(' + (diff / (this.ratio * 0.65)) + 'px)'; 255 | 256 | }; 257 | 258 | 259 | // create slider 260 | var slider = new Slider(); 261 | 262 | })(); --------------------------------------------------------------------------------