灵动岛前端Ui

简介: 灵动岛前端Ui

一、前言


灵动岛(Dynamic Island )是什么?


灵动岛,是苹果公司iPhone 14 Pro系列 [2]


交互UI,让虚拟软件和硬件的交互变得更为流畅。当有来电、短信等通知时,灵动岛会变化它的形态,以便让用户能够更直观地接收到这些信息。而在用户使用一些应用App并将其切换到后台时(如音乐),灵动岛也能以另一种形态来显示这些软件,还可以轻点这个区域进行更复杂一点的操作,比如切换歌曲。



功能


当用户收到信息后,iPhone 14 Pro显示屏上方的灵动岛可以展开显示信息。此外灵动岛还可以显示音乐播放、Siri等组件,让用户在首页直接完成各种功能控制和信息阅读。iPhone 14 Pro 拥有6.1英寸屏幕,还将推出6.7英寸的iPhone 14 Pro MAX [2]


发展历程


2022年9月,iOS 16.1 Beta 1 发布后,苹果iPhone 14 Pro和Max灵动岛已支持单手操作。 [4]


2022年10月,媒体报道,在一次新的采访中,苹果公司软件工程高级副总裁 Craig Federighi 和苹果公司人机界面设计副总裁 Alan Dye,讨论了 iPhone 14 Pro 的灵动岛。表示 iPhone X 问世五年来的第一个重大操作变化。


当用户收到信息后,iPhone 14 Pro显示屏上方的灵动岛可以展开显示信息。此外灵动岛还可以显示音乐播放、Siri等组件,让用户在首页直接完成各种功能控制和信息阅读。iPhone 14 Pro 拥有6.1英寸屏幕,还将推出6.7英寸的iPhone 14 Pro MAX [2]



我主要实现的是从灵动岛跳转csdn主页的动画效果,大家有需要可以在html部分更改跳转的链接(iframe部分)


%iframe#doom{:height => "800", :src => "https://blog.csdn.net/weixin_43233219?spm=1019.2139.3001.5343/", :width => "1200"}


tips:但是该代码的缺点是目前该跳转链接和灵动岛的大小以及Ui不匹配


二、效果展示1



三、编码实现1


html部分


#wrapper
  .phone
    .inner
      .info
        %span#time
        %span
    .island
  .framewrap
    %iframe#doom{:height => "800", :src => "https://blog.csdn.net/weixin_43233219?spm=1019.2139.3001.5343/", :width => "1200"}


css部分


body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  width: 100vw;
  position: relative;
  overflow: hidden;
  background: #000;
  --transition: 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.075);
  perspective: 2400px;
  &:after {
    content: "Enter : Start // Arrow Keys : Move // Ctrl : Shoot // Space : Open Door";
    color: #666;
    position: absolute;
    top: 10px;
    font-size: 14px;
    transition: var(--transition);
    transform: translateY(-50px);
  }
  &:before {
    content: "";
    position: absolute;
    width: 100vw;
    height: calc(50vh - 100px);
    bottom: 0;
    left: 0;
    z-index: 12;
    pointer-events: none;
    background: linear-gradient(to top, #000, rgba(0,0,0,0.01));
  }
  &.loaded {
    .phone {
      transform: translateY(0);
      filter: brightness(1);
    }
  }
  #wrapper {
    position: absolute;
    width: 100vw;
    height: 100vh;
    transition: transform 0.5s cubic-bezier(0.95, 0.84, 0.44, 1);
    transform-style: preserve-3d;
    transform: rotateX(30deg) translateZ(0px);
    transform-origin: 50% 75%;
  }
  &:hover {
    #wrapper {
      transform: rotateX(30deg) translateZ(0px) scale(1.015);
    }
  }
  &:not(.active){
    .phone .island{
      animation:pulse 10s ease-in-out infinite;
      @keyframes pulse{
        90%{
          box-shadow:0 0 0 0px rgba(0,0,0,0.01);
        }
        95%{
          box-shadow:0 0 0 3px rgba(0,0,0,0.25);
        }
        100%{
          box-shadow:0 0 0 8px rgba(0,0,0,0.01);
        }
      }
    }
  }
  &.active {
    &:after {
      transform: translateY(0);
      transition-delay: 0.5s;
    }
    #wrapper {
      transform: scale(1.25) translateZ(0px);
      transition:transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.075);
    }
    .phone {
      .island {
        &:after {
          transform: scaleX(3.5) scaleY(9.85) translateZ(0px);
          border-radius: 6px / 2px;
        }
      }
      &:before {
        filter: contrast(2);
      }
      .info {
        width: 150%;
        transition-delay: 0.05s;
      }
    }
    .framewrap {
      transform: translate(-50%, calc(-50% - 15px)) scale(1) translateZ(0px);
      iframe {
        opacity: 1;
      }
    }
  }
  .framewrap {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, calc(-50% - 15px)) scale(0) translateZ(0px);
    transform-origin: 50% calc(50% - 100px);
    width: 1000px;
    height: 210px;
    overflow: hidden;
    transition: var(--transition);
    z-index: 20;
    &:before {
      content: "";
      position: absolute;
      width: 330px;
      height: 210px;
      border-radius: 15px;
      box-shadow: inset 0 0 0 5px #000, 0 0 0 5px #000;
      z-index: 10;
      pointer-events: none;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
    }
  }
  .phone {
    position: absolute;
    width: 400px;
    height: 700px;
    background: url("https://assets.codepen.io/383755/wallpaper.jpg") 50% 50% /
        cover,
      #000;
    border-radius: 50px;
    left: calc(50% - 200px);
    top: calc(50% - 160px);
    transform: scale(1.25) translateY(100vh) rotateX(-10deg);
    transition: 2s cubic-bezier(0.175, 0.885, 0.32, 1.075);
    filter: brightness(1.5);
    .inner {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      border-radius: inherit;
      overflow: hidden;
    }
    &:before {
      content: "";
      position: absolute;
      width: 100%;
      height: 100%;
      border-radius: inherit;
      left: 0;
      top: 0;
      box-shadow: inset 0 0 0 2px #666, inset 0 0 0 12.5px #000, 0 0 0 1px #fff;
      z-index: 2;
      transition: var(--transition);
    }
    &:after {
      content: "";
      position: absolute;
      width: 2px;
      height: 40px;
      background: #efefef;
      left: -3px;
      top: 125px;
      box-shadow: 0 75px 0 #efefef, 0 100px 0 #efefef;
    }
    .info {
      position: absolute;
      width: calc(100% - 100px);
      top: 25px;
      left: 50%;
      transform: translateX(-50%);
      z-index: 1;
      display: flex;
      justify-content: space-between;
      color: #fff;
      transition: 0.175s cubic-bezier(0.175, 0.885, 0.32, 1.075);
      transition-delay: 0.3s;
      span:not(#time) {
        &:before,
        &:after {
          content: "";
          position: absolute;
          top: 0;
        }
        &:before {
          width: 25px;
          height: 15px;
          right: 20px;
          background: linear-gradient(
                to right,
                #fff 3px,
                rgba(0,0,0,0.01) 3px,
                rgba(0,0,0,0.01) 10px
              )
              0px 100% / 20px 5px no-repeat,
            linear-gradient(
                to right,
                #fff 3px,
                rgba(0,0,0,0.01) 3px,
                rgba(0,0,0,0.01) 10px
              )
              5px 100% / 20px 7.5px no-repeat,
            linear-gradient(
                to right,
                #fff 3px,
                rgba(0,0,0,0.01) 3px,
                rgba(0,0,0,0.01) 10px
              )
              10px 100% / 20px 10px no-repeat,
            linear-gradient(
                to right,
                #fff 3px,
                rgba(0,0,0,0.01) 3px,
                rgba(0,0,0,0.01) 10px
              )
              15px 100% / 20px 12.5px no-repeat;
        }
        &:after {
          width: 22.5px;
          height: 13px;
          right: 0px;
          background: radial-gradient(
            circle at bottom,
            #fff 2px,
            rgba(0,0,0,0.01) 2px,
            rgba(0,0,0,0.01) 5px,
            #fff 5px,
            #fff 7px,
            rgba(0,0,0,0.01) 7px,
            rgba(0,0,0,0.01) 10px,
            #fff 10px,
            #fff 12px,
            rgba(0,0,0,0.01) 12px
          );
          clip-path: polygon(0 0, 50% 100%, 100% 0);
        }
      }
    }
    .island {
      width: 100px;
      height: 25px;
      position: absolute;
      top: 20px;
      left: 50%;
      transform: translateX(-50%);
      cursor: pointer;
      z-index: 9;
      border-radius: 50px;
      &:before,
      &:after {
        content: "";
        position: absolute;
      }
      &:before {
        width: 12.5px;
        height: 12.5px;
        border-radius: 100%;
        box-shadow: inset 0 0 2px 0.5px #333, 0 0 0 1px #111;
        top: 5px;
        right: 10px;
        z-index: 2;
        background: radial-gradient(circle at center, #222 1px, #000 1.5px) 1px
          0px / 100% 100% no-repeat;
      }
      &:after {
        width: 100%;
        height: 100%;
        border-radius: 50px;
        background: #000;
        top: 0;
        left: 0;
        transition: var(--transition);
        transform-origin: top;
      }
    }
  }
  iframe {
    clip-path: polygon(10px 207px, 650px 207px, 650px 612px, 10px 612px);
    height: 800px;
    width: 1200px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(calc(-50% + 136.5px), calc(-50% - 5px)) scale(0.5);
    opacity: 0;
    transition: var(--transition);
  }
}


