const translateYRegex = /\.*translateY\((.*)px\)/i; let paneY; let paneEl; let totalprice = 0; let itemprice = 3; let size = 'S'; let bottomer = 20; const contentEl = document.querySelector('.content'); const firstStep = document.querySelector('.first-step'); const myBag = document.querySelector('.my-bag'); const myBagH2 = document.querySelector('.my-bag h2'); const myBagList = document.querySelector('.my-bag .list'); const firstHeight = 120; firstStep.style.height = `${firstHeight - 30}px`; contentEl.style.marginTop = `-${firstHeight + firstHeight/2}px`; contentEl.style.paddingTop = `${firstHeight/2}px`; contentEl.style.transform = `translateY(${firstHeight}px) translateZ(0px)`; contentEl.style.height = `calc(100% + ${firstHeight/2}px + 30px)`; function checkTransformations() { paneEl = document.querySelector('.pane'); if (!paneEl) return; paneY = parseFloat(translateYRegex.exec(paneEl.style.transform)[1]); if (window.innerHeight - paneY <= bottomer) { drawer.disableDrag(); drawer.destroy({animate: true}); return; } if (window.innerHeight - paneY - 30 > firstHeight) { myBagH2.style.transform = 'translate3d(0px, 0px, 0px)'; myBagList.style.transform = 'translate3d(0px, 0px, 0px)'; myBag.style.opacity = 1; firstStep.style.opacity = 0; } else { myBagH2.style.transform = 'translate3d(0px, 60px, 0px)'; myBagList.style.transform = 'translate3d(0px, 60px, 0px)'; myBag.style.opacity = 0; firstStep.style.opacity = 1; } } let drawer = new CupertinoPane('ion-drawer', { followerElement: '.content', breaks: { middle: { enabled: true, height: firstHeight, timing: 'ease' }, bottom: { enabled: true, height: bottomer, timing: 'ease' } }, buttonDestroy: false, showDraggable: false, bottomClose: true, draggableOver: true, lowerThanBottom: false, dragBy: ['.cupertino-pane-wrapper .pane', '.content'], events: { onDrag: () => checkTransformations(), onTransitionEnd: () => checkTransformations() } }); function presentPane(e) { drawer.present({animate: true}); drawer.enableDrag(); // Total price totalprice += itemprice; document.getElementsByClassName('big')[1].innerHTML = totalprice; document.getElementById('total-amount').innerHTML = totalprice; document.getElementsByClassName('size-drink')[1].innerHTML = size; // Button animation let icon = document.querySelector('#button-add ion-icon'); let text = document.querySelector('#button-add .button-text'); text.style.opacity = 0; setTimeout(() => { icon.style.opacity = 1; text.innerHTML = 'Add 1 more' }, 200); setTimeout(() => { icon.style.opacity = 0; }, 1000); setTimeout(() => { text.style.opacity = 1; }, 1300); } function setActive(e, n, kfc, s) { itemprice = n; size = s; let frame = document.querySelector('.active-frame '); frame.style.transform = `translate3d(${55 * kfc}px, 0px, 0px)`; let elems = document.getElementsByClassName('size'); for (var i = 0; i < elems.length; i++) { elems[i].classList.remove('active'); } e.classList.add('active'); document.getElementsByClassName('big')[0].innerHTML = itemprice; }
<html dir="ltr" mode="ios"> <body> <ion-app> <ion-content scroll-y="false"> <div class="content"> <ion-header translucent="true"> <ion-toolbar> <ion-buttons slot="start"> <ion-button> <ion-icon name="chevron-back-outline"></ion-icon> Frappuccino </ion-button> </ion-buttons> <ion-buttons slot="end"> <ion-button> <ion-icon name="heart-outline"></ion-icon> </ion-button> </ion-buttons> </ion-toolbar> </ion-header> <div class="content-body"> <img draggable="false" src="https://raw.githubusercontent.com/roman-rr/cupertino-pane/master/playground/img/starbucks.png" /> <h1>Mocha Frappuccino®</h1> <p> Buttery caramel syrup meets coffee, milk and ice for a rendezvous in the blender. </p> <div class="line"> <div class="price"> £ <div class="big">3</div>.45 </div> <div class="sizes"> <div class="active-frame"></div> <div class="size active" onclick="setActive(this, 3, 0, 'S')"> S <ion-icon name="cafe-outline"></ion-icon> </div> <div class="size" onclick="setActive(this, 5, 1, 'M')"> M <ion-icon name="cafe-outline"></ion-icon> </div> <div class="size" onclick="setActive(this, 7, 2, 'L')"> L <ion-icon name="cafe-outline"></ion-icon> </div> </div> </div> <ion-button id="button-add" expand="block" onclick="presentPane();"> <span class="button-text">Add to Bag</span> <ion-icon name="checkmark-outline"></ion-icon> </ion-button> <div class="draggable"> <div class="move"></div> </div> </div> </div> <ion-drawer> <!-- First step --> <div class="first-step"> <div class="drinks"> <div class="drink"> <img src="https://raw.githubusercontent.com/roman-rr/cupertino-pane/master/playground/img/cup-1.png" /> <div class="size-drink">M</div> <div class="bg"></div> </div> <div class="drink"> <img src="https://raw.githubusercontent.com/roman-rr/cupertino-pane/master/playground/img/cup-2.png" /> <div class="size-drink">L</div> <div class="bg"></div> </div> </div> <div class="price"> £ <div class="big">3</div>.45 </div> </div> <!-- My Bag --> <div class="my-bag"> <h2>My Bag</h2> <div class="list"> <!-- Item 1 --> <div class="item"> <div class="left-side"> <div class="drink"> <img src="https://raw.githubusercontent.com/roman-rr/cupertino-pane/master/playground/img/cup-1.png" /> <div class="bg"></div> </div> <div class="desc"> <div class="name">Caramel Frappuccino®</div> <div class="size">Size M</div> <div class="price">£ 4.85</div> </div> </div> <div class="amount">x 1</div> </div> <!-- Item 2 --> <div class="item"> <div class="left-side"> <div class="drink"> <img src="https://raw.githubusercontent.com/roman-rr/cupertino-pane/master/playground/img/cup-2.png" /> <div class="bg"></div> </div> <div class="desc"> <div class="name">Mocha Frappuccino®</div> <div class="size">Size L</div> <div class="price">£ 3.70</div> </div> </div> <div class="amount">x 1</div> </div> </div> <div class="footer"> <div class="line"> <div class="text"> Total </div> <div class="amount"> £ <span id="total-amount"></span>.70 </div> </div> <ion-button expand="block"> Confirm Order </ion-button> </div> </div> </ion-drawer> </ion-content> </ion-app> </body> </html>
ion-toolbar { --background: #ffffff; --border-color: #ffffff; } ion-content { --background: rgb(0, 112, 74); --cupertino-pane-background: rgb(0, 112, 74); } .content { background: #ffffff; height: 100%; border-radius: 0 0 30px 30px; border-width: 1px; border: 1px solid #ffffff; z-index: 12; position: relative; } ion-toolbar ion-button { --color: #292929; } .content-body { padding-left: 20px; padding-right: 20px; } .content-body h1 { margin-top: 30px; } .content-body p { color: #828282; font-size: 14px; line-height: 20px; } .content-body img { display: block; max-width: 100%; margin: auto; margin-top: 10px; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -o-user-select: none; user-select: none; } .content-body ion-button { margin-left: 0; margin-right: 0; --border-radius: 30px; font-weight: 600; --background: rgb(0, 112, 74); margin-top: 5px; } .content-body ion-button:active { --background: rgb(39, 92, 65); } .content-body .price { display: flex; align-items: center; font-size: 26px; font-weight: 600; height: 60px; margin-left: 5px; } .content-body .price .big { margin-left: 5px; font-size: 50px; } .content-body .line { height: 60px; display: flex; justify-content: space-between; align-items: center; flex-direction: row; } .content-body .sizes { display: flex; } .content-body .sizes .size { font-size: 11px; font-weight: 700; display: flex; justify-content: center; align-items: center; width: 48px; height: 48px; border: 1px solid #DADADA; border-radius: 3px; margin-right: 7px; color: #DADADA; background: rgb(248, 248, 248); padding-bottom: 3px; transition: all 200ms ease-in-out; position: relative; } .content-body .sizes .size.active { font-size: 11px; background: rgb(232, 240, 236); color: rgb(48, 111, 78); } .content-body .sizes .active-frame { transform: translate3d(0px, 0px, 0px); transition: all 200ms ease-in-out; border-radius: 3px; width: 48px; height: 48px; position: absolute; border: 2px solid rgb(48, 111, 78); z-index: 2; } .content-body .sizes .size ion-icon { position: absolute; font-size: 37px; margin-top: 6px; top: 0; left: 2px; right: 0; margin-left: auto; margin-right: auto; z-index: 1; } .content-body .draggable { padding: 15px; position: absolute; bottom: 0px; left: 0px; right: 0px; margin-left: auto; margin-right: auto; height: 30px; } .content-body .draggable .move { margin: 0px auto; height: 5px; background: rgba(202, 202, 202, 0.6); width: 50px; border-radius: 4px; backdrop-filter: saturate(180%) blur(20px); } .pane ion-drawer { background: rgb(0, 112, 74) !important; border-radius: 0 !important; box-shadow: none !important; } #button-add .button-text { transition: all 300ms ease-in-out; opacity: 1; } #button-add ion-icon { position: absolute; transition: all 300ms ease-in-out; opacity: 0; } ion-drawer .first-step { display: flex; justify-content: space-between; align-items: center; margin-left: 20px; margin-right: 20px; transition: all 150ms ease-in-out; opacity: 1; margin-top: 20px; } ion-drawer .first-step .price { display: flex; align-items: center; font-size: 26px; font-weight: 600; color: #ffffff; } ion-drawer .first-step .drinks { display: flex; justify-content: center; align-items: center; } .first-step .drinks .drink { width: 48px; height: 48px; border-radius: 3px; margin-right: 7px; position: relative; } .first-step .drinks .bg { position: absolute; width: 40px; height: 40px; border-radius: 50%; background: rgb(30, 74, 52); bottom: 0; margin-left: auto; margin-right: auto; left: 0; right: 0; } .first-step .drinks .size-drink { position: absolute; width: 18px; height: 18px; border-radius: 50%; background: #ffffff; font-weight: 700; right: -3px; z-index: 1; display: flex; align-items: center; justify-content: center; font-size: 11px; } .first-step .drinks img { display: block; position: absolute; z-index: 2; left: 0; right: 0; margin-left: auto; margin-right: auto; bottom: 6px; } ion-drawer .my-bag { margin-left: 20px; margin-right: 20px; display: flex; flex-direction: column; align-items: center; opacity: 0; transition: all 150ms ease-in-out; } ion-drawer .my-bag h2 { font-weight: 800; color: #ffffff; margin-top: -60px; font-size: 28px; will-change: transform, opacity; transform: translate3d(0px, 60px, 0px); transition: all 150ms ease-in-out; } ion-drawer .my-bag .list { width: 100%; will-change: transform, opacity; transform: translate3d(0px, 60px, 0px); transition: all 150ms ease-in-out; } ion-drawer .my-bag .item { display: flex; justify-content: space-between; margin-top: 25px; } ion-drawer .my-bag .left-side { display: flex; align-items: center; } ion-drawer .my-bag .drink { width: 48px; height: 48px; border-radius: 3px; margin-right: 20px; position: relative; transform: scale(1.2); } .my-bag .drink .bg { position: absolute; width: 40px; height: 40px; border-radius: 50%; background: rgb(30, 74, 52); bottom: 0; margin-left: auto; margin-right: auto; left: 0; right: 0; } .my-bag .drink img { display: block; position: absolute; z-index: 2; left: 0; right: 0; margin-left: auto; margin-right: auto; bottom: 6px; } .my-bag .item .amount { font-size: 22px; font-weight: 700; color: #ffffff; display: flex; align-items: center; } .my-bag .item .desc .name { color: #fff; font-weight: 600; font-size: 17px; } .my-bag .item .desc .size { color: #fff; font-size: 14px; margin-top: 2px; } .my-bag .item .desc .price { color: #88afa2; font-size: 16px; margin-top: 10px; } .my-bag .footer { border-top: 1px solid #ffffff2b; position: absolute; width: calc(100% - 40px); bottom: 0; padding-bottom: 35px; background: #00704a; } .my-bag .footer .line { display: flex; justify-content: space-between; align-items: center; margin-top: 20px; margin-bottom: 20px; } .my-bag .footer .line .text, .my-bag .footer .line .amount { font-weight: 700; color: #ffffff; font-size: 26px; } .my-bag .footer ion-button { --border-radius: 30px; font-weight: 700; --background: #fff; color: #00704a; font-size: 17px; letter-spacing: 0.1px; } .my-bag .footer ion-button:active { --background: #effffa; }