JSFiddle - React, Tailwind, and code Playground
by romantonoff
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ionic/core@6.6.2/css/ionic.bundle.css">
<script src="https://unpkg.com/cupertino-pane/dist/cupertino-pane.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@ionic/core@6.6.2/dist/ionic/ionic.js"></script>
<html mode="ios">
<head>
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
</head>
<body class="dark primary">
<ion-app>
<ion-content scroll-y="false">
<!-- Texts -->
<div class="top-content hide-on-present">
<div class="titles">
<h1>$23,165.82</h1>
<h2 class="result">+$49.56 (0.32%)</h2>
<h2 class="name">Bitcoin</h2>
</div>
<!-- Thanks GUI CHALLENGE for button idea -->
<button class="theme-toggle" onclick="toggleTheme();" id="theme-toggle" title="Toggles light & dark" aria-label="auto" aria-live="polite">
<svg class="sun-and-moon" aria-hidden="true" width="24" height="24" viewBox="0 0 24 24">
<mask class="moon" id="moon-mask">
<rect x="0" y="0" width="100%" height="100%" fill="white" />
<circle cx="24" cy="10" r="6" fill="black" />
</mask>
<circle class="sun" cx="12" cy="12" r="6" mask="url(#moon-mask)" fill="currentColor" />
<g class="sun-beams" stroke="currentColor">
<line x1="12" y1="1" x2="12" y2="3" />
<line x1="12" y1="21" x2="12" y2="23" />
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
<line x1="1" y1="12" x2="3" y2="12" />
<line x1="21" y1="12" x2="23" y2="12" />
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</g>
</svg>
</button>
</div>
<!-- Synthwave -->
...
CSS
body.dark {
--ion-background-color: #080317;
--ion-background-color-rgb: rgb(8 3 23);
--ion-toolbar-background: #1f1f1f;
--hide-delay: 400ms;
}
body.primary {
--ion-color-primary: #ff69b4;
--ion-color-primary-rgb: 255, 107, 181;
--ion-color-primary-contrast: #333333;
--ion-color-primary-contrast-rgb: 51, 51, 51;
--ion-color-primary-shade: #f3499e;
--ion-color-primary-tint: #fa71b5;
--ion-color-secondary: #add65c;
--ion-color-secondary-rgb: 173, 214, 92;
--ion-color-secondary-contrast: #333333;
--ion-color-secondary-contrast-rgb: 51, 51, 51;
--ion-color-secondary-shade: #a4d63e;
--ion-color-secondary-tint: #b5da6b;
}
body.secondary {
--ion-color-primary: #add65c;
--ion-color-primary-rgb: 173, 214, 92;
--ion-color-primary-contrast: #333333;
--ion-color-primary-contrast-rgb: 51, 51, 51;
--ion-color-primary-shade: #a4d63e;
--ion-color-primary-tint: #b5da6b;
--ion-color-secondary: #ff69b4;
--ion-color-secondary-rgb: 255, 107, 181;
--ion-color-secondary-contrast: #333333;
--ion-color-secondary-contrast-rgb: 51, 51, 51;
--ion-color-secondary-shade: #f3499e;
--ion-color-secondary-tint: #fa71b5;
}
.hide-on-present {
opacity: 1;
transition: opacity var(--hide-delay) ease;
}
.show-on-present {
opacity: 0;
transition: opacity var(--hide-delay) ease;
}
body.pane-visible .hide-on-present {
opacity: 0;
}
body.pane-visible .show-on-present {
opacity: 1;
}
/* Synthwave styles */
.fade-overlay {
position: absolute;
bottom: 183px;
width: 100vw;
height: 100px;
z-index: 1;
background: linear-gradient(180deg, rgba(8,3,23,1) 0%, rgba(8,3,23,0.8) 37%, rgba(8,3,23,0) 100%);
}
section.synthwave {
position: absolute;
bottom: 0px;
height: 270px;
overflow: visible;
z-index: 1;
}
section.synthwave div.synth-wrapper {
height: 100vh;
width: 140vw;
...
JavaScript
// Global scope
let pane;
let presentTransition = {
duration: 600,
opacity: 0,
translateY: 280,
prespective: 250,
rotateX: 65,
scale: 0.3
};
let destroyTransition = {
duration: 600,
opacity: 0,
translateY: 280,
prespective: 250,
rotateX: 65,
scale: 0.3
};
// DOM ready
window.onload = async function () {
await document.querySelector('ion-app').componentOnReady();
drawGraphCanvas();
window.addEventListener('resize', drawGraphCanvas);
// Calculator
let price = '23,165.82';
let amount = document.querySelector('#amount');
let submitButton = document.querySelector('#submitButton');
let estPrice = document.querySelector('#estPrice');
let estBtc = document.querySelector('#estBtc');
let swipeCancel = document.querySelector('#swipeCancel');
let sendingOrder = document.querySelector('#sendingOrder');
// Cupertino-Pane is magic panes for PWA interfaces
// npm i cupertino-pane
pane = new CupertinoPane('cupertino-pane', {
fitHeight: true,
inverse: true,
bottomClose: true,
showDraggable: false,
bottomOffset: 120,
upperThanTop: true,
dragBy: ['.backdrop', '.cupertino-pane-wrapper .pane'],
backdrop: true,
backdropOpacity: 0,
events: {
onWillPresent: () => {
amount.value = '$1';
estPrice.value = `$${price}`;
estBtc.value = '0.0000431670 BTC';
submitButton.removeAttribute('disabled');
},
onWillDismiss: () => {
document.body.classList.remove('pane-visible');
},
onDidDismiss: () => {
sendingOrder.classList.add('hidden');
swipeCancel.classList.remove('hidden');
}
}
});
// Rewrite and customize some transitions to make
// pane moved by touchmove events with
// custom perspective transitions
pane.transitions.setPaneElTransform = (params) => setPaneElTransform(params);
// Set caret
amount.addEventListener('ionFocus', () => {
let val = amount.value;
amount.value = '$1 ';
...