js部分


document.querySelector(".island").addEventListener("click", function () {
  document.body.classList.toggle("active");
});
document.addEventListener(
  "DOMContentLoaded",
  function () {
    var today = new Date();
    var time =
      (today.getHours() % 12) +
      ":" +
      today.getMinutes().toString().padStart(2, "0");
    document.getElementById("time").appendChild(document.createTextNode(time));
    setTimeout(() => {
      document.body.classList.add("loaded");
    }, 2000);
  },
  false
);


四、效果展示2


再增加一个前端灵动岛的ui效果源码,可以 切换界面的Ui主题颜色,有官方的几个配色和随机配色


效果图如下



五、源码2


.html代码


input(name="theme" type="radio" id="deep-purple" checked)
input(name="theme" type="radio" id="gold")
input(name="theme" type="radio" id="space-black")
input(name="theme" type="radio" id="silver")
input(name="theme" type="radio" id="random")
input(name="zoom" type="checkbox" id="zoom")
.scene
  .pallette
    label.swatch(tabIndex="0" for="deep-purple")
    label.swatch(tabIndex="0" for="gold")
    label.swatch(tabIndex="0" for="space-black")
    label.swatch(tabIndex="0" for="silver")
    label.swatch(tabIndex="0" for="random")
      .icon
      .tooltip CMD + click to save
  .zoom-con
    label.swatch(tabIndex="0" for="zoom")
  .phone-con
    .phone
      .buttons
        .left
          .button
          .button
          .button
        .right
          .button
      .camera
      .screen-container
        .bg
          .deep-purple
            .section
              .glow
            .section
              .glow
          .gold
            .section
              .glow
            .section
              .glow
          .space-black
            .section
              .glow
            .section
              .glow
          .silver
            .section
              .glow
            .section
              .glow
          .random.canvas
            .shapes
              .shape
              .shape
              .shape
              .shape
              .shape
              .shape
        .notch-container(tabIndex="0")
          .notch
            .content
              .left
                .tile
                .text
              .right
              .bar
                .duration
        .notch-blur
        .screen
          .app
            .weather
          .app
          .app
          .app
          .app
          .app
          .app
          .app
          .app
          .app


.css代码


