Share two sets of different 3D VR cards

Recently, a lot of VR videos have appeared on Xingyin. Turning the phone, you can see scenes that are not displayed on the phone interface. I think we can do this too.

So two different 3D VR cards are coming:

The first is that it can be dragged a great distance horizontally or up and down. The information on the card will move with the dragging, but no more information will be displayed:
insert image description here
the second is that the horizontal or vertical dragging distance is limited. But the information displayed on the card can express more.
insert image description here
Of course, capable students can combine the two or modify them to make them meet your needs~

The following are the source codes of two different cards, for students in need~

The first:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  <style>
    @import url(https://fonts.googleapis.com/css?family=Roboto);
    html, body {
      
      
      font-family: "Roboto", sans-serif;
      height: 100%;
    }

    body {
      
      
      background: linear-gradient(to bottom, #ddd 0%, #f0f0f0 40%);
      transform-style: preserve-3d;
      transform: perspective(800px);
      background-image: url(data:image/png;base64,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);
    }

    .wrap {
      
      
      position: absolute;
      perspective: 600px;
      height: 100%;
      width: 100%;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      overflow: hidden;
      text-align: center;
    }

    .card-shadow, .card {
      
      
      margin: 0 auto;
      margin-top: 100px;
      width: 300px;
      height: 450px;
      z-index: 1;
      position: absolute;
      border-radius: 10px;
      top: 0px;
      bottom: 0px;
      left: 0px;
      right: 0px;
    }

    .card {
      
      
      background: #fff url("https://images.unsplash.com/photo-1441716844725-09cedc13a4e7?fit=crop&fm=jpg&h=950&q=80&w=1925") 50% 50%;
      background-size: 450%;
    }

    .card-shine {
      
      
      position: absolute;
      width: 100%;
      height: 100%;
      transform-style: preserve-3d;
      z-index: 1;
      border-radius: 10px;
      background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 60%);
      z-index: -1;
    }

    .card-shadow {
      
      
      top: 10px;
      transform-style: preserve-3d;
      transform: translateZ(40px);
      z-index: -1;
      background: #B3B3B3;
      transform: scale(0.5, 0.5);
      box-shadow: 0 0 30px 10px #aaa;
    }

    .card-front, .card-title, .card-subtitle {
      
      
      position: absolute;
      color: #FFF;
      transform-style: preserve-3d;
    }

    .card-front {
      
      
      border-radius: 10px;
      width: 100%;
      height: 100%;
      z-index: 0;
      background-color: rgba(0, 0, 0, 0.1);
    }

    .card-title {
      
      
      font-weight: 700;
      text-align: left;
      left: 30px;
      bottom: 140px;
      font-size: 35px;
      line-height: 30px;
      text-shadow: 0 5px 8px rgba(0, 0, 0, 0.65);
      transform: translateZ(0px);
      overflow: hidden;
      margin: 0;
      width: 80%;
    }

    .card-subtitle {
      
      
      font-weight: normal;
      text-align: left;
      left: 30px;
      width: 80%;
      bottom: 80px;
      font-size: 25px;
      line-height: 20px;
      text-shadow: 0 3px 6px rgba(0, 0, 0, 0.8);
      transform: translateZ(0px);
    }
  </style>
</head>
<body>
<div class='wrap'>
  <div class='card-shadow'></div>
  <div class='card'>
    <div class='card-front'>
      <div class='card-title'>3D perspective title</div>
      <div class='card-subtitle'>3D perspective subtitle</div>
      <div class='card-shine'></div>
    </div>
  </div>
</div>
</body>
<script>
  var
          $card = $('.card'),
          $cardTitle = $('.card-title'),
          $cardSubtitle = $('.card-subtitle'),
          $cardShine = $('.card-shine'),
          $cardShadow = $('.card-shadow'),
          currentMousePos = {
      
       x: 0, y: 0 },
          mouseFromCenter = {
      
       x: 0, y: 0 };

  $(document).mousemove(function(event) {
      
      
    var
            wHeight= $(window).height(),
            wWidth= $(window).width();

    currentMousePos.x = event.pageX;
    currentMousePos.y = event.pageY;
    mouseFromCenter.x = currentMousePos.x - (wWidth / 2);
    mouseFromCenter.y = currentMousePos.y - (wHeight / 2);

    var
            around1 = -1 * (currentMousePos.y * 100 / wHeight * 0.2 - 10) + 'deg',
            around2 = 1 * (currentMousePos.x * 100 / wWidth * 0.2 - 10) + 'deg',
            trans1 = (currentMousePos.x * 100 / wHeight * 0.3 ) + 'px',
            trans2 = (currentMousePos.y * 100 / wHeight * 0.3 ) + 'px',
            dy = event.pageY - wHeight / 2, //@h/2 = center of poster
            dx = event.pageX - wWidth / 2, //@w/2 = center of poster
            theta = Math.atan2(dy, dx), // angle between cursor and center of poster in RAD
            angle = theta * 180 / Math.PI - 90,
            mousePositionX = ( currentMousePos.x / wWidth) * 100,
            mousePositionY = 50+( currentMousePos.y / wHeight)*10;

    // gradient angle and opacity for card shine effect
    $cardShine.css('background', 'linear-gradient(' + angle + 'deg, rgba(255,255,255,' + (currentMousePos.y / wHeight) * .7 + ') 0%,rgba(255,255,255, 0) 80%)');
    // card pos and angle
    $card.css({
      
      
      "-webkit-transform": "translate3d(" + trans1 + ", " + trans2 +", 0) scale(1) rotatex(" + around1 + ") rotatey(" + around2 + ")",'background-position': mousePositionX + '%' + ' ' + (currentMousePos.y / wHeight) * 50  + '%'
    });
    // card shadow pos and angle
    $cardShadow.css({
      
      "transform": "scale(.9,.9) translateX(" + ((mouseFromCenter.x * -0.02) + 12) + "px) translateY(" + ((mouseFromCenter.y * -0.02) + 12 ) + "px) scale(1.0) rotateY(" + (mouseFromCenter.x / 25) * 0.5 + "deg) rotateX(" + ((mouseFromCenter.y / -25) ) + "deg)" });

    $cardTitle.css({
      
      "transform": "translateX(" + ((mouseFromCenter.x / 25) * 0.7) + "px) translateY(" + ((mouseFromCenter.y / 25) * 1.65) + "px)"
    });

    $cardSubtitle.css({
      
      "transform": "translateX(" + ((mouseFromCenter.x / 25) * 0.5) + "px) translateY(" + ((mouseFromCenter.y / 25) * 1.15) + "px) translateZ(60px)"
    });
  });
</script>
</html>

The second type:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.1/vue.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Playfair+Display:700|Raleway:500.700">
    <style>
        body {
      
      
            margin: 40px 0;
            font-family: "Raleway";
            font-size: 14px;
            font-weight: 500;
            background-color: #BCAAA4;
            -webkit-font-smoothing: antialiased;
        }

        .title {
      
      
            font-family: "Raleway";
            font-size: 24px;
            font-weight: 700;
            color: #5D4037;
            text-align: center;
        }

        p {
      
      
            line-height: 1.5em;
        }

        h1 + p, p + p {
      
      
            margin-top: 10px;
        }

        .container {
      
      
            padding: 40px 80px;
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
        }

        .card-wrap {
      
      
            margin: 10px;
            transform: perspective(800px);
            transform-style: preserve-3d;
            cursor: pointer;
        }
        .card-wrap:hover .card-info {
      
      
            transform: translateY(0);
        }
        .card-wrap:hover .card-info p {
      
      
            opacity: 1;
        }
        .card-wrap:hover .card-info, .card-wrap:hover .card-info p {
      
      
            transition: 0.6s cubic-bezier(0.23, 1, 0.32, 1);
        }
        .card-wrap:hover .card-info:after {
      
      
            transition: 5s cubic-bezier(0.23, 1, 0.32, 1);
            opacity: 1;
            transform: translateY(0);
        }
        .card-wrap:hover .card-bg {
      
      
            transition: 0.6s cubic-bezier(0.23, 1, 0.32, 1), opacity 5s cubic-bezier(0.23, 1, 0.32, 1);
            opacity: 0.8;
        }
        .card-wrap:hover .card {
      
      
            transition: 0.6s cubic-bezier(0.23, 1, 0.32, 1), box-shadow 2s cubic-bezier(0.23, 1, 0.32, 1);
            box-shadow: rgba(255, 255, 255, 0.2) 0 0 40px 5px, white 0 0 0 1px, rgba(0, 0, 0, 0.66) 0 30px 60px 0, inset #333 0 0 0 5px, inset white 0 0 0 6px;
        }

        .card {
      
      
            position: relative;
            flex: 0 0 240px;
            width: 240px;
            height: 320px;
            background-color: #333;
            overflow: hidden;
            border-radius: 10px;
            box-shadow: rgba(0, 0, 0, 0.66) 0 30px 60px 0, inset #333 0 0 0 5px, inset rgba(255, 255, 255, 0.5) 0 0 0 6px;
            transition: 1s cubic-bezier(0.445, 0.05, 0.55, 0.95);
        }

        .card-bg {
      
      
            opacity: 0.5;
            position: absolute;
            top: -20px;
            left: -20px;
            width: 100%;
            height: 100%;
            padding: 20px;
            background-repeat: no-repeat;
            background-position: center;
            background-size: cover;
            transition: 1s cubic-bezier(0.445, 0.05, 0.55, 0.95), opacity 5s 1s cubic-bezier(0.445, 0.05, 0.55, 0.95);
            pointer-events: none;
        }

        .card-info {
      
      
            padding: 20px;
            position: absolute;
            bottom: 0;
            color: #fff;
            transform: translateY(40%);
            transition: 0.6s 1.6s cubic-bezier(0.215, 0.61, 0.355, 1);
        }
        .card-info p {
      
      
            opacity: 0;
            text-shadow: black 0 2px 3px;
            transition: 0.6s 1.6s cubic-bezier(0.215, 0.61, 0.355, 1);
        }
        .card-info * {
      
      
            position: relative;
            z-index: 1;
        }
        .card-info:after {
      
      
            content: "";
            position: absolute;
            top: 0;
            left: 0;
            z-index: 0;
            width: 100%;
            height: 100%;
            background-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.6) 100%);
            background-blend-mode: overlay;
            opacity: 0;
            transform: translateY(100%);
            transition: 5s 1s cubic-bezier(0.445, 0.05, 0.55, 0.95);
        }

        .card-info h1 {
      
      
            font-family: "Playfair Display";
            font-size: 36px;
            font-weight: 700;
            text-shadow: rgba(0, 0, 0, 0.5) 0 10px 10px;
        }

        .Original{
      
      
            position: fixed;
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 20% 0 0 80%;
            width: 100%;
            z-index: 3;
            height: 7em;
            font-family: "Bebas Neue", sans-serif;
            font-size: clamp(0.66rem, 2vw, 1rem);
            letter-spacing: 0.5em;
        }

        a{
      
      
            color: black;
            text-decoration: none;
        }
    </style>
