爬行的蜗牛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: golang Linux PHP
查看: 84|回复: 0

HTML+CSS+JS实现“口袋妖怪卡片全息效果”

[复制链接]

134

主题

41

回帖

1031

积分

管理员

积分
1031
发表于 2024-11-23 19:27:03 | 显示全部楼层 |阅读模式
111.gif

这款效果不仅适合喜欢口袋妖怪的人,还具有令人惊叹的全息视觉效果。每张卡片都使用动画 GIF 和渐变色打造出闪闪发光的效果,尽管这种设计不适合所有场景,但它绝对是独一无二的。
HTML
  1. <main id=app>
  2.    
  3.   <p>Please checkout the newer version of this; <a target="_top" href="https://codepen.io/simeydotme/pen/abYWJdX">https://codepen.io/simeydotme/pen/abYWJdX</a></p>
  4.   
  5.   <h1>Pokemon Card, Holo Effect</h1>
  6.   
  7.   <section class="cards">
  8.     <div class="card charizard animated"></div>
  9.     <div class="card pika animated"></div>
  10.     <div class="card eevee animated"></div>
  11.     <div class="card mewtwo animated"></div>
  12.   </section>
  13.   

  14.   
  15.   
  16.   
  17.   
  18.   <style class="hover"></style>
  19.   
  20.   <section class="demo">
  21.     <div class="card"></div>
  22.     <span class="operator">+</span>
  23.     <div class="card"><span>color-dodge</span></div>
  24.     <span class="operator">+</span>
  25.     <div class="card"><span>color-dodge</span></div>
  26.   </section>

  27.   
  28. </main>


  29. <section class="promo">
  30.   <p>
  31.   <a target="_top" href="https://codepen.io/simeydotme/pen/abYWJdX">
  32.     View Version 2, much improved here
  33.     <img src="https://assets.codepen.io/13471/internal/screenshots/pens/abYWJdX.custom.png?version=1674760356" alt="">
  34.   </a>
  35.   </p>
  36. </section>
复制代码