@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap');
:root {
  --size: max(5px, 1vmin);
  --height: 80em;
  --pad: 1.25em;
  --border-radius: 6.666em;
  --gutter: calc(var(--pad) * 2);
  --scene-pad: 5vmin;
  --bg-blur: 0.333em;
  --button-width: 0.333em;
  --notch-height: 3.33em;
  --notch-width: 33.3%;
  --notch-radius: calc(var(--border-radius) - calc(var(--pad) * 2));
  --notch-duration: 0.333s;
  --ease: cubic-bezier(.666, 0, .4, 1);
  --ease-spring: cubic-bezier(.666, 0, .4, 1.2);
  --ease-out: cubic-bezier(.15,0,.333,1);
  --border-width: 0.4em;
  --deep-purple: 284;
  --gold: 22.5;
  --space-black: 215;
  --silver: 254;
  --c-h: var(--deep-purple);
  --c-s: 100%;
  --c-l: 50%;
}
// Squircle effect
@function round-off() {
  @return url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1'><defs><filter id='round'><feGaussianBlur in='SourceGraphic' stdDeviation='5' result='blur' /><feColorMatrix in='blur' mode='matrix' values='1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 19 -9' result='goo'/><feComposite in='SourceGraphic' in2='goo' operator='atop'/></filter></defs></svg>#round");
}
// Smoother gradients
@function scrim-gradient(
  $startColor,
  $direction: 'to bottom',
  $from: 0,
  $to: 100,
  $type: linear,
  $reverse: false,
  $debug: false
) {
  $scrimCoordinates: (
    0: 1,
    19: 0.738,
    34: 0.541,
    47: 0.382,
    56.5: 0.278,
    65: 0.194,
    73: 0.126,
    80.2: 0.075,
    86.1: 0.042,
    91: 0.021,
    95.2: 0.008,
    98.2: 0.002,
    100: 0
  );
  $hsl: '';
  @if type-of($startColor) == 'list' {
    $hsl: $startColor;
  } @else {
    $hue: hue($startColor);
    $saturation: saturation($startColor);
    $lightness: lightness($startColor);
    $hsl: #{$hue}, #{$saturation}, #{$lightness};
  }
  $stops: ();
  @each $colorStop, $alpha in $scrimCoordinates {
    $stop:
      unquote("hsla(#{$hsl}, #{if($reverse, 1 - $alpha, $alpha)})") 
      $from + ($colorStop/($to/(100 - $from))) * 1%;
    $stops: append($stops, $stop, comma);
  }
  @if $debug {
    @return '$startColor: #{$startColor},$direction: #{$direction}, $from: #{$from}, $to: #{$to}, $type: #{$type}, $reverse: #{$reverse}';
  } 
  @else {
    @return #{$type}-gradient(unquote($direction), $stops);
  }
}
@keyframes appear {
  to {
    transform: scale3d(1,1,1);
    opacity: 1;
  }
}
body {
  background: darken(blue, 48);
}
.scene {
  display: flex;
  flex-wrap: wrap;
  gap: 3em 0;
  align-items: center;
  align-content: center;
  justify-content: center;
  min-height: 100vh;
  font-family: Inter;
  font-size: var(--size);
  padding: var(--scene-pad);
  box-sizing: border-box;
}
.phone-con {
  flex-basis: 100%;
  display: flex;
  justify-content: center;
}
.phone {
  position: relative;
  z-index: 1;
  aspect-ratio: 37/76;
  background: black;
  height: var(--height);
  border-radius: var(--border-radius);
  box-shadow: 0 0 0.1em 0.25em hsl(var(--c-h), 20%, 25%), 0 0 0 var(--border-width) hsl(var(--c-h), 30%, 85%);
  box-sizing: border-box;
  opacity: 0;
  transform: scale3d(1.1,1.1,1);
  animation: appear 1s var(--ease-out) forwards;
  webkit-backface-visibility: hidden;
  &:before {
    content: '';
    position: absolute;
    top: var(--border-radius);
    right: calc(var(--border-width) * -1);
    bottom: var(--border-radius);
    left: calc(var(--border-width) * -1);
    border: 0.5em solid hsl(var(--c-h), 20%, 30%);
    border-left-width: 0;
    border-right-width: 0;
  }
}
.buttons {
  position: absolute;
  inset: calc(var(--border-width) * -1);
  pointer-events: none;
  .left,
  .right {
    position: absolute;
    width: var(--button-width);
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 1.5em;
  }
  .left {
    right: 100%;
    top: calc(var(--border-radius) * 2);
    .button {
      &:nth-child(1) {
        height: 3em;
        margin-bottom: 0.5em;
      }
    }
  }
  .right {
    left: 100%;
    transform: scale3d(-1, 1, 1);
    top: calc(var(--border-radius) * 3);
    .button {
      height: 9.5em;
    }
  }
  .button {
    background: hsl(var(--c-h), 20%, 95%);
    height: 6em;
    box-shadow:
      inset -0.15em 0 0.1em black, 
      inset 0 0 0.1em hsl(var(--c-h), 30%, 90%),
      inset 0 0.2em 0.1em hsl(var(--c-h), 30%, 90%),
      inset 0 -0.2em 0.1em hsl(var(--c-h), 30%, 90%),
      inset -0.1em 0.333em 0.1em rgba(black, 0.5), 
      inset -0.1em -0.333em 0.1em rgba(black, 0.5), 
    ;
    border-top-left-radius: 0.2em;
    border-bottom-left-radius: 0.2em;
  }
}
.screen-container {
  position: absolute;
  // overflow: hidden;
  inset: 0;
  border-radius: var(--border-radius);
  border: var(--pad) solid black;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--pad) * 2);
  // Bottom thingy
  &:before {
    content: '';
    position: absolute;
    z-index: 2;
    background: white;
    width: 36.6%;
    bottom: calc(var(--pad) * 0.75);
    height: calc(var(--pad) * 0.5);
    border-radius: calc(var(--pad) * 0.25);
    filter: drop-shadow(0 0.1em 0.25em rgba(black, 0.1));
  }
}
.bg {
  position: absolute;
  inset: 0;
  background: black;
  border-radius: calc(var(--border-radius) - var(--pad));
  overflow: hidden;
  // filter: round-off();
  transform: translateZ(0);
  > * {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    opacity: 0;
    transition: opacity 1s var(--ease-out) 0.5s;
    background: black;
  }
  .section {
    --g-h: var(--c-h);
    --g-s: var(--c-s);
    --g-l: var(--c-l);
    flex-grow: 1;
    position: relative;
    overflow: hidden;
    border-radius: calc(var(--border-radius) - var(--pad));
    border-bottom-left-radius: 20em;
    border-bottom-right-radius: 20em;
    &:before {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: inherit;
      background:
        scrim-gradient(black, '120% 110% at 50% 92.5%', $from: 33.3, $type: radial),
        scrim-gradient((calc(var(--g-h) - var(--g-hue-adjust-2, var(--g-hue-adjust))), 100%, 50%), '100% 66.6% at 110% var(--g-hue-adjust-2-y, 100%)', $from: 33.3, $type: radial),
        scrim-gradient((calc(var(--g-h) - var(--g-hue-adjust-2, var(--g-hue-adjust))), 100%, 50%), '100% 66.6% at -10% var(--g-hue-adjust-2-y, 100%)', $from: 33.3, $type: radial),
        scrim-gradient((calc(var(--g-h) + 33.3), 100%, var(--g-lightness, 82.5%)), '150% 100% at 50% 80%', $from: 35, $type: radial, $reverse: true),
      ;
      background-color: hsl(var(--g-h), var(--g-s), var(--g-l));
      transform: scale3d(1.1, 1.25, 1);
      transform-origin: bottom;
      transition: transform 1s var(--ease-out) 0.5s;
    }
    &:after {
      content: '';
      position: absolute;
      inset: 0;
      border: var(--border-width) solid rgba(white, 0.8);
      border-radius: inherit;
      filter: blur(0.05em);
      // backdrop-filter: blur(0.75em);
      mask-image: radial-gradient(100% 100% at 50% 70%, black 30%, transparent 50%);
      transform: translatez(2px);
    }
    .glow {
      position: absolute;
      inset: 0;
      border-radius: inherit;
      mix-blend-mode: overlay;
      z-index: 1;
      background: radial-gradient(80% 150% at 50% 100%, hsl(var(--g-h), 100%, var(--g-l)), transparent 70%);
    }
  }
  // Bottom bg section
  .section:last-of-type {
    --g-h: calc(var(--c-h) - var(--g-hue-adjust, 0));
    --g-l: calc(var(--c-l) + 40%);
    --g-lightness: 95%;
    transform: scale3d(1, -1, 1) translateZ(1px);
  }
}
.notch-container {
  position: absolute;
  z-index: 3;
  top: var(--pad);
  right: var(--pad);
  left: var(--pad);
  display: flex;
  justify-content: center;
  height: 100%;
  max-height: calc(var(--notch-radius) * 2);
  pointer-events: none;
  outline: none;
  transition: var(--notch-duration) var(--ease);
  transition-property: max-height, max-width, filter, transform;
  will-change: max-width, max-height, filter;
  // Stop transitions when resizing screen or zooming
  .is-resizing &,
  .is-resizing & * {
    transition: none;
  }
  &:hover,
  &:focus-within {
    --shadow-opacity: 0.5;
    transition-timing-function: var(--ease-spring);
    .content {
      --content-padding: 2em;
      .text {
        opacity: 1;
      }
    }
    .notch {
      max-width: 100%;
      max-height: 100%;
      // transition: max-width 0.3s ease-in-out, max-height 0.2s ease-in-out 0.1s;
      pointer-events: all;
      transform: scale3d(1,1,1);
    }
    ~ .notch-blur {
      opacity: 1;
      max-height: calc(var(--notch-radius) * 3.333 + var(--pad));
    }
  }
  &:focus-within {
    max-height: calc(var(--notch-radius) * 3);
    --bar-height: 1em;
    --bar-opacity: 1;
    .left,
    .right {
      max-height: calc(100% - var(--bar-height, 0%) - var(--content-gap));
    }
    ~ .notch-blur {
      max-height: calc(var(--notch-radius) * 5);
      opacity: 1;
    }
  }
}
// Blurred drop-shadow
.notch-blur {
  position: absolute;
  z-index: 2;
  top: calc(var(--pad) - 3px);
  right: calc(var(--pad) - 3px);
  left: calc(var(--pad) - 3px);
  height: 100%;
  max-height: calc(var(--notch-radius) * 1.5);
  backdrop-filter: blur(0.2em);
  mask-image: scrim-gradient(black, $from: 60);
  opacity: 0;
  border-radius: calc(var(--border-radius) - var(--pad));
  transition: var(--notch-duration) var(--ease);
  transition-property: max-height, max-width, opacity, transform;
  will-change: max-width, max-height;
}
.notch {
  position: relative;
  border-radius: var(--notch-radius);
  pointer-events: all;
  overflow: hidden;
  color: white;
  // max-height: var(--notch-height);
  // max-width: var(--notch-width);
  display: flex;
  cursor: pointer;
  width: 100%;
  // max-width: var(--notch-width);
  transition: inherit;
  transition-property: inherit;
  will-change: inherit;
  filter: drop-shadow(0 1em 2em hsla(0 0% 0% / var(--shadow-opacity, 0)));
  transform: scale3d(0.375,0.4,1);
  transform-origin: top;
  &:before {
    content: '';
    position: absolute;
    inset: 0;
    background: black;
    filter: round-off();
    border-radius: inherit;
  }
}
.content {
  --content-padding: 1.75em;
  --duration-height: 0.5em;
  --content-gap: 1em;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  justify-content: stretch;
  padding: var(--content-padding);
  gap: var(--content-gap);
  font-size: 125%;
  transition-property: padding;
  will-change: padding;
  position: relative;
  .left,
  .right {
    height: 100%;
    max-height: calc(100% - var(--bar-height, 0%));
    display: flex;
    align-items: center;
    gap: 1em;
  }
  &, .left, .right, .bar, .text {
    transition: var(--notch-duration) var(--ease-out);
  }
  .left, .right, .bar {
    transition-property: max-height, opacity;
    will-change: max-height;
  }
  .left {
    flex-grow: 2;
    // background: red;
  }
  .text {
    display: flex;
    flex-direction: column;
    gap: 0.333em;
    transition-property: opacity;
    opacity: var(--bar-opacity, 0);
    &:before {
      content: 'The Move';
      order: 1;
      text-transform: uppercase;
    }
    &:after {
      order: 2;
      content: 'Space Rangers';
      opacity: 0.5;
    }
  }
  .right {
    flex-grow: 1;
    // background: blue;
  }
  .tile {
    background: #{desaturate(darken(blue, 10), 25%)};
    height: 100%;
    aspect-ratio: 1;
    border-radius: 33.3%;
    position: relative;
    &:before {
      content: '';
      position: absolute;
      inset: 0;
      border-radius: 50%;
      background: radial-gradient(50% 50% at 55% 40%, desaturate(darken(blue, 20), 25%), #cd1385 75%, transparent) center / 133.3% 133.3%;
      background-color: yellow;
      filter: blur(0.05em);
    }
  }
  .bar {
    display: flex;
    align-items: center;
    gap: 1em;
    flex-basis: 100%;
    height: 100%;
    max-height: var(--bar-height, 0%);
    color: rgba(white, 0.5);
    opacity: var(--bar-opacity, 0);
    .duration {
      position: relative;
      height: var(--duration-height);
      background: rgba(white, 0.25);
      border-radius: calc(var(--duration-height) * 0.5);
      overflow: hidden;
      flex-grow: 1;
      &:before {
        content: '';
        height: 100%;
        background: white;
        width: 25%;
        position: absolute;
      }
    }
    &:before {
      content: '1:20';
    }
    &:after {
      content: '-1:48';
    }
  }
}
.camera {
  display: flex;
  justify-content: center;
  align-items: center;
  height: var(--notch-height);
  aspect-ratio: 1/1;
  border-radius: 50%;
  pointer-events: none;
  position: absolute;
  z-index: 4;
  top: calc(var(--pad) * 2);
  right: calc(50% - calc(var(--notch-width) * 0.5));
  margin-right: calc(var(--pad) * 0.333);
  &:before {
    content: "";
    height: 33.3%;
    aspect-ratio: 1;
    border-radius: inherit;
    box-shadow:
      inset 0 0 0.25em #4c4da3
    ;
    background:
      radial-gradient(#6667ac, transparent 50%) no-repeat 33.3% 10% / 75% 50%,
      radial-gradient(darken(#6667ac, 15), transparent 50%) no-repeat 60% 85% / 50% 50%,
      ;
    background-color: #080928;
  }
}
.screen {
  // opacity: 0;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  flex-grow: 1;
  gap: var(--gutter);
  box-sizing: border-box;
  width: 100%;
  position: relative;
  overflow: hidden;
  z-index: 1;
  padding: var(--gutter);
  padding-top: calc(var(--gutter) * 3);
  border-radius: calc(var(--border-radius) - var(--pad));
  transition: opacity 1s var(--ease-out) 0.25s;
}
.app {
  --col: 4;
  aspect-ratio: 1;
  border-radius: 20%;
  flex-basis: 15%;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2%;
  padding: 5%;
  box-sizing: border-box;
  font-size: 1.5em;
  --scale: 1.5;
  --duration: 0.8s;
  transform: scale3d(var(--scale), var(--scale), 1);
  animation: appear var(--duration) var(--ease-out) forwards;
  &:nth-child(1),
  &:nth-child(2) {
    flex-basis: 40%;
    border-radius: 15%;
    background: linear-gradient(190deg, var(--app-bg-s1, white) 33.3%, var(--app-bg-s2, var(--app-bg-s1, white))) top / 100% 125%;
  }
  &:not(:nth-child(1)):not(:nth-child(2)) {
    &:before {
      content: '';
      background: linear-gradient(190deg, var(--app-bg-s1, white), var(--app-bg-s2, var(--app-bg-s1, white))) top / 100% 125%;
      border-radius: inherit;
      position: absolute;
      inset: 0;
      filter: round-off();
    }
  }
  &:nth-child(1),
  &:nth-child(2),
  &:nth-child(3),
  &:nth-child(6),
  &:nth-child(7),
  &:nth-child(10) {
    --scale: 1.75;
    --duration: 1s;
  }
  &:nth-child(1) {
    --app-bg-s1: #{darken(#6490d2, 10)};
    --app-bg-s2: #6490d2;
    color: white;
    transform-origin: 125% 200%;
    &:after {
      content: 'Sunny';
    }
    .weather {
      display: flex;
      flex-direction: column;
      gap: 2%;
      &:before {
        content: 'Oakland';
      }
      &:after {
      font-size: 225%;
        content: '80°';
      }
    }
  }
  &:nth-child(2) {
    --app-bg-s1: #cbe2ae;
    --app-bg-s2: #{lighten(#cbe2ae, 15)};
    transform-origin: -25% 200%;
    &:before {
      content: '';
      align-self: flex-end;
      width: 40%;
      background: #f8d7a2;
      border: var(--border-width) solid white;
      aspect-ratio: 1;
      border-radius: 50%;
    }
    &:after {
      content: 'Hudson Ave';
      font-weight: 500;
      margin-top: auto;
    }
  }
  &:nth-child(3) {
    --app-bg-s1: #a7f88f;
    --app-bg-s2: #41c144;
    transform-origin: 175% 200%;
  }
  &:nth-child(4) {
    transform-origin: 75% 230%;
  }
  &:nth-child(5) {
    --app-bg-s1: #cecdd5;
    --app-bg-s2: #89888d;
    transform-origin: -25% 230%;
  }
  &:nth-child(6) {
    --app-bg-s1: #1ac5fb;
    --app-bg-s2: #1d71f2;
    transform-origin: -125% 200%;
  }
  &:nth-child(7) {
    --app-bg-s1: #fe9b01;
    --app-bg-s2: #f67324;
    transform-origin: 175% 80%;
  }
  &:nth-child(8) {
    --app-bg-s1: #cb65f0;
    --app-bg-s2: #8628bb;
    transform-origin: 75% 100%;
  }
  &:nth-child(9) {
    --app-bg-s1: #1d71f2;
    --app-bg-s2: #1ac8fd;
    transform-origin: -25% 100%;
  }
  &:nth-child(10) {
    transform-origin: -125% 80%;
  }
}
.pallette {
  position: relative;
  z-index: 1;
  order: 1;
  display: flex;
  gap: 2em;
  margin-right: 2.25em;
  margin-bottom: -.25em;
  &:hover ~ .phone-con .screen {
    transition-delay: 0.5s;
    opacity: 0;
  }
}
.zoom-con {
  order: 1;
}
// --------------
// Theme picker
// --------------
// Hide inputs
input[type="radio"],
input[type="checkbox"] {
  display: none;
}
.swatch {
  --swatch-size: max(30px,5em);
  --border-opacity: 0;
  background: white;
  width: var(--swatch-size);
  height: var(--swatch-size);
  border-radius: 50%;
  position: relative;
  cursor: pointer;
  border: max(1.5px, var(--border-width)) solid black;
  box-sizing: border-box;
  // transform: scale3d(0.85, 0.85, 1);
  background: radial-gradient(100% 100% at 50% 30%, var(--swatch-s1), var(--swatch-s2));
  opacity: 0;
  transform: translate3d(0, 20%, 0) scale3d(0.75, 0.75, 1);
  animation: appear 0.333s var(--ease-out) forwards 0.75s;
  display: flex;
  align-items: center;
  color: white;
  justify-content: center;
  outline: none;
  &:before {
    content: '';
    position: absolute;
    inset: -1px;
    border-radius: inherit;
    border: var(--border-width) solid black;
    background-image: radial-gradient(400% 300% at 50% 225%, transparent 20%, white);
    // filter: blur(0.2em);
    // box-shadow: inset 0 0 0.1em 0.1em black;
  }
  &:not([for="zoom"]) {
    &:after {     
      content: '';
      position: absolute;
      inset: calc(var(--border-width) * -1);
      border-width: inherit;
      border-style: inherit;
      opacity: var(--border-opacity);
      transition: 0.25s var(--ease-out);
      transition-property: opacity;
      border-radius: inherit;
    }
    &:hover {
      --border-opacity: 0.666;
    }
    &:focus {
      --border-opacity: 1;
    }
  }
  &:nth-child(1) {
    transform-origin: 100% 200%;
  }
  &:nth-child(2) {
    animation-delay: 0.8s;
    transform-origin: 80% 200%;
  }
  &:nth-child(3) {
    animation-delay: 0.85s;
    transform-origin: 50% 200%;
  }
  &:nth-child(4) {
    animation-delay: 0.9s;
    transform-origin: 40% 200%;
  }
  &:nth-child(5) {
    animation-delay: 0.95s;
    transform-origin: 20% 200%;
  }
  &[for="deep-purple"] {
    --swatch-s1: hsl(var(--deep-purple), 100%, 50%);
    --swatch-s2: hsl(calc(var(--deep-purple) - 60), 100%, 20%);
    &:before {
      opacity: 0.5;
    }
  }
  &[for="gold"] {
    --swatch-s1: hsl(var(--gold), 100%, 50%);
    --swatch-s2: hsl(var(--gold), 100%, 50%);
  }
  &[for="space-black"] {
    --swatch-s1: hsl(var(--space-black), 50%, 20%);
    --swatch-s2: hsl(var(--space-black), 50%, 10%);
    &:before {
      opacity: 0.5;
    }
  }
  &[for="silver"] {
    --swatch-s1: hsl(var(--silver), 50%, 80%);
    --swatch-s2: hsl(var(--silver), 50%, 10%);
    &:before {
      opacity: 0.75;
    }
  }
  &[for="random"] {
    &:before {
      background: none;
    }
    border-color: rgba(white, 0.25);
    transition: border-color 0.2s var(--ease-out);
    &:hover {   
      border-color: rgba(white, 0.75);
      .icon {
        opacity: 1;
      }
    }
    .icon {
      position: absolute;
      inset: 22.5%;
      background: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m18 15 3 3m0 0-3 3m3-3h-4l-1-1-1-1h-1m4-13 3 3m0 0-3 3m3-3h-4l-1 1-1 1-6 8-1 1-1 1H3M3 6h4l1 1 1 1 1 1' stroke='%23fff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain; 
      opacity: 0.75;
      transition: opacity 0.2s var(--ease-out);
    }
    #random:not(:checked) ~ .scene &:after {
      border: none;
    }
    #random:checked ~ .scene & {
      --swatch-s1: hsl(var(--r-h), var(--r-s), var(--r-l));
      --swatch-s2: hsl(var(--r-h), var(--r-s), calc(min(98%, var(--r-l) + 10%)));
      &:after {
        border-color: hsl(var(--r-h), 50%, 75%);
      }
      .icon {
        background: url("data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m18 15 3 3m0 0-3 3m3-3h-4l-1-1-1-1h-1m4-13 3 3m0 0-3 3m3-3h-4l-1 1-1 1-6 8-1 1-1 1H3M3 6h4l1 1 1 1 1 1' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain; 
      }
      &:hover,
      &:focus {
        .tooltip {
          pointer-events: all;
          opacity: 1;
        }
      }
    }   
  }
  &[for="zoom"] {
    --zoom-icon: url("data:image/svg+xml,%3Csvg width='32' height='32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m5 27 9-9m-9 9v-9m0 9h9M27 5l-9 9m9-9v9m0-9h-9' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    animation-delay: 1s;
    transform-origin: 40% 200%;
    border-color: rgba(white, 0.25);
    transition: border-color 0.2s var(--ease-out);
    &:before {
      background: none;
    }
    &:after {
      content: '';
      position: absolute;
      inset: 22.5%;
      background: var(--zoom-icon) center / cover;
      opacity: 0.75;
      transition: opacity 0.2s var(--ease-out);
    }
    &:hover {   
      border-color: rgba(white, 0.5);
      &:after {
        opacity: 1;
      }
    }
    &:focus {   
      border-color: rgba(white, 0.75);
      &:after {
        opacity: 1;
      }
    }
  }
}
// Deep Purple theme
.deep-purple {
  --c-h: var(--deep-purple);
  --g-hue-adjust: 40;
  --g-hue-adjust-2: 45;
  .section:last-of-type {
    --g-hue-adjust-2-y: 85%;
  }
}
// Gold theme
.gold {
  --c-h: var(--gold);
  --g-hue-adjust: 0;
  .section:last-of-type {
    --g-hue-adjust: 15;
    --g-hue-adjust-2: -190;
    --g-lightness: 82.5%;
  }
}
// Space Black theme
.space-black {
  --c-h: var(--space-black);
  --g-hue-adjust: 0;
  --g-lightness: 95%;
  .section:last-of-type {
    --g-hue-adjust: 215;
    --g-hue-adjust-2: -215;
  }
}
// Silver theme
.silver {
  --c-h: var(--silver);
  --c-s: 10%;
  --g-hue-adjust: 40;
  --g-lightness: 95%;
  --g-hue-adjust-2-y: 85%;
  .section:last-of-type {
    --g-hue-adjust-2: 15;
  }
  .glow {
    opacity: 0.25;
  }
}
$themes: 'deep-purple', 'gold', 'space-black', 'silver', 'random';
@each $theme in $themes {
  label[for="#{$theme}"]:after {
    border-color: hsl(var(--#{$theme}), 50%, 75%);
  }
  ##{$theme}:checked {
    ~ .scene .phone .bg .#{$theme} {
      opacity: 1;
      z-index: 1;
      transition-delay: 0s;
      .section:before {
        transition-delay: 0s;
        transform: scale3d(1,1,1) translate3d(0, 0 ,0);
      }
    }
    ~ .scene .pallette label[for="#{$theme}"] {
      --border-opacity: 1 !important;
    }
  }
}
// Zoom
#zoom:checked ~ .scene {
  --size: max(5px, 2vmin);
  opacity: 0;
  animation: appear 0.5s var(--ease-out) forwards;
  .phone {
    order: 1;
  }
  .pallette,
  .zoom-con {
    order: 0;
    font-size: 50%;
  }
  label[for="zoom"] {
    --zoom-icon: url("data:image/svg+xml,%3Csvg width='32' height='32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m14 18-9 9m9-9v9m0-9H5M18 14l9-9m-9 9V5m0 9h9' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}
#zoom:not(:checked) ~ .scene {
  opacity: 0;
  animation: appear-again 0.5s var(--ease-out) forwards;
  @keyframes appear-again {
    to {
      transform: scale3d(1,1,1);
      opacity: 1;
    }
  }
}
// Random gradient
.random {
  background: hsl(var(--r-h), var(--r-s), var(--r-l));
  &--colourful {
    --bm-outer: overlay;
    --bm-inner: difference;
  }
  &--moody {
    --bm-outer: exclusion;
    --bm-inner: multiply;
  }
  &--neon {
    --bm-outer: hue;
    --bm-inner: multiply;
  }
  &--abstract {
    --bm-outer: color-burn;
    --bm-inner: difference;
  }
  &--grayscale {
    --bm-outer: color-burn;
    --bm-inner: difference;
    filter: brightness(1.2) grayscale(100%) contrast(2);
  }
  &--light-leak {
    --bm-outer: color-burn;
    --bm-inner: multiply;
  }
}
.shapes {
  mix-blend-mode: var(--bm-outer, overlay);
  background: hsl(var(--r-h), var(--r-s), 85%);
  position: absolute;
  inset: 0%;
  z-index: 1;
  backface-visibility: hidden;
}
.shape {
  position: absolute;
  pointer-events: none;
  transition-property: background, inset, border-radius, filter, transform;
  will-change: inset, border-radius, filter;
  mix-blend-mode: var(--bm-inner, difference);
  top: 50%;
  left: 50%;
  aspect-ratio: 1/1;
  background: hsl(var(--r-h), var(--r-s), var(--r-l));
  width: var(--w, 99%);
  border-radius: var(--b-r, 55%);
  filter: blur(var(--b));
  transform: translate3d(calc(var(--x, -1%) - 50%), calc(var(--y, -8%) - 50%), 0) scale3d(var(--s-x, 1.9), var(--s-y, 1.15), 1) rotate(var(--r, 260deg));
}
.tooltip {
  --t-caret: 0.5em;
  position: absolute;
  z-index: 1;
  top: calc(100% + var(--t-caret) + 0.5em);
  white-space: nowrap;
  background: black;
  color: rgba(white, 0.75);
  padding: 0.25em;
  font-size: max(11px, 1em);
  border-radius: 0.25em;
  border: 1px solid lighten(black, 25);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s var(--ease);
  &:after {
    content: '';
    position: absolute;
    bottom: calc(100% - calc(var(--t-caret) / 2) - 1px);
    left: calc(50% - calc(var(--t-caret) / 2));
    border-radius: inherit;
    height: var(--t-caret);
    width: var(--t-caret);
    background: inherit;
    border: inherit;
    border-top-color: transparent;
    border-left-color: transparent;
    transform: rotate(-135deg);
  }
  #zoom:checked ~ .scene & {
    top: unset;
    bottom: calc(100% + var(--t-caret) + 0.5em);
    &:after {
      transform: rotate(45deg);
      top: calc(100% - calc(var(--t-caret) / 2) - 1px);
      bottom: unset;
    }
  }
}


js部分


// Tiny bit of JS to ensure that the notch doesn't move about when you resize the screen
const delay = 300;
let afterResize;
let currentStyle;
window.onresize = function(){
  document.body.classList.add('is-resizing');
    clearTimeout(afterResize);
    afterResize = setTimeout(() => document.body.classList.remove('is-resizing'), delay);
};
document.getElementById('zoom').addEventListener('click', () => {
  document.body.classList.add('is-resizing');
  setTimeout(() =>    document.body.classList.remove('is-resizing'), delay)
});
// Generating random gradient
let dimension = 1000; // Size of tile to be download px
const styles = ['colourful', 'moody', 'neon', 'abstract', 'grayscale', 'light-leak'];
const generateBtn = document.querySelector('[for="random"]');
const canvas = document.querySelector('.canvas');
const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min);
// Generate randomised gradients
generateBtn.addEventListener('click', generateOrSave);
function generateOrSave(e) {
  if (e.metaKey) {
    saveGradient(e);
  } else {
    generateGradient();
  }
}
function generateGradient() {
  // Assign style
  const newStyle = styles[Math.floor(Math.random() * styles.length)];
  // console.log(styles, styles[Math.floor(Math.random() * styles.length)]);
  if (currentStyle) canvas.classList.remove(`random--${currentStyle}`);
  currentStyle = newStyle;
  canvas.classList.add(`random--${newStyle}`);
  // Loop through each canvas and assign a bunch of random CSS variables
  const shapes = canvas.getElementsByClassName('shape');
  document.body.style.setProperty('--r-h', `${random(0, 360)}deg`);
  document.body.style.setProperty('--r-s', `${random(40, 90)}%`);
  document.body.style.setProperty('--r-l', `${random(55, 90)}%`);
  Object.values(shapes).forEach((shape) => {
    shape.style.setProperty('--r-h', `${random(0, 360)}deg`);
    shape.style.setProperty('--r-s', `${random(40, 90)}%`);
    shape.style.setProperty('--r-l', `${random(55, 90)}%`);
    shape.style.setProperty('--w', `${random(0, 30) + 85}%`);
    shape.style.setProperty('--b-r', `${random(20, 60)}%`);
    shape.style.setProperty('--b', `${random(5, 75) / 10}em`);
    shape.style.setProperty('--x', `${random(0, 100) - 50}%`);
    shape.style.setProperty('--y', `${random(0, 100) - 50}%`);
    shape.style.setProperty('--s-x', `${1 + ((random(0, 130) - 30) / 100)}`);
    shape.style.setProperty('--s-y', `${1 + ((random(0, 130) - 30) / 100)}`);
    shape.style.setProperty('--r', `${random(0, 720) - 360}deg`);
  })
}
// Convert RGB colour to Hex
// Needed for api.color.pizza call
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
// Save gradient
function saveGradient(e) {
  const gradient = canvas;
  const rect = gradient.getBoundingClientRect();
  const scale = dimension / rect.width
  //  Get canvas background color
  const color = rgba2hex(window.getComputedStyle(gradient, null).getPropertyValue('background-color'));
  console.log(color, scale, rect);
  // Get name of color for use in file name
  fetch(`https://api.color.pizza/v1/${color.substring(1)}`)
    .then(c => c.json())
    .then(c => {
      // console.log(c);
      // Convert DOM to canvas
      domtoimage.toPng(gradient, {
        bgColor: '#ffffff',
        width: rect.width * scale,
        height: rect.height * scale,
        style: {
            'transform': `scale(${scale})`,
            'transform-origin': 'top left'
         }
      })
      // Download image
      .then(function (dataUrl) {
        // const img = new Image();
        // img.src = dataUrl;
        // document.body.appendChild(img);
        // Render canvas as a link and click dat
        const link = document.createElement('a');
        link.download = `${currentStyle}-${c['paletteTitle'].toLowerCase().replaceAll(' ','-')}-gradient`;
        link.href = dataUrl;
        link.click();
      })
  });
}
相关文章
|
4月前
|
前端开发
Element UI 【实战】纯前端对表格数据进行增删改查(内含弹窗表单、数据校验、时间日期格式)
Element UI 【实战】纯前端对表格数据进行增删改查(内含弹窗表单、数据校验、时间日期格式)
185 6
|
14天前
|
前端开发 JavaScript
Bootstrap Web 前端 UI 框架
Bootstrap 是快速开发 Web 应用程序的前端工具包。
30 3
|
2月前
|
前端开发 开发者 UED
前端只是切图仔?来学学给开发人看的UI设计
该文章针对前端开发者介绍了UI设计的基本原则与实践技巧,覆盖了布局、色彩理论、字体选择等方面的知识,并提供了设计工具和资源推荐,帮助开发者提升产品的视觉与交互体验。
|
3月前
|
开发者 C# Android开发
明白吗?Xamarin与Native的终极对决:究竟哪种开发方式更适合您的项目需求,让我们一探究竟!
【8月更文挑战第31天】随着移动应用开发的普及,开发者面临多种技术选择。本文对比了跨平台解决方案Xamarin与原生开发方式的优势与劣势。Xamarin使用C#进行跨平台开发,代码复用率高,可大幅降低开发成本;但因基于抽象层,可能影响性能。原生开发则充分利用平台特性,提供最佳用户体验,但需维护多套代码库,增加工作量。开发者应根据项目需求、团队技能和预算综合考量,选择最适合的开发方式。
106 0
|
3月前
|
JavaScript 前端开发 开发者
决战前端之巅!Element UI与Vuetify谁才是Vue.js组件界的霸主?一场关于颜值与实力的较量!
【8月更文挑战第30天】本文对比了两款热门的Vue.js组件库——Element UI与Vuetify。Element UI由饿了么团队打造,提供多种高质量UI组件,设计简洁大方。Vuetify基于Material Design规范,支持Vue.js 2.0及3.0版本,具备前瞻性。两者均涵盖表单、导航、数据展示等组件,Element UI配置选项丰富,而Vuetify则提供了更深层的样式定制功能。开发者可根据项目需求及个人偏好选择合适的组件库。
249 0
|
4月前
|
编解码 前端开发 UED
UI/UX设计在前端开发中的重要性
【7月更文挑战第27天】综上所述,UI/UX设计在前端开发中具有不可替代的重要性。它们不仅决定了产品的视觉呈现和交互体验,还影响了用户的满意度、品牌形象、转化率和技术创新等多个方面。因此,在前端开发过程中,我们应该高度重视UI/UX设计的作用和价值,与设计师紧密合作共同打造出优秀的产品。
|
5月前
|
前端开发 JavaScript Java
SSMP整合案例第六步 在前端页面上利用axios和element-ui与后端交互实现增删改
SSMP整合案例第六步 在前端页面上利用axios和element-ui与后端交互实现增删改
43 1
|
4月前
|
前端开发 API
前端框架与库 - Material-UI组件库
【7月更文挑战第20天】Material-UI 是一个基于 React 的 UI 组件库,它遵循 Google 的 Material Design 设计规范,提供了丰富的预构建组件,极大地简化了前端开发过程。本文将深入浅出地介绍 Material-UI 的常见问题、易错点及如何避免这些问题,并附带代码示例,帮助你更好地掌握 Material-UI 的使用技巧。
145 0
前端开发
17 0
|
4月前
|
前端开发
ElementPlus卡片如何能够一行呈四,黑马UI前端布局视频资料,element样式具体的细节无法修改,F12找到那个位置,可能在其他组件写了错误,找到那个位置,围绕着位置解决问题最快了,卡片下边
ElementPlus卡片如何能够一行呈四,黑马UI前端布局视频资料,element样式具体的细节无法修改,F12找到那个位置,可能在其他组件写了错误,找到那个位置,围绕着位置解决问题最快了,卡片下边