灵动岛,是苹果公司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 问世五年来的第一个重大操作变化。

我主要实现的是从灵动岛跳转csdn主页的动画效果,大家有需要可以在html部分更改跳转的链接(iframe部分)
%iframe#doom{:height => "800", :src => "https://blog.csdn.net/weixin_43233219?spm=1019.2139.3001.5343/", :width => "1200"}
tips:但是该代码的缺点是目前该跳转链接和灵动岛的大小以及Ui不匹配

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) 1px0px / 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
);
再增加一个前端灵动岛的ui效果源码,可以 切换界面的Ui主题颜色,有官方的几个配色和随机配色
效果图如下

.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.pallettelabel.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-conlabel.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,#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 screenconst 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 gradientlet dimension = 1000; // Size of tile to be download pxconst 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 gradientsgenerateBtn.addEventListener('click', generateOrSave);function generateOrSave(e) {if (e.metaKey) {saveGradient(e);} else {generateGradient();}
}function generateGradient() {// Assign styleconst 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 variablesconst 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 colorconst color = rgba2hex(window.getComputedStyle(gradient, null).getPropertyValue('background-color'));console.log(color, scale, rect);// Get name of color for use in file namefetch(`https://api.color.pizza/v1/${color.substring(1)}`).then(c => c.json()).then(c => {// console.log(c);// Convert DOM to canvasdomtoimage.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 datconst link = document.createElement('a');link.download = `${currentStyle}-${c['paletteTitle'].toLowerCase().replaceAll(' ','-')}-gradient`;link.href = dataUrl;link.click();})});}