CSS
  1. :root {
  2.   --color1: rgb(0, 231, 255);
  3.   --color2: rgb(255, 0, 231);
  4.   --back: url(https://cdn2.bulbagarden.net/upload/1/17/Cardback.jpg);
  5.   --charizard1: #fac;
  6.   --charizard2: #ddccaa;
  7.   --charizardfront: url(https://assets.codepen.io/13471/charizard-gx.webp);
  8.   --pika1: #54a29e;
  9.   --pika2: #a79d66;
  10.   --pikafront: url(https://assets.codepen.io/13471/pikachu-gx.webp);
  11.   --eevee1: #efb2fb;
  12.   --eevee2: #acc6f8;
  13.   --eeveefront: url(https://assets.codepen.io/13471/eevee-gx.webp);
  14.   --mewtwo1: #efb2fb;
  15.   --mewtwo2: #acc6f8;
  16.   --mewtwofront: url(https://assets.codepen.io/13471/mewtwo-gx.webp);
  17. }



  18. .card {

  19.   width: 71.5vw;
  20.   height: 100vw;
  21.     // width: clamp(200px, 61vh, 18vw);
  22.     // height: clamp(280px, 85vh, 25.2vw);
  23.   @media screen and (min-width: 600px) {
  24.     // width: 61vh;
  25.     // height: 85vh;
  26.     // max-width: 500px;
  27.     // max-height: 700px;
  28.     width: clamp(12.9vw, 61vh, 18vw);
  29.     height: clamp(18vw, 85vh, 25.2vw);
  30.   }
  31.   
  32.   position: relative;
  33.   overflow: hidden;
  34.   margin: 20px;
  35.   overflow: hidden;
  36.   z-index: 10;
  37.   touch-action: none;
  38.   
  39.   border-radius: 5% / 3.5%;
  40.   box-shadow:
  41.     -5px -5px 5px -5px var(--color1),
  42.     5px 5px 5px -5px var(--color2),
  43.     -7px -7px 10px -5px transparent,
  44.     7px 7px 10px -5px transparent,
  45.     0 0 5px 0px rgba(255,255,255,0),
  46.     0 55px 35px -20px rgba(0, 0, 0, 0.5);
  47.   
  48.   transition: transform 0.5s ease, box-shadow 0.2s ease;
  49.   will-change: transform, filter;
  50.   
  51.   background-color: #040712;
  52.   background-image: var(--front);
  53.   background-size: cover;
  54.   background-repeat: no-repeat;
  55.   background-position: 50% 50%;
  56.   transform-origin: center;
  57.   
  58. }

  59. .card:hover {
  60.   box-shadow:
  61.     -20px -20px 30px -25px var(--color1),
  62.     20px 20px 30px -25px var(--color2),
  63.     -7px -7px 10px -5px var(--color1),
  64.     7px 7px 10px -5px var(--color2),
  65.     0 0 13px 4px rgba(255,255,255,0.3),
  66.     0 55px 35px -20px rgba(0, 0, 0, 0.5);
  67. }

  68. .card.charizard {
  69.   --color1: var(--charizard1);
  70.   --color2: var(--charizard2);
  71.   --front: var(--charizardfront);
  72. }
  73. .card.pika {
  74.   --color1: var(--pika1);
  75.   --color2: var(--pika2);
  76.   --front: var(--pikafront);
  77. }
  78. .card.mewtwo {
  79.   --color1: var(--mewtwo1);
  80.   --color2: var(--mewtwo2);
  81.   --front: var(--mewtwofront);
  82. }
  83. .card.eevee {
  84.   --color1: #ec9bb6;
  85.   --color2: #ccac6f;
  86.   --color3: #69e4a5;
  87.   --color4: #8ec5d6;
  88.   --color5: #b98cce;
  89.   --front: var(--eeveefront);
  90. }

  91. .card:before,
  92. .card:after {
  93.   content: "";
  94.   position: absolute;
  95.   left: 0;
  96.   right: 0;
  97.   bottom: 0;
  98.   top: 0;
  99.   background-repeat: no-repeat;
  100.   opacity: .5;
  101.   mix-blend-mode: color-dodge;
  102.   transition: all .33s ease;
  103. }

  104. .card:before {
  105.   background-position: 50% 50%;
  106.   background-size: 300% 300%;
  107.   background-image: linear-gradient(
  108.     115deg,
  109.     transparent 0%,
  110.     var(--color1) 25%,
  111.     transparent 47%,
  112.     transparent 53%,
  113.     var(--color2) 75%,
  114.     transparent 100%
  115.   );
  116.   opacity: .5;
  117.   filter: brightness(.5) contrast(1);
  118.   z-index: 1;
  119. }

  120. .card:after {
  121.   opacity: 1;
  122.   background-image: url("https://assets.codepen.io/13471/sparkles.gif"),
  123.     url(https://assets.codepen.io/13471/holo.png),
  124.     linear-gradient(125deg, #ff008450 15%, #fca40040 30%, #ffff0030 40%, #00ff8a20 60%, #00cfff40 70%, #cc4cfa50 85%);
  125.   background-position: 50% 50%;
  126.   background-size: 160%;
  127.   background-blend-mode: overlay;
  128.   z-index: 2;
  129.   filter: brightness(1) contrast(1);
  130.   transition: all .33s ease;
  131.   mix-blend-mode: color-dodge;
  132.   opacity: .75;
  133. }

  134. .card.active:after,
  135. .card:hover:after {
  136.   filter: brightness(1) contrast(1);;
  137.   opacity: 1;
  138. }

  139. .card.active,
  140. .card:hover {
  141.   animation: none;
  142.   transition: box-shadow 0.1s ease-out;
  143. }

  144. .card.active:before,
  145. .card:hover:before {
  146.   animation: none;
  147.   background-image: linear-gradient(
  148.     110deg,
  149.     transparent 25%,
  150.     var(--color1) 48%,
  151.     var(--color2) 52%,
  152.     transparent 75%
  153.   );
  154.   background-position: 50% 50%;
  155.   background-size: 250% 250%;
  156.   opacity: .88;
  157.   filter: brightness(.66) contrast(1.33);
  158.   transition: none;
  159. }

  160. .card.active:before,
  161. .card:hover:before,
  162. .card.active:after,
  163. .card:hover:after {
  164.   animation: none;
  165.   transition: none;
  166. }

  167. .card.animated {
  168.   transition: none;
  169.   animation: holoCard 12s ease 0s 1;
  170.   &:before {
  171.     transition: none;
  172.     animation: holoGradient 12s ease 0s 1;
  173.   }
  174.   &:after {
  175.     transition: none;
  176.     animation: holoSparkle 12s ease 0s 1;
  177.   }
  178. }




  179. @keyframes holoSparkle {
  180.   0%, 100% {
  181.     opacity: .75; background-position: 50% 50%; filter: brightness(1.2) contrast(1.25);
  182.   }
  183.   5%, 8% {
  184.     opacity: 1; background-position: 40% 40%; filter: brightness(.8) contrast(1.2);
  185.   }
  186.   13%, 16% {
  187.     opacity: .5; background-position: 50% 50%; filter: brightness(1.2) contrast(.8);
  188.   }
  189.   35%, 38% {
  190.     opacity: 1; background-position: 60% 60%; filter: brightness(1) contrast(1);
  191.   }
  192.   55% {
  193.     opacity: .33; background-position: 45% 45%; filter: brightness(1.2) contrast(1.25);
  194.   }
  195. }

  196. @keyframes holoGradient {
  197.   0%, 100% {
  198.     opacity: 0.5;
  199.     background-position: 50% 50%;
  200.     filter: brightness(.5) contrast(1);
  201.   }
  202.   5%, 9% {
  203.     background-position: 100% 100%;
  204.     opacity: 1;
  205.     filter: brightness(.75) contrast(1.25);
  206.   }
  207.   13%, 17% {
  208.     background-position: 0% 0%;
  209.     opacity: .88;
  210.   }
  211.   35%, 39% {
  212.     background-position: 100% 100%;
  213.     opacity: 1;
  214.     filter: brightness(.5) contrast(1);
  215.   }
  216.   55% {
  217.     background-position: 0% 0%;
  218.     opacity: 1;
  219.     filter: brightness(.75) contrast(1.25);
  220.   }
  221. }

  222. @keyframes holoCard {
  223.   0%, 100% {
  224.     transform: rotateZ(0deg) rotateX(0deg) rotateY(0deg);
  225.   }
  226.   5%, 8% {
  227.     transform: rotateZ(0deg) rotateX(6deg) rotateY(-20deg);
  228.   }
  229.   13%, 16% {
  230.     transform: rotateZ(0deg) rotateX(-9deg) rotateY(32deg);
  231.   }
  232.   35%, 38% {
  233.     transform: rotateZ(3deg) rotateX(12deg) rotateY(20deg);
  234.   }
  235.   55% {
  236.     transform: rotateZ(-3deg) rotateX(-12deg) rotateY(-27deg);
  237.   }
  238. }



  239. .card.eevee:hover {
  240.   box-shadow:
  241.     0 0 30px -5px white,
  242.     0 0 10px -2px white,
  243.     0 55px 35px -20px rgba(0, 0, 0, 0.5);
  244. }
  245. .card.eevee:hover:before,
  246. .card.eevee.active:before {
  247.   background-image: linear-gradient(
  248.     115deg,
  249.     transparent 20%,
  250.     var(--color1) 36%,
  251.     var(--color2) 43%,
  252.     var(--color3) 50%,
  253.     var(--color4) 57%,
  254.     var(--color5) 64%,
  255.     transparent 80%
  256.   );
  257. }




  258. .demo .card {
  259.   background-image: var(--back);
  260.   font-size: 2vh
  261. }
  262. .demo .card > span {
  263.   position: relative;
  264.   top: 45%;
  265. }

  266. .demo .card:nth-of-type(1),
  267. .demo .card:nth-of-type(2),
  268. .demo .card:nth-of-type(3) {
  269.   width: 20vh;
  270.   height: 27.5vh;
  271.   box-shadow: inset 0 0 0 1px rgba(white,0.4), 0 25px 15px -10px rgba(0, 0, 0, 0.5);
  272.   animation: none;
  273. }

  274. .demo .card:nth-of-type(1),
  275. .demo .card:nth-of-type(2),
  276. .demo .card:nth-of-type(3) {
  277.   &:before, &:after {
  278.     animation: none;
  279.     // opacity: 1;
  280.   }
  281. }
  282. .demo .card:nth-of-type(1) {
  283.   &:before, &:after { display: none; }
  284. }
  285. .demo .card:nth-of-type(2) {
  286.   background: none;
  287.   &:before { display: none; }
  288. }
  289. .demo .card:nth-of-type(3) {
  290.   background: none;
  291.   &:after { display: none; }
  292. }

  293. .operator {
  294.   display: inline-block;
  295.   vertical-align: middle;
  296.   font-size: 6vh;
  297. }






  298. html, body {
  299.   height: 100%;
  300.   background-color: #333844;
  301.   padding: 0;
  302.   z-index: 1;
  303.   transform: translate3d(0,0,0.1px);
  304. }
  305. body {
  306.   color: white;
  307.   background-color: #333844;
  308.   font-family: "Heebo", sans-serif;
  309.   text-align: center;
  310. }
  311. h1 {
  312.   display: block;
  313.   margin: 30px 0;
  314. }
  315. p {
  316.   margin-top: 5px;
  317.   font-weight: 200;
  318. }
  319. #app {
  320.   position: relative;
  321. }

  322. .demo,
  323. .cards {
  324.   display: flex;
  325.   flex-direction: column;
  326.   align-items: center;
  327.   justify-content: space-evenly;
  328.   perspective: 2000px;
  329.   position: relative;
  330.   z-index: 1;
  331.   transform: translate3d(0.1px, 0.1px, 0.1px )
  332. }
  333. .demo {
  334.   flex-direction: row;
  335.   justify-content: center;
  336. }

  337. @media screen and (min-width: 600px) {
  338.   .cards {
  339.     flex-direction: row;
  340.   }
  341. }






  342. .cards .card {
  343.   &:nth-child(2) {
  344.     &, &:before, &:after {
  345.       animation-delay: 0.25s;
  346.     }
  347.   }
  348.   &:nth-child(3) {
  349.     &, &:before, &:after {
  350.       animation-delay: 0.5s;
  351.     }
  352.   }
  353.   &:nth-child(4) {
  354.     &, &:before, &:after {
  355.       animation-delay: 0.75s;
  356.     }
  357.   }
  358. }


  359. p {
  360.   font-weight: 400;
  361.   font-size: 18px;
  362.   padding: 1em;
  363.   background: rgba(0,0,0,0.3);
  364.   margin-top: 0;
  365.   animation: rubberBand 1.5s linear 3s 1;
  366. }
  367. .promo {
  368.   margin-top: 50px;
  369. }
  370. .promo img {
  371.   margin-top: 10px;
  372.   max-width: 80%;
  373. }
  374. p a {
  375.   color: cyan;
  376. }

  377. html,body,main {
  378.   min-height: 100%;
  379. }



  380. @keyframes rubberBand {
  381.   from {
  382.     transform: scale3d(1, 1, 1);
  383.   }

  384.   30% {
  385.     transform: scale3d(1.25, 0.75, 1);
  386.   }

  387.   40% {
  388.     transform: scale3d(0.75, 1.25, 1);
  389.   }

  390.   50% {
  391.     transform: scale3d(1.15, 0.85, 1);
  392.   }

  393.   65% {
  394.     transform: scale3d(0.95, 1.05, 1);
  395.   }

  396.   75% {
  397.     transform: scale3d(1.05, 0.95, 1);
  398.   }

  399.   to {
  400.     transform: scale3d(1, 1, 1);
  401.   }
  402. }
复制代码

JS
  1. /*

  2.   using
  3.     - an animated gif of sparkles.
  4.     - an animated gradient as a holo effect.
  5.     - color-dodge mix blend mode
  6.   
  7. */
  8. var x;
  9. var $cards = $(".card");
  10. var $style = $(".hover");

  11. $cards
  12.   .on("mousemove touchmove", function(e) {
  13.     // normalise touch/mouse
  14.     var pos = [e.offsetX,e.offsetY];
  15.     e.preventDefault();
  16.     if ( e.type === "touchmove" ) {
  17.       pos = [ e.touches[0].clientX, e.touches[0].clientY ];
  18.     }
  19.     var $card = $(this);
  20.     // math for mouse position
  21.     var l = pos[0];
  22.     var t = pos[1];
  23.     var h = $card.height();
  24.     var w = $card.width();
  25.     var px = Math.abs(Math.floor(100 / w * l)-100);
  26.     var py = Math.abs(Math.floor(100 / h * t)-100);
  27.     var pa = (50-px)+(50-py);
  28.     // math for gradient / background positions
  29.     var lp = (50+(px - 50)/1.5);
  30.     var tp = (50+(py - 50)/1.5);
  31.     var px_spark = (50+(px - 50)/7);
  32.     var py_spark = (50+(py - 50)/7);
  33.     var p_opc = 20+(Math.abs(pa)*1.5);
  34.     var ty = ((tp - 50)/2) * -1;
  35.     var tx = ((lp - 50)/1.5) * .5;
  36.     // css to apply for active card
  37.     var grad_pos = `background-position: ${lp}% ${tp}%;`
  38.     var sprk_pos = `background-position: ${px_spark}% ${py_spark}%;`
  39.     var opc = `opacity: ${p_opc/100};`
  40.     var tf = `transform: rotateX(${ty}deg) rotateY(${tx}deg)`
  41.     // need to use a <style> tag for psuedo elements
  42.     var style = `
  43.       .card:hover:before { ${grad_pos} }  /* gradient */
  44.       .card:hover:after { ${sprk_pos} ${opc} }   /* sparkles */
  45.     `
  46.     // set / apply css class and style
  47.     $cards.removeClass("active");
  48.     $card.removeClass("animated");
  49.     $card.attr( "style", tf );
  50.     $style.html(style);
  51.     if ( e.type === "touchmove" ) {
  52.       return false;
  53.     }
  54.     clearTimeout(x);
  55.   }).on("mouseout touchend touchcancel", function() {
  56.     // remove css, apply custom animation on end
  57.     var $card = $(this);
  58.     $style.html("");
  59.     $card.removeAttr("style");
  60.     x = setTimeout(function() {
  61.       $card.addClass("animated");
  62.     },2500);
  63.   });
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表