skip to Main Content

I am making a simple Iphone IOS project in which there will be an Iphone frame and user will be able to use it as a phone and some basic features in it like camera, calendar, time etc…. so I was thinking to apply drag up gesture in it just like normal phones have but the drag function in not working I am an beginner so I don’t have so much of knowledge in html css and js so please help me solve the issue.

I was making the ios iphone replica project and trying to apply drag up gesture unlock feature in it so I wrote some html css and js for it

const iphone = document.querySelector('.iphone');
const mainScreen = document.querySelector('.main-screen');
const controlBar = document.querySelector('.control');
const lockScreen = document.querySelector('.lockscreen')
let isLocked = true;
let startY = 0;
let currentY = 0;

function unlocked() {
  let isLocked = false;
  mainScreen.style.display = 'flex';
  lockScreen.style.display = 'none';

}

// Hover effect to show control bar
iphone.addEventListener('mouseenter', () => {
  if (isLocked) {
    controlBar.style.opacity = 1;
    iphone.style.cursor = 'pointer';
  }
});

iphone.addEventListener('mouseleave', () => {
  if (isLocked) {
    controlBar.style.opacity = 0;
  }
});

// Drag gesture to unlock
iphone.addEventListener('mousedown', (e) => {
  if (isLocked) {
    startY = e.clientY;
    currentY = startY;
    iphone.addEventListener('mousemove', drag);
  }
});

window.addEventListener('mouseup', () => {
  if (isLocked) {
    iphone.removeEventListener('mousemove', drag);
    if (currentY - startY < -100) {
      unlockScreen();
    }
  }
});

function drag(e) {
  currentY = e.clientY;
}

function unlockScreen() {
  isLocked = false;
  mainScreen.style.transform = 'translateY(0)';
  controlBar.style.opacity = 1;
  iphone.style.cursor = 'default';
}
@import url('https://fonts.googleapis.com/css2?family=Ubuntu&display=swap');
* {
  margin: 0px;
  padding: 0px;
  font-family: 'Ubuntu', sans-serif;
}


/* Update the positioning for the info sections */

.info-left,
.info-right {
  font-size: 12px;
  /* Adjust the size as needed */
}


/* Update the positioning for the info sections */

.info-left {
  position: absolute;
  top: 5px;
  /* Adjust the vertical position as needed */
  left: 10px;
}

.info-right {
  position: absolute;
  top: 5px;
  right: 10px;
  display: flex;
  align-items: center;
  color: white;
}

.info-right .signal {
  margin-right: 5px;
  /* Adjust the margin as needed */
}

.info-right .network-type {
  margin-right: 5px;
  /* Adjust the margin as needed */
}

.iphone {
  background-image: url(ios-wallpaper.jpg);
  background-repeat: no-repeat;
  background-size: cover;
  width: 23vw;
  height: 95vh;
  margin: auto;
  color: white;
  border: 10px solid black;
  border-radius: 30px;
  position: relative;
}

.notch {
  background-color: black;
  display: flex;
  height: 4vh;
  width: 9vw;
  border-bottom-left-radius: 10px;
  border-bottom-right-radius: 10px;
  align-items: center;
  justify-content: center;
  position: relative;
  left: 80px;
}

.speaker {
  background-color: rgba(48, 47, 47, 0.6);
  box-shadow: 2px solid rgb(88, 88, 88);
  height: 3px;
  width: 20px;
  border-radius: 4px;
  margin-left: 5px;
}

.front-cam {
  margin-left: 5px;
  position: absolute;
  left: 5px;
  top: 6px;
  height: 14px;
  width: 14px;
  box-shadow: inset 0 0 1px rgba(26, 25, 25, 0.2);
}

.lens {
  height: 6px;
  width: 6px;
  border-radius: 50%;
  background-color: rgba(216, 216, 216, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);
}

.lens img {
  height: 12px;
  width: 13px;
}

.DateAndTime {
  text-align: center;
  position: relative;
  top: 15vh;
}

.bottom {
  position: relative;
  bottom: -350px;
}

.flashlight {
  position: relative;
  background-color: black;
  height: 6vh;
  width: 3vw;
  left: 10px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 500px;
}

