灵动岛前端Ui

news2024/12/26 0:03:20

一、前言

灵动岛(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 问世五年来的第一个重大操作变化。
在这里插入图片描述

我主要实现的是从灵动岛跳转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();
			})
	});
	
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/115600.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【大数据】M1 mac win docker安装kafka+mysql+canal

文章目录kafkadocker-compose创建kafka容器启动以后&#xff0c;访问容器&#xff0c;并且发送消息测试问题Exception in thread "main" kafka.zookeeper.ZooKeeperClientTimeoutException: Timed out waiting for connection while in state: CONNECTINGmysqldocker…

LAPS本地管理员密码之使用PowerShell查看和重置密码

目录 一、PowerShell策略设置 二、引入AdmPwd.PS模块 三、查看密码 四、强制重置密码 文章主要介绍在部署了LAPS后&#xff0c;怎么使用PowerShell查看和管理域内本地管理员密码。需要注意的是被操作的电脑需要加域&#xff0c;所有操作都在域内环境下进行。 LAPS介绍 LAP…

Spring Boot 知识总结

Spring Boot 知识总结 一、Spring Boot基础 1.1 什么是Spring Spring是一个开源框架&#xff0c;2003年兴起的一个Java轻量级开发框架&#xff0c;作者&#xff1a;Rod Johnson。 Spring是为了解决企业级应用开发的复杂性而创建的&#xff0c;简化开发。 Spring是如何简化…

LeetCode 每日一题——1759. 统计同构子字符串的数目

1.题目描述 1759. 统计同构子字符串的数目 难度中等43 给你一个字符串 s &#xff0c;返回 s 中 同构子字符串 的数目。由于答案可能很大&#xff0c;只需返回对 109 7 取余 后的结果。 同构字符串 的定义为&#xff1a;如果一个字符串中的所有字符都相同&#xff0c;那么…

Rancher RFO 正式 GA

Rancher RFO GA RFO 是 Rancher For openEuler 的缩写&#xff0c;旨在面向 openEuler 打造 Rancher 基础平台。其中最核心的工作是打造一款面向 openEuler 生态的 Kubernetes 发行版。它基于上游 RKE2 的技术栈&#xff0c;构建物采用 openEuler base image&#xff0c;致力于…

C语言及算法设计课程实验一:C程序的运行环境和运行C程序的方法

C语言及算法设计课程实验一&#xff1a;C程序的运行环境和运行C程序的方法一、实验目的二、实验内容2.1、输人并运行一个简单的正确的程序2.2、输人并编辑一个有错误的C程序2.3、输入并运行一个需要在运行时输入数据的程序2.4、运行一个自己编写的程序三、实验步骤3.1、输人并运…

Android OpenGL ES 学习(十一) –渲染YUV视频以及视频抖音特效

OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学习(三) – 绘制平面图形 Android OpenGL ES 学习(四) – 正交投影 Android OpenGL ES 学习(五) – 渐变色 Android OpenGL ES 学习(六) – 使用…

基于MWORKS.Sysplorer的电子控制器应用案例——永磁同步电机FOC算法建模

1 前言 MWORKS是面向数字工程的新一代科学计算与系统建模仿真平台&#xff0c;可提供机械、电子、液压、控制、热、信息等多领域统一建模仿真环境。经过同元持续攻关&#xff0c;全新推出的MWORKS.Sysplorer嵌入式代码生成器&#xff0c;现已支持面向电子控制器的产品级的嵌入…

循环神经网络的简洁实现

参考8.6. 循环神经网络的简洁实现 — 动手学深度学习 2.0.0 documentation 本节将展示如何使用深度学习框架的高级API提供的函数更有效地实现相同的语言模型。 我们仍然从读取时光机器数据集开始。 pip install mxnet1.7.0.post1 pip install d2l0.15.0 from mxnet import n…

ubuntu18.04下用Fiddler抓取curl库网络数据包总结

本人在ubuntu18.04下进行开发&#xff0c;需要使用http和服务端进行通信&#xff0c;为了确认自己发送给服务端和服务端返回数据字段&#xff0c;所以需要进行抓包分析参数。本文就说明一下如何在ubuntu18.04使用fidder对自己编写的应用程序进行http协议数据包抓取。 目录 1.…

