Приложение для чтения - пример html js css



Книга Приложение для чтения

Приложение для чтения (HTML код)


<div class="container">

    <div class="status-bar">
      
      <span class="status-bar__clock" onload="showTime()"></span>

      <div>

        <img class="status-bar__img img" src="https://utopian-drink.surge.sh/images/icon/status-bar.svg" alt="status-bar">

      </div>

    </div>

    <header class="header">
      
      <div class="header__context">

        <h1 class="header__title">browse</h1>
        <b class="header__text">recommended</b>

      </div>

      <nav class="tabbar">

        <ul class="tabbar__list list">

          <li class="tabbar__item">history</li>
          <li class="tabbar__item">classical</li>
          <li class="tabbar__item active">biography</li>
          <li class="tabbar__item">cartoon</li>
          <li class="tabbar__item">fantasy</li>
          <li class="tabbar__item">drama</li>
          <li class="tabbar__item">memoir</li>
          <li class="tabbar__item">self help</li>

        </ul>

      </nav>

    </header>

    <div class="global-button global-button--position-ab flex">
          
      <button class="global-button__back">

        <img class="img" src="https://utopian-drink.surge.sh/images/icon/back.svg" alt="icon-back">

      </button>
      
      <button> 

        <img class="img" src="https://utopian-drink.surge.sh/images/icon/menu.svg" alt="icon-menu">

      </button>

    </div>

    <main class="main">
      
      <ul class="product-card list"></ul>

    </main>

  </div>

Приложение для чтения (CSS код)



@import url('https://fonts.googleapis.com/css2?family=Kumbh+Sans&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Rubik&display=swap');

html {

    box-sizing: border-box ;
    --padding-left: 1.25em ;
    --duration-header: .25s ;
    --duration-product-item: .5s ;

}

html *,
html *::before,
html *::after {

    box-sizing: inherit ;
    scrollbar-width: none ;
}

@media (max-width: 26.875em) {
    
    html {

        --none: none ;
        --top-start: 4.99em ;
        --top-end: 2.08em ;
    }

}

body{
    
    margin: 0 ;
    display: flex ;
    user-select: none ;
    align-items: center ;
    justify-content: center ;
    background-color: #dadfea ;
    font-family: 'Kumbh Sans', sans-serif ;
    -webkit-tap-highlight-color: transparent ;

} 

::-webkit-scrollbar{

    width: 0 ;
    height:  0 ;

}

.list {

    margin: 0 ;
    padding: 0 ;
    list-style-type: none ;

}

.img {
    
    width: 100% ;
    display: block ;
    object-fit: cover ;
    position: relative ;
    
}

.img::after{

    top: 0 ;
    left: 0 ;
    content: "" ;
    width: 100% ;
    height: 100% ;
    position: absolute ;
    background-color: white ;
    
}

.flex {

    display: flex ;
    align-items: center ;
    justify-content: space-between ;

}

button {

    all: unset ;
    font: inherit ;
    cursor: pointer ;

}

.container {

    width: 100% ;
    height: 100% ;
    display: flex ;
    overflow: hidden ;
    font-size: 6.4vw ;
    position: relative ;
    flex-direction: column ;
    background-color: white ;
    border-radius: var(--none, 1.3em ) ;
    border: var(--none, 0.45em solid black) ;
    
}

.container::before {

    right: 0 ;
    bottom: 0 ;
    opacity: 0 ;
    content: " " ;
    position: absolute ;
    pointer-events: none ;
    transition: opacity .2s ;
    height: calc(100% - 4.81em) ;
    background-color: #f8f9fc ;
    width: calc(100% - var(--padding-left)) ;

}

@media (min-width: 26.875em) {
    
    .container {
        
        font-size: 1em ;
        width: 15.0375em ;
        height: 31.84em ;
        
    }

    .container::before {

        height: 80.2% ;
        

    }

}


.container.active::before{

    opacity: 1 ;
    z-index: 100 ;
    
}

.status-bar {

    display: var(--none, flex) ;
    padding: .3em .25em 0 .95em ;
    justify-content: space-between ;
    

}