.camera {
  position: relative;
  background-color: black;
  height: 6vh;
  width: 3vw;
  right: -210px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 500px;
  bottom: 6vh;
}

.control {
  width: 10vw;
  height: 3px;
  border-radius: 20px;
  background-color: white;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  left: 30%;
  bottom: -40px;
  opacity: 0;
  transition: opacity 0.3s;
}

.main-screen {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: white;
  /* Customize the background color */
  display: none;
  /* Hide by default */
  transition: transform 0.3s ease;
  z-index: -1;
  /* Place it behind the lock screen */
}

.iphone.hovered.control {
  opacity: 1;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/fontawesome.min.css" integrity="sha384-QYIZto+st3yW+o8+5OHfT6S482Zsvz2WfOzpFSXMF9zqeLcFV0/wlZpMtyFcZALm" crossorigin="anonymous">
  <title>IOS : Replica</title>
</head>

<body>
  <div class="container">
    <div class="iphone">
      <div class="notch">
        <div class="speaker"></div>
        <div class="front-cam">
          <div class="lens"><img src="lens.png" alt=""></div>
        </div>
      </div>
      <div class="lockscreen">

        <div class="DateAndTime">
          <h1 class="lock-time">11:57</h1>
          <p class="date">Saturday, 26 August</p>
        </div>
        <div class="info-left">
          <div class="operator">
            Airtel
          </div>
        </div>
        <div class="info-right">
          <div class="signal">
            <i class="fas fa-signal"></i>
          </div>
          <div class="network-type">
            5G
          </div>
          <ion-icon name="battery-half-outline"></ion-icon>
        </div>
        <div class="bottom">

          <div class="control"></div>

          <div class="flashlight">
            <ion-icon name="flashlight"></ion-icon>
          </div>

          <div class="camera">
            <i class="fas fa-camera"></i>
          </div>
        </div>
      </div>

      <div class="main-screen"></div>
    </div>
  </div>
</body>
<script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
<script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>

<script src="script.js"></script>

</html>

Please check the code and someone help me in this problem I want that the main screen (which is currently empty) should appear when someone drags up on the screen or the control bar and the lock screen should disappear but it is not happening

2

Answers


  1. Within the mouseup callback if you add the currentY=e.clientY, making sure that the event handler assigns e as the event, then I think your code does what you want. I added some CSS to help illustrate what happens when you drag up by more than designated amount (screen will turn green)

    const iphone = document.querySelector('.iphone');
    const mainScreen = document.querySelector('.main-screen');
    const controlBar = document.querySelector('.control');
    const lockScreen = document.querySelector('.lockscreen')
    let isLocked = true;
    let startY = 0;
    let currentY = 0;
    
    function unlocked() {
      let isLocked = false;
      mainScreen.style.display = 'flex';
      lockScreen.style.display = 'none';
    
    }
    
    // Hover effect to show control bar
    iphone.addEventListener('mouseenter', (e) => {
      if (isLocked) {
        currentY=e.clientY;
        controlBar.style.opacity = 1;
        iphone.style.cursor = 'pointer';
      }
    });
    
    iphone.addEventListener('mouseleave', (e) => {
      if (isLocked) {
        controlBar.style.opacity = 0;
      }
    });
    
    // Drag gesture to unlock
    iphone.addEventListener('mousedown', (e) => {
      if (isLocked) {
        startY = e.clientY;
        currentY = startY;
      }
    });
    
    window.addEventListener('mouseup', (e) => {
      if (isLocked) {
        currentY=e.clientY;
        if (currentY - startY < -100) {
          unlockScreen();
        }
      }
    });
    
    function drag(e) {
      currentY = e.clientY;
    }
    
    function unlockScreen() {
      isLocked = false;
      mainScreen.style.transform = 'translateY(0)';
      controlBar.style.opacity = 1;
      iphone.style.cursor = 'default';
      iphone.style.background='rgba(0,255,0,0.25)';
    }
    @import url('https://fonts.googleapis.com/css2?family=Ubuntu&display=swap');
    * {
      margin: 0px;
      padding: 0px;
      font-family: 'Ubuntu', sans-serif;
    }
    
    
    /* Update the positioning for the info sections */
    
    .info-left,
    .info-right {
      font-size: 12px;
      /* Adjust the size as needed */
    }
    
    
    /* Update the positioning for the info sections */
    
    .info-left {
      position: absolute;
      top: 5px;
      /* Adjust the vertical position as needed */
      left: 10px;
    }
    
    .info-right {
      position: absolute;
      top: 5px;
      right: 10px;
      display: flex;
      align-items: center;
      color: white;
    }
    
    .info-right .signal {
      margin-right: 5px;
      /* Adjust the margin as needed */
    }
    
    .info-right .network-type {
      margin-right: 5px;
      /* Adjust the margin as needed */
    }
    
    .iphone {
      background-image: url(ios-wallpaper.jpg);
      background-repeat: no-repeat;
      background-size: cover;
      width: 23vw;
      height: 95vh;
      margin: auto;
      color: white;
      border: 10px solid black;
      border-radius: 30px;
      position: relative;
    }
    
    .notch {
      background-color: black;
      display: flex;
      height: 4vh;
      width: 9vw;
      border-bottom-left-radius: 10px;
      border-bottom-right-radius: 10px;
      align-items: center;
      justify-content: center;
      position: relative;
      left: 80px;
    }
    
    .speaker {
      background-color: rgba(48, 47, 47, 0.6);
      box-shadow: 2px solid rgb(88, 88, 88);
      height: 3px;
      width: 20px;
      border-radius: 4px;
      margin-left: 5px;
    }
    
    .front-cam {
      margin-left: 5px;
      position: absolute;
      left: 5px;
      top: 6px;
      height: 14px;
      width: 14px;
      box-shadow: inset 0 0 1px rgba(26, 25, 25, 0.2);
    }
    
    .lens {
      height: 6px;
      width: 6px;
      border-radius: 50%;
      background-color: rgba(216, 216, 216, 0.7);
      display: flex;
      align-items: center;
      justify-content: center;
      box-shadow: inset 0 0 1px rgba(0, 0, 0, 0.5);
    }
    
    .lens img {
      height: 12px;
      width: 13px;
    }
    
    .DateAndTime {
      text-align: center;
      position: relative;
      top: 15vh;
    }
    
    .bottom {
      position: relative;
      bottom: -350px;
    }
    
    .flashlight {
      position: relative;
      background-color: black;
      height: 6vh;
      width: 3vw;
      left: 10px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 500px;
    }
    
    .camera {
      position: relative;
      background-color: black;
      height: 6vh;
      width: 3vw;
      right: -210px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 500px;
      bottom: 6vh;
    }
    
    .control {
      width: 10vw;
      height: 3px;
      border-radius: 20px;
      background-color: white;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      left: 30%;
      bottom: -40px;
      opacity: 0;
      transition: opacity 0.3s;
    }
    
    .main-screen {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: white;
      /* Customize the background color */
      display: none;
      /* Hide by default */
      transition: transform 0.3s ease;
      z-index: -1;
      /* Place it behind the lock screen */
    }
    
    .iphone.hovered.control {
      opacity: 1;
    }
    
    
    .DateAndTime,.operator{
      color:black
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <link rel="stylesheet" href="style.css">
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/fontawesome.min.css" integrity="sha384-QYIZto+st3yW+o8+5OHfT6S482Zsvz2WfOzpFSXMF9zqeLcFV0/wlZpMtyFcZALm" crossorigin="anonymous">
      <title>IOS : Replica</title>
    </head>
    
    <body>
      <div class="container">
        <div class="iphone">
          <div class="notch">
            <div class="speaker"></div>
            <div class="front-cam">
              <div class="lens"><img src="lens.png" alt=""></div>
            </div>
          </div>
          <div class="lockscreen">
    
            <div class="DateAndTime">
              <h1 class="lock-time">11:57</h1>
              <p class="date">Saturday, 26 August</p>
            </div>
            <div class="info-left">
              <div class="operator">
                Airtel
              </div>
            </div>
            <div class="info-right">
              <div class="signal">
                <i class="fas fa-signal"></i>
              </div>
              <div class="network-type">
                5G
              </div>
              <ion-icon name="battery-half-outline"></ion-icon>
            </div>
            <div class="bottom">
    
              <div class="control"></div>
    
              <div class="flashlight">
                <ion-icon name="flashlight"></ion-icon>
              </div>
    
              <div class="camera">
                <i class="fas fa-camera"></i>
              </div>
            </div>
          </div>
    
          <div class="main-screen"></div>
        </div>
      </div>
    </body>
    <script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
    <script nomodule src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.js"></script>
    
    <script src="script.js"></script>
    
    </html>
    Login or Signup to reply.
  2. Read this article on pointer events.

    Details are commented in example

    View in Full page mode — Initial display within <iframe> is not rendered correctly

    // Reference .iphone, .lock, and .main
    const iphone = document.querySelector(".iphone");
    const lock = document.querySelector(".lock");
    const main = document.querySelector(".main");
    
    /**
     * Register the "pointerdown" event to .lock
     * Call event handler unlock(e) when event is triggered
     */
    lock.onpointerdown = unlock;
    
    // Event handler passes (e)vent Object by default
    function unlock(e) {
      // Get current height of .iphone in px
      const total = iphone.clientHeight;
      // Define start vertical position coordinate
      const start = e.clientY;
      // Define element registered to event
      const lock = e.currentTarget;
      // Retarget all pointer events to .lock
      lock.setPointerCapture(e.pointerId);
    
      // Register "pointermove" event to .lock
      lock.onpointermove = e => {
        // If user drags up more than 25% of .iphone height...
        let dist = start - e.clientY;
        let perc = (dist / total) * 100;
        if (perc > 25) {
          // ...open .main...
          main.classList.add("open");
          // ...close .lock
          lock.classList.add("close");
        }
      };
    
      // Register "pointerup" event to .lock
      lock.onpointerup = e => {
        // Remove pointer events
        lock.onpointermove = null;
        lock.onpointerup = null;
      };
    };
    @import url('https://fonts.googleapis.com/css2?family=Ubuntu&display=swap');
    
    /**
     * When font-size is defined on <html> element, 1rem will equal
     * the font-size. ex. 1rem = 5vmin
     * 5vmin = 5vh if viewport height is less than viewport width
     * OR 
     * 5vmin = 5vw if viewport width is less than viewport height
     */
    
    :root {
      font: 5vmin/1 'Ubuntu';
    }
    
    .center {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      align-items: center;
    }
    
    .stack {
      flex-flow: column nowrap;
    }
    
    
    /**
     * This is the "frame"
     */
    
    .iphone {
      position: relative;
      width: 27vw;
      height: 95vh;
      margin: auto;
      border: 0.5rem solid black;
      border-radius: 20px;
      color: white;
      background: rgb(43, 87, 124);
      overflow: hidden;
    }
    
    
    /**
     * Both "screens" hide any content that goes beyond it's borders
     */
    
    section {
      overflow: hidden;
    }
    
    time {
      display: block;
      text-align: center;
    }
    
    
    /**
     * This is the lockscreen.
     * It is positioned within the borders of .iphone
     */
    
    .lock {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 95vh;
      background: url(https://w0.peakpx.com/wallpaper/413/669/HD-wallpaper-blue-aesthetic-atmosphere-cloud-new-peace-lockscreen-iphone-android.jpg) no-repeat center;
      background-size: cover;
      /* Initial position for animation */
      transform: translateY(0%);
      /* If transform value changes, this animation activates */
      transition: transform 0.8s ease-in;
    }
    
    .lock header {
      position: absolute;
      top: 10vh;
      width: 100%;
    }
    
    .lock .time {
      font-size: 2.5rem;
    }
    
    
    /**
     * This is the mainscreen.
     * It sits above .iphone, hidden.
     */
    
    .main {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 95vh;
      background: url(https://mcdn.wallpapersafari.com/medium/52/55/Es4tdg.jpg) no-repeat center;
      background-size: cover;
      /* Initial position for animation */
      transform: translateY(-100%);
      /* If transform value changes, this animation activates */
      transition: transform 0.8s ease-in;
    }
    
    .main header {
      position: relative;
      height: 3vh;
      padding: 0.25rem;
      font-size: 0.5rem;
    }
    
    .main .time {
      position: absolute;
      top: 0;
      width: 8vw;
      text-align: center;
    }
    
    .main .notch {
      position: absolute;
      top: 0;
      left: 9vw;
      background-color: black;
      height: 3vh;
      width: 9vw;
      border-bottom-left-radius: 5px;
      border-bottom-right-radius: 5px;
    }
    
    .main .status {
      position: absolute;
      top: 0;
      left: 18vw;
      width: 8vw;
      text-align: center;
    }
    
    .main .status * {
      margin-left: 0.2rem;
    }
    
    .main .apps {
      display: flex;
      flex-flow: row wrap;
      align-content: flex-start;
      width: 24vw;
      min-height: 75vh;
      margin: 2vh auto;
    }
    
    .main .icon {
      display: block;
      min-width: 4.5vw;
      min-height: 4.5vw;
      margin: 0.5rem 0.2rem;
      background: rgba(255, 255, 255, 0.3);
      border-radius: 4px;
    }
    
    .main footer {
      position: absolute;
      bottom: 0;
      width: 100%;
      height: 20vh;
    }
    
    .main nav {
      position: absolute;
      top: 0;
      width: 100%;
      height: 3vw;
    }
    
    .main menu {
      list-style: none;
      padding: 0;
      margin-left: 0;
    }
    
    .main li {
      width: 0.25rem;
      height: 0.25rem;
      margin: 0 0.25rem;
      border: 2px solid white;
      border-radius: 50%;
    }
    
    .main .active {
      background: white
    }
    
    .main .control {
      position: absolute;
      top: 2vh;
      width: 24vw;
      margin-left: 0;
      padding: 0.25rem;
      background: rgba(255, 255, 255, 0.2);
      border-radius: 8px;
    }
    
    .main .control .icon {
      min-width: 5vw;
      min-height: 5vw;
      margin: 0.25rem;
    }
    
    .time::before {
      content: attr(data-time);
    }
    
    .date::before {
      content: attr(data-date);
    }
    
    .open {
      transform: translateY(0%);
    }
    
    .close {
      transform: translateY(-100%);
    }
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Iphone Mockup</title>
      <!-- 
        Only one <link> is needed to use Font-Awesome 
      -->
      <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
      <!-- 
        The custom CSS can be placed within <style> OR in a external stylesheet using 
        <link href="file.css"> 
      -->
      <style></style>
    </head>
    
    <body>
      <div class="iphone">
        <!-- 
          Lockscreen 
        -->
        <section class="lock">
          <header class="center stack">
            <time class="time" data-time="1:45 AM"></time>
            <time class="date" data-date="August 26, 2023"></time>
          </header>
        </section>
        <!-- 
          Mainscreen 
        -->
        <section class="main">
          <header>
            <time class="time" data-time="1:45 AM"></time>
            <div class="notch"></div>
            <div class="status">
              <i class="fas fa-signal"></i>
              <b>5G</b>
              <i class="fas fa-battery"></i>
            </div>
          </header>
          <main class="apps">
            <ion-icon name="aperture" class="icon center"></ion-icon>
            <ion-icon name="basketball" class="icon center"></ion-icon>
            <ion-icon name="baseball" class="icon center"></ion-icon>
            <ion-icon name="rocket" class="icon center"></ion-icon>
            <ion-icon name="trophy" class="icon center"></ion-icon>
            <ion-icon name="logo-pinterest" class="icon center"></ion-icon>
            <ion-icon name="logo-chrome" class="icon center"></ion-icon>
          </main>
          <footer class="center stack">
            <nav class="center">
              <menu class="center">
                <li class="active">&nbsp;</li>
                <li>&nbsp;</li>
                <li>&nbsp;</li>
              </menu>
            </nav>
            <menu class="center control">
              <ion-icon name="call" class="icon center"></ion-icon>
              <ion-icon name="flashlight" class="icon center"></ion-icon>
              <ion-icon name="camera" class="icon center"></ion-icon>
              <ion-icon name="compass" class="icon center"></ion-icon>
            </menu>
          </footer>
        </section>
      </div>
      <!-- 
        <script> should be before end tag of </body>, not after it 
      -->
      <script type="module" src="https://unpkg.com/[email protected]/dist/ionicons/ionicons.esm.js"></script>
      <!-- 
        Custom JavaScript can be placed within <script> OR in an external .JS file using 
        <script src="file.js"> 
      -->
      <script></script>
    </body>
    
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search