无线网络渗透测试清单

©网络研究院 无线渗透测试积极检查 WiFi 网络中的信息安全措施的过程&#xff0c;并分析弱点、技术流程和关键无线漏洞。 我们应该关注的最重要的对策是威胁评估、数据盗窃检测、安全控制审计、风险预防和检测、信息系统管理和升级基础设施&#xff0c;并且应该准备一份…

13-14-15-RabbitMq工作模式深度剖析与Spring整合MQ以及RabbitMq高级特性

RabbitMQ消息传递流程 连接( Connection) 在RabbitMQ中&#xff0c;生产者和消费者与RabbitMQ的通信就是基于TCP连接的。不过呢我们知道TCP连接的创建和销毁在高并发场景下对于操作系统来说都是特别昂贵的开销&#xff0c;所以RabbitMQ又引入了信道的概念 信道&#xff08;Chan…

云原生之使用Docker部署轻量级web服务器lighthttpd

云原生之使用Docker部署轻量级web服务器lighthttpd一、Lighthttpd介绍二、检查系统版本三、检查docker状态四、下载lighthttpd镜像五、部署lighthttpd1.创建数据目录2.创建lighthttpd容器3.查看容器状态六、访问lighthttpd服务七、编辑index.html1.编辑index.html文件2.重新访问…

Hadoop大数据存算分离方案:计算层无缝对接存储系统

Hadoop的诞生改变了企业对数据的存储、处理和分析的过程&#xff0c;加速了大数据的发展。随着大数据系统建设的深入&#xff0c;企业的数据基础设施易出现计算资源浪费、存储性能低、管理成本过高等挑战。相比存算一体架构&#xff0c;存算分离架构具有性能与成本最优、兼具灵…

3D地图app

3D三维地图APP 发布时间&#xff1a;2018-07-19 版权&#xff1a; 3D地图依据高程数据等对地表进行渲染&#xff0c;实现地表的起伏&#xff0c;模拟出真实的三维场景&#xff0c;让你有如身临其境般的感觉。 &#xff08;注&#xff1a;Bigemap 3D地图是一个三维地图浏览功能…

项目沟通怎么才能不像在吵架?

项目沟通并非吵架&#xff0c;看起来却总是剑拔弩张。有效沟通才能真正解决问题&#xff0c;笔者给出了一些实用的建议&#xff0c;从对象到场景&#xff0c;再到方法与技巧&#xff0c;应该在沟通中有针对性地注意这些问题。 沟通是个老话题&#xff0c;在项目管理中有专门讲沟…

draw.io使用教程

大部分的绘图应用都离不开三个基本的元素&#xff0c;图形&#xff0c;链接&#xff0c;文本。每个元素都有基本的操作和样式&#xff0c;元素与元素之间又可以进行组合&#xff0c;“三生万物”&#xff0c;生成各种各样的图表。 如果没有这款绘图的 可以点击获取 : drawio文…

企业项目管理的不同与好处

大型企业组织通常同时运行多个复杂项目。尽管这些项目看起来不一定相互关联&#xff0c;但它们都会影响同一个企业组织。企业项目管理(EPM)是指在公司范围内管理项目的实践。它通常涉及实施战略和流程&#xff0c;以大规模简化和提高项目管理的有效性。根据项目管理协会(PMI)的…

burpsuite靶场——XXE

文章目录什么是XML&#xff1f;什么是XML实体&#xff1f;什么是文档类型定义(DTD)&#xff1f;什么是XML自定义实体&#xff1f;什么是XML外部实体&#xff1f;使用外部实体利用 XXE 来检索文件利用 XXE 执行 SSRF 攻击盲XXE漏洞带外交互的盲 XXE过 XML 参数实体进行带外交互的…

【AJAX】AJAX的跨域问题

AJAX的跨域问题跨域的概述区别同源与不同源同源策略有什么用&#xff1f;AJAX跨域解决方案方案一、设置响应头方案二、jsonp方案三、代理机制&#xff08;httpclient&#xff09;跨域的概述 跨域是指从一个域名的网页去请求另一个域名的资源。比如从百度&#xff08;https://ba…