</head>
<body>
<h1 class="title">Hover over the cards</h1>
<div id="app" class="container">
    <card data-image="https://images.unsplash.com/photo-1479660656269-197ebb83b540?dpr=2&auto=compress,format&fit=crop&w=1199&h=798&q=80&cs=tinysrgb&crop=">
        <h1 slot="header">Canyons</h1>
        <p slot="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </card>
    <card data-image="https://images.unsplash.com/photo-1479659929431-4342107adfc1?dpr=2&auto=compress,format&fit=crop&w=1199&h=799&q=80&cs=tinysrgb&crop=">
        <h1 slot="header">Beaches</h1>
        <p slot="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </card>
    <card data-image="https://images.unsplash.com/photo-1479644025832-60dabb8be2a1?dpr=2&auto=compress,format&fit=crop&w=1199&h=799&q=80&cs=tinysrgb&crop=">
        <h1 slot="header">Trees</h1>
        <p slot="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </card>
    <card data-image="https://images.unsplash.com/photo-1479621051492-5a6f9bd9e51a?dpr=2&auto=compress,format&fit=crop&w=1199&h=811&q=80&cs=tinysrgb&crop=">
        <h1 slot="header">Lakes</h1>
        <p slot="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
    </card>
</div>
<div class="Original"><a href="https://blog.csdn.net/qq_35241329?type=blog">Original By TiMi先生</a></div>
</body>
<script>
    Vue.config.devtools = true;

    Vue.component('card', {
      
      
        template: `
    <div class="card-wrap"
      @mousemove="handleMouseMove"
      @mouseenter="handleMouseEnter"
      @mouseleave="handleMouseLeave"
      ref="card">
      <div class="card"
        :style="cardStyle">
        <div class="card-bg" :style="[cardBgTransform, cardBgImage]"></div>
        <div class="card-info">
          <slot name="header"></slot>
          <slot name="content"></slot>
        </div>
      </div>
    </div>`,
        mounted() {
      
      
            this.width = this.$refs.card.offsetWidth;
            this.height = this.$refs.card.offsetHeight;
        },
        props: ['dataImage'],
        data: () => ({
      
      
            width: 0,
            height: 0,
            mouseX: 0,
            mouseY: 0,
            mouseLeaveDelay: null }),

        computed: {
      
      
            mousePX() {
      
      
                return this.mouseX / this.width;
            },
            mousePY() {
      
      
                return this.mouseY / this.height;
            },
            cardStyle() {
      
      
                const rX = this.mousePX * 30;
                const rY = this.mousePY * -30;
                return {
      
      
                    transform: `rotateY(${ 
        rX}deg) rotateX(${ 
        rY}deg)` };

            },
            cardBgTransform() {
      
      
                const tX = this.mousePX * -40;
                const tY = this.mousePY * -40;
                return {
      
      
                    transform: `translateX(${ 
        tX}px) translateY(${ 
        tY}px)` };

            },
            cardBgImage() {
      
      
                return {
      
      
                    backgroundImage: `url(${ 
        this.dataImage})` };

            } },

        methods: {
      
      
            handleMouseMove(e) {
      
      
                this.mouseX = e.pageX - this.$refs.card.offsetLeft - this.width / 2;
                this.mouseY = e.pageY - this.$refs.card.offsetTop - this.height / 2;
            },
            handleMouseEnter() {
      
      
                clearTimeout(this.mouseLeaveDelay);
            },
            handleMouseLeave() {
      
      
                this.mouseLeaveDelay = setTimeout(() => {
      
      
                    this.mouseX = 0;
                    this.mouseY = 0;
                }, 1000);
            } } });

    const app = new Vue({
      
      
        el: '#app' });
</script>
</html>

Guess you like

Origin blog.csdn.net/qq_35241329/article/details/130740896