.status-bar__clock {

    font-size: .53em ;
    font-weight: bold ;
    letter-spacing: .075em ; 
    font-family: 'Rubik', sans-serif ;

}

.status-bar__img {

    width: 2.85em ;

}

.header {

    padding: 1.15em 0 .25em var(--padding-left) ;
    transition: height, var(--duration-header), padding var(--duration-header), transform var(--duration-header), opacity var(--duration-header);

}

.header.hide {
    
    height: 0 ;
    opacity: 0 ;
    padding-top: 0 ;
    padding-bottom: 0 ;
    pointer-events: none ;
    transform: translate3d(0, -5%, 0) ;

}

.header__context {

    display: flex ;
    font-size: .6em ;
    align-items: baseline ;
    text-transform: capitalize ;

}

.header__title {

    margin: 0 .8em 0 0 ;
    letter-spacing: 0.03em ;

}

.header__text {

    color: #414141b4 ;

}

.tabbar {

    overflow: hidden ;

}

.tabbar__list {

    overflow: auto ;
    cursor: pointer ;
    white-space: nowrap ;
    padding: .6em 1.2em .6em 0 ;


}

.tabbar__item {

    font-size: .41em ;
    color: #9e9fa2 ;
    border-radius: 2em ;
    display: inline-flex ;
    justify-content: center ;
    padding: .75em 1.2em .4em ;
    text-transform: capitalize ;
    background-color: #f0f1f4 ; 
    pointer-events: var(--pointer-event) ;

}

.tabbar__item:not(:first-of-type) {

    margin-left: .5em ;

}

.tabbar__item.active {

    color: #f1f1f1 ;
    background-color: #1469fc ;

}

.global-button {

    opacity: 0 ;
    width: 100% ;
    pointer-events: none ;
    padding: .55em 1em 0 .8em ;

}

.global-button--position-ab {

    top: .5% ;
    position: absolute ;

}

@media (min-width: 26.875em) {
    
    .global-button--position-ab {

        top: 4.6% ;
    
    }

}


.global-button > * {

    width: 1em ;
    height: 1em ;

}

.global-button.show {
    
    opacity: 1 ;
    pointer-events: initial ;

}

.main {

    height: 100% ;
    font-size: 1.1em ;
    touch-action: none ;
    overflow: hidden auto ;
    overscroll-behavior: contain ;

}

@media (min-width: 26.875em) {
    
    .main {
        
        font-size: 1em ;
        
    }

}

.product-card {

    height: var(--productCardHeight) ;
    padding-left: var(--padding-left) ;

}

.product-card__item {
    
    width: 100% ;
    display: flex ;
    height: 9.92em ;
    align-items: center ;
    max-height: var(--max-height-item) ;
    pointer-events: var(--pointer-event) ;
    transform: var(--transform, perspective(1000px) rotateX(0)) ;
    transition: height var(--duration-product-item), margin var(--timeOut, calc( var(--duration-product-item) / 1.5 )) ;
    
}

.product-card__img {

    width: 6.55em ;
    height: 8.75em ;
    overflow: hidden ;
    position: absolute ;
    border-radius: .3em ;
    pointer-events: none ;
    transform: translate3d(80%, 0, 0) ;
    transition: border-radius var(--duration-product-item) ;
    box-shadow: 0.3125em 0.3125em 0.875em -0.1875em #403e3e4f ;

}

.product-card__item.active {

    height: 100% ;
    padding-top: 3em ;
    align-items: unset ;
    margin-bottom: 1.5em ;
    flex-direction: column ;

}

@media (min-width: 26.875em) {

    .product-card__item.active {

        padding-top: 3.55em ;

    }

} 


.product-card__item.active .product-card__img {
    
    z-index: 200 ;
    cursor: pointer ;
    pointer-events: initial ;
    
} 

.product-card__img.move-img {

    border-radius: 0 .3em .3em 0 ;
    animation: product-card-img-move var(--duration-product-item) forwards ;

}

@keyframes product-card-img-move {

    0%, 20%{

        top: var(--top-start, 20.5%) ;

    }

    80% ,100%{

        top: var(--top-end, 12.8%) ;
        transform: translate3d(-20%, 0, 0);
        
    }

}

.product-card__img.back-img {

    border-radius: .3em ;
    animation: product-card-img-back var(--duration-product-item) forwards ;

}

@keyframes product-card-img-back {

    0%, 15%{

        top: var(--top-end, 12.8%) ;
        transform: translate3d(-20%, 0, 0);

    }

    50% ,100%{

        top: var(--top-start, 20.5%) ;
        
    }

    
}

.product-card__content {

    width: 6em ;
    z-index: 50 ;
    height: 6.88em ;
    cursor: pointer ;
    overflow: hidden ;
    border-radius: .25em ;
    will-change : transform ;
    background-color: white ;
    text-transform: capitalize ;
    box-shadow: -2px 6px 15px 0px #2f2f2f24 ;
    transition: opacity calc(var(--duration-product-item) / 2) ;

} 

.product-card__content.open-content {

    width: 100% ;
    height: 100% ;
    z-index: 150 ;
    cursor: initial ;
    box-shadow: none ;
    padding-left: 1.05em ;
    pointer-events: initial ;
    background-color: unset ;
    transform: translate3d(0, 180%, 0) ;
    animation: open-content var(--duration-product-item) forwards,
    opacity-content calc(var(--duration-product-item) * 2) forwards ;

}

@keyframes open-content {
    
    100%{

        transform:  none ;

    }

}

@keyframes opacity-content {
    
    0%{
        
        opacity: 0;
    }
    
    100%{
        
        opacity: 1;


    }

}

.product-card__info {

    padding: .82em .7em ;

}

.product-card__content.open-content .product-card__info {

    width: 63% ;
    margin-left: auto ;
    padding: .8em .7em ;

}

.product-card__product-name {

    margin: 0 0 .2em ;
    line-height: 1.4 ;
    font-size: .63em ;
    min-height: 2.778em ;
    white-space: pre-line ;

}

.product-card__content.open-content .product-card__product-name {

    font-size: .78em ;
    line-height: 1.5 ;
    margin-bottom: .8em ;
    letter-spacing: .03em ;

}

.product-card__product-author {

    font-size: .4em ;
    font-weight: bold ;
    color: #00000073 ;
    letter-spacing: -.01em ;

}

.product-card__content.open-content .product-card__product-author {

    font-size: .55em ;

}

.product-card__rank {

    display: flex ;
    align-items: center ;
    margin: .8em 0 .75em ;

}

.product-card__content.open-content .product-card__rank {

    width: 0 ;
    overflow: hidden ;
    margin: 1.2em 0 0 ;
    animation: show-rank var(--duration-product-item) var(--duration-product-item) forwards ;
    
}

@keyframes show-rank {
    
    100%{

        width: 100% ;

    }

}

.product-card__starts {

    position: relative ;

}

.product-card__starts::after {

    right: 0 ;
    content: "" ;
    height: 100% ;
    width: var(--rank) ;
    position: absolute ;
    background-color: #ffffffc2 ;

}

.product-card__content.open-content .product-card__starts::after {

    background-color: #f8f9fcc9 ;
    
}

.product-card__start-icon {

    width: .5em ;
    height: .5em ;
    flex-shrink: 0 ;
    margin-right: .1em ;

}

.product-card__content.open-content .product-card__start-icon {

    animation: show-star var(--duration-product-item) var(--duration-product-item) forwards ;

}

@keyframes show-star {
    
    0% {

        transform: scale(0) ;

    }

    100%{

        transform: scale(1) ;

    }

}

.product-card__rank-number {

    font-size: .5em ;
    color: #ffb964 ;
    font-weight: bold ;
    margin-left: .15em ;
    margin-bottom: -.3em ;
    letter-spacing: .05em ;

}

.product-card__view {

    display: flex ;
    font-size: .45em ;
    font-weight: bold ;
    color: #00000059 ;
    position: relative ;
    align-items: center ;

}

.product-card__view.hide{

    display: none ;

}

.product-card__view::after {
    
    right: 4% ;
    opacity: .2 ;
    width: 1.6em ;
    content: " " ;
    height: 1.6em ;
    position: absolute ;
    transform: rotate(180deg) ;
    background-position: center ;
    background-repeat: no-repeat ;
    background-image: url(http://utopian-drink.surge.sh/images/icon/back.svg) ;

}

.product-card__view-number {

    color: #408cff ;
    margin-right: .45em ;

}

.product-card__view-value{

    font-size: .45em ;
    color:#00000059 ;
    margin: 0 0 -.3em .8em ;

}

.product-card__view-value.hide{

    display: none ;

}

.product-card__buttons {

    width: 100% ;
    margin-top: 2.8em ;
    font-size: 0.45em ; 
    color: #000000d9 ;
    will-change: transform ;
    padding: 0 1.6em 2.4em 0 ;
    border-bottom: .2em solid #c3c3c31f ;

}

@media (max-width: 26.875em) {

    .product-card__buttons {

        margin-top: 1.8em ;
        padding: 0 1.6em 1.4em 0 ;

    }

}    

.product-card__button-icon {

    width: 1.6em ;
    margin-right: .8em ;

}

.product-card__button-text {

    margin: .5em 0 0 ;

}

.product-card__context {

    height: 100% ;
    overflow: hidden ;
    font-size: .52em ;
    padding: 1.2em 0 0 ;
    text-transform: none ;

}

.product-card__context ::first-letter{

    text-transform: capitalize ;

}

.product-card__description {

    overflow: auto ;
    line-height: 1.9 ;
    margin: 1.6em 0 0 ;
    color: #969696a8 ;
    padding-right: 2.15em ;
    pointer-events: initial ;
    height: calc(100% - 23.2em) ;

}

@media (min-width: 26.875em) {

    .product-card__description {

        overflow: hidden ;

    }

} 

.product-card__content.open-content .product-card__description {
    
    transform: translate3d(0, 12%, 0) ;
    animation: description var(--duration-product-item) calc(var(--duration-product-item) / 2) forwards;

}

@keyframes description {
    
    100% {

        transform: translate3d(0, 0, 0) ;

    }

}

.product-card__cta {

    opacity: 0 ;
    z-index: 300 ;
    color: white ;
    font-size: .55em ;
    margin-left: auto ;
    pointer-events: none ;
    letter-spacing: 0.1em ;
    text-transform: capitalize ;
    background-color: #1368fa ;
    padding: 1.7em 1.5em 1em 1.9em ;
    
}

.product-card__item.active  .product-card__cta {
    
    opacity: 1 ;
    pointer-events: initial ;
    transition: opacity calc(var(--duration-product-item) / 2) var(--duration-product-item) ;

}


Приложение для чтения (JS код)



// Designed by: Crank 
// Original image: https://dribbble.com/shots/5707503-Reading-Application?utm_source=Pinterest_Shot&utm_campaign=crankwh&utm_content=Reading%20Application&utm_medium=Social_Share

"use strict";

gsap.registerPlugin(ScrollTrigger);

let info;
let genre;
const request = "https://www.json-generator.com/api/json/get/cqyGXnDfjC?indent=2";
const html = document.documentElement;
const container = document.querySelector(".container");
const tabbarList = document.querySelector(".tabbar__list");
const main = container.querySelector(".main");
const productCard = main.querySelector(".product-card");
let productCardItems;
const header = document.querySelector(".header");
const time = parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--duration-header")) * 1000;
const globalButton = document.querySelector(".global-button");
const globalButtonBack = globalButton.querySelector(".global-button__back");
let elements;
let activeItem;
let isMove = false;
let startY;
let scrollTop;
let startX;
let scrollLeft;
let tabbarItemActive = tabbarList.querySelector(".tabbar__item.active");
const statusBar = document.querySelector(".status-bar");
const statusBarClock = document.querySelector(".status-bar__clock");
let progressScroll = 0;
let notScroll = false;

fetch(request).
then(response => response.json()).
then(item => {
  info = item;
  booksGenre(info);
  setMaxHeight();
});

function setMaxHeight() {

  document.body.style.height = window.innerHeight + "px";
  const maxHeightItem = container.clientHeight - globalButton.offsetHeight - statusBar.offsetHeight;
  html.style.setProperty("--max-height-item", `${maxHeightItem}px`);
  html.style.setProperty("--height-body", `${window.innerHeight}px`);
}

function booksGenre(info) {

  const key = tabbarItemActive.textContent;
  genre = info[key];

  if (!genre) return;
  productCard.innerHTML = "";
  genre.forEach(book => {

    book.rank = `${book.rank}`.replace(/^\d$/, "$&.0");
    const width = 100 - book.rank * 20;

    book.keywords.forEach(word => {

      const regex = new RegExp(`${word}`, `i`);
      book.description = book.description.replace(regex, `${word}`);

    });

    productCard.insertAdjacentHTML("beforeend", creatBook(book, width));

  });

  productCardItems = Array.from(productCard.children);
  const productCardHeight = (genre.length + 3) * productCard.firstElementChild.offsetHeight;
  html.style.setProperty("--productCardHeight", `${productCardHeight}px`);

  main.scrollTop = 0;

  ScrollTrigger.getAll().forEach(item => {
    item.kill();
  });

  roll(productCardItems);

}

function creatBook(book, width) {

  const { picture, name, author, rank, view, description } = book;

  return `
    
  • book

    ${name}

    ${author}
    star-icon star-icon star-icon star-icon star-icon
    ${rank} (${view})

    ${view}

    views

    about the book

    ${description}

  • `; } function openProductCard(e, productCardItems) { const target = e.target; activeItem = target.closest(".product-card__item"); if (target.closest(".product-card__img")) { activeItem.classList.remove("active"); closeProductCard(elements); return; } if (!target.closest(".product-card__content")) return; const indexActiveItem = productCardItems.findIndex(item => item == activeItem); notScroll = true; main.scrollTo(0, indexActiveItem * productCardItems[0].offsetHeight); const productCardWrapperImg = activeItem.querySelector(".product-card__img"); const productCardContent = activeItem.querySelector(".product-card__content"); const productCardView = productCardContent.querySelector(".product-card__view"); const productCardViewValue = productCardContent.querySelector(".product-card__view-value"); elements = [ activeItem, productCardWrapperImg, productCardContent, productCard, header, container, productCardView, productCardViewValue]; header.classList.add("hide"); if (header.classList.contains("hide")) { productCard.style.paddingTop = `${globalButton.offsetHeight}px`; } activeItem.style.cssText = ` --timeOut : 0s; --transform : none; `; main.style.cssText = ` pointer-events : none; overflow: hidden; `; container.classList.add("active"); productCardView.classList.add("hide"); productCardViewValue.classList.remove("hide"); productCardContent.classList.add("open-content"); productCardWrapperImg.classList.add("move-img"); activeItem.classList.add("active"); } function closeProductCard(elements) { const [ activeItem, productCardWrapperImg, productCardContent, productCard, header, container, productCardView, productCardViewValue] = elements; if (!activeItem.classList.contains("active")) { productCardWrapperImg.classList.add("back-img"); productCardContent.classList.remove("open-content"); container.classList.remove("active"); productCardView.classList.remove("hide"); productCardViewValue.classList.add("hide"); productCardContent.style.opacity = 0; setTimeout(() => { productCard.style = ""; header.classList.remove("hide"); }, time); } productCardWrapperImg.addEventListener("animationend", function (e) { if (e.animationName.includes("img-back")) { productCardItems.forEach(item => { item.style.removeProperty("--timeOut"); item.classList.remove("hide"); }); this.classList.remove("move-img", "back-img"); productCardContent.style = ""; main.style = ""; activeItem.style = ""; } }); } function showTime() { const date = new Date(); let hours = date.getHours(); let minutes = date.getMinutes(); if (hours == 0) { hours = 12; } if (hours > 12) { hours = hours - 12; } hours = hours < 10 ? "0" + hours : hours; minutes = minutes < 10 ? "0" + minutes : minutes; statusBarClock.textContent = `${hours}:${minutes}`; setTimeout(showTime, 1000); }; showTime(); tabbarList.addEventListener("click", function (e) { if (tabbarItemActive == e.target) return; if (e.target.tagName != "LI") return; tabbarItemActive = e.target; booksGenre(info); if (!genre) return; tabbarItemActive.classList.add("active"); gsap.to(".product-card__content", { duration: .4, rotationY: -180, scaleX: -1 }); gsap.fromTo(".product-card__img", { duration: .75, filter: "brightness(.5)" }, { duration: .75, filter: "brightness(1)" }); gsap.to(".product-card__content", { clearProps: "all" }); tabbarList.querySelectorAll(".tabbar__item").forEach(item => { if (item != tabbarItemActive) { item.classList.remove("active"); } }); }); tabbarList.addEventListener("pointerdown", function (e) { isMove = true; startX = Math.floor(e.pageX - this.getBoundingClientRect().left); scrollLeft = this.scrollLeft; }); tabbarList.addEventListener("pointermove", function (e) { if (!isMove) return; this.style.cssText = ` --pointer-event: none; cursor : grabbing; `; const lastX = Math.floor(e.pageX - this.getBoundingClientRect().left); const walk = lastX - startX; this.scrollLeft = scrollLeft - walk; }); tabbarList.addEventListener("pointerup", function () { isMove = false; this.style = ""; }); tabbarList.addEventListener("pointerleave", function () { isMove = false; this.style = ""; }); header.addEventListener("transitionend", function () { if (this.classList.contains("hide")) { globalButton.classList.add("show"); } }); header.addEventListener("transitionstart", () => { globalButton.classList.remove("show"); }); globalButtonBack.addEventListener("click", () => { activeItem.classList.remove("active"); closeProductCard(elements); }); productCard.addEventListener("click", e => openProductCard(e, productCardItems)); function roll(productCardItems) { productCardItems.forEach((item, index) => { gsap.set(item, { transformPerspective: 1000 }); const animation = gsap.to(item, { rotationX: 95, y: 70, opacity: 0 }); ScrollTrigger.create({ animation: animation, trigger: item, scroller: main, start: `top+=5 top`, end: `bottom-=5 top`, scrub: true, onEnter: progress => { progressScroll = progress.end + 5; }, onLeaveBack: progress => { progressScroll = progress.start - 5; }, onEnterBack: progress => { progressScroll = progress.start - 5; }, onUpdate: ({ direction, isActive }) => { productCardItems.forEach(item => { if (index == productCardItems.length - 1) return; if (isActive) item.style.marginBottom = direction * .25 + "em";else item.style.removeProperty("margin-bottom"); }); } }); }); } function scrollInMain() { if (notScroll) return; main.scroll({ top: progressScroll, behavior: "smooth" }); } main.addEventListener("pointerdown", function (e) { if (activeItem && activeItem.classList.contains("active")) return; isMove = true; startY = Math.floor(e.pageY - this.getBoundingClientRect().top); scrollTop = this.scrollTop; }); main.addEventListener("pointermove", function (e) { if (!isMove) return; notScroll = false; const lastY = Math.floor(e.pageY - this.getBoundingClientRect().top); const walk = lastY - startY; this.scrollTop = scrollTop - walk; this.style.setProperty("--pointer-event", "none"); }); main.addEventListener("pointerup", function () { isMove = false; this.style.removeProperty("--pointer-event"); scrollInMain(); }); main.addEventListener("pointerleave", function () { isMove = false; this.style.removeProperty("--pointer-event"); }); window.addEventListener("resize", setMaxHeight); document.ondragstart = () => { return false; }; //# sourceURL=pen.js

    Приложение для чтения (Результат кода)

    88   0  
      Ничего не найдено.

    Добавить ответ:
    Отменить.