首页
关于
Search
1
如何使用img标签和picture标签的srcset/sizes属性
307 阅读
2
ES6 更新内容简介
284 阅读
3
使用Git进行版本控制
216 阅读
4
CSS动画实现
203 阅读
5
vue3之Composition API
175 阅读
WEB前端
CSS
VUE
HTML
小记
登录
Search
标签搜索
游戏
JavaScript
异步
动画
Shthah
累计撰写
36
篇文章
累计收到
59
条评论
首页
栏目
WEB前端
CSS
VUE
HTML
小记
页面
关于
搜索到
28
篇与
的结果
2023-11-08
网页自定义Audio标签样式
audio 标签属性src:指定音频文件的URL。可以是本地文件路径或远程URL。autoplay:表示音频是否自动播放。如果设置这个属性,音频会在页面加载完成后立即开始播放。controls:显示浏览器内置的音频控件,如播放/暂停按钮、音量控制等。 controlsList="nodownload noplaybackrate" nodownload 不显示下载按钮 nofullscreen: 不要全屏按钮 noplaybackrate 不要播放速度按钮 noremoteplayback: 不要远程回放 disablePictureInPicture 禁止画中画按钮loop:指定音频是否循环播放。preload:指定音频在页面加载时的预加载行为。可选值有:none:不进行预加载。metadata:仅加载音频的元数据(比如时长、编码等)。auto:自动选择最合适的预加载方式。muted:表示音频是否静音。如果设置为true,音频将被静音。volume:指定音频的音量大小。取值范围为0.0到1.0之间。<div class="modal-audio"> <div v-if="audioSource" class="aiAudio-box"> <audio ref="audioPlayer" id="aiAudio" controls :muted="!isMuted" controlsList="nodownload noplaybackrate" @canplay="changeAudio($event,'allTime')" @timeupdate="changeAudio($event,'getCurrentTime')"> <source :src="audioSource" type="audio/mpeg"> </audio> <!-- 自定义 播放暂停 --> <span class="play-button" v-if="!isPlaying" @click="pauseAudio"></span> <span class="pause-button" v-else @click="playAudio"></span> <!-- 自定义 音量 静音 --> <span class="volume-button" v-if="isMuted" @click="toggleMute"></span> <span class="mute-button" v-else @click="toggleMute"></span> <!-- 自定义 时间 --> <span class="audio-time"> <!-- {{ currentTimeLabel + ' / ' + allTimeLabel }} --> </span> <!-- 自定义 进度条 --> <input type="range" class="audio-range" ref="audioPlayInput" step="0.01" :max="allTime" :value="currentTime" @change="changeAudio($event,'changeCurrentTime')" /> </div> </div>.modal-audio { padding: 20px 20px 0; display: flex; justify-content: center; .aiAudio-box { position: relative; #aiAudio { height: 50px; border: 1px solid #b292f4; border-radius: 40px; object-fit: initial; } .play-button, .pause-button { position: absolute; left: 13px; top: 11px; display: inline-block; width: 28px; height: 28px; background-size: cover; } .play-button { background-image: url("https://shthah.cn/audio/play.webp"); } .pause-button { background-image: url("https://shthah.cn/audio/pause.webp"); } .volume-button, .mute-button { position: absolute; left: 255px; top: 11px; display: inline-block; width: 28px; height: 28px; background-size: cover; } .volume-button { background-image: url("https://shthah.cn/audio/volume.webp"); } .mute-button { background-image: url("https://shthah.cn/audio/mute.webp"); } .audio-time { position: absolute; top: 14px; left: 48px; color: #454545; } .audio-range { position: absolute; top: 22px; left: 133px; width: 110px; } input[type="range"].audio-range { outline: none; -webkit-appearance: none; /*清除系统默认样式*/ background: -webkit-linear-gradient(#b292f4, #b292f4) no-repeat, rgba(0, 0, 0, 0.19); background-size: 0% 100%; /*设置左右宽度比例*/ height: 5px; border-radius: 5px; } /*拖动块的样式*/ input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; /*清除系统默认样式*/ height: 13px; width: 13px; background: #b292f4; border-radius: 50%; border: solid 1.5px #fff; } } audio::-webkit-media-controls-timeline-container, audio::-webkit-media-controls-seek-back-button, audio::-webkit-media-controls-seek-forward-button { background-color: #555; } // 整个音频控制面板的容器 audio::-webkit-media-controls-panel { background: #fcfbff; } // 静音按钮 audio::-webkit-media-controls-mute-button { background-image: none; } // 播放按钮 暂停 audio::-webkit-media-controls-play-button { background-image: none; } audio::-webkit-media-controls-pause-button { background-image: none; } // 包含时间轴的容器 audio::-webkit-media-controls-timeline-container { background-color: #b292f4; } // 当前播放时间显示 剩余播放时间显示 时间轴 audio::-webkit-media-controls-current-time-display, audio::-webkit-media-controls-time-remaining-display, audio::-webkit-media-controls-timeline { display: none; } }
2023年11月08日
68 阅读
0 评论
0 点赞
2023-08-11
electron 开发 页面调用require is not a function
require is not a function错误。由于require可以直接请求运行客户机上的文件,容易引起安全问题,而在Electron 12以后的版本中被禁止。解决方案如果需要直接使用客户机上的文件,则需要设置web上下文contextIsolation选项为false。 webPreferences: { nodeIntegration: true, contextIsolation: false}修改后,本地使用require时,程序就正常跑起来了。
2023年08月11日
68 阅读
0 评论
0 点赞
2023-06-06
vue3之Composition API
Composition API也叫组合式API,是Vue3.x的新特性。通过创建 Vue 组件,我们可以将接口的可重复部分及其功能提取到可重用的代码段中。仅此一项就可以使我们的应用程序在可维护性和灵活性方面走得更远。然而,我们的经验已经证明,光靠这一点可能是不够的,尤其是当你的应用程序变得非常大的时候——想想几百个组件。在处理如此大的应用程序时,共享和重用代码变得尤为重要创建一个可组合函数创建一个简单的可组合函数。下面count是具有无功值的组件的示例。使用Composition API的计数器示例<script setup> import { ref } from "vue"; const count = ref(0); const increment = () => { count.value++; }; </script> <template> <button @click="increment"> Clicked {{ count }} times </button> </template>Options API 表示法主要在 Vue 2 之前使用,它不允许您从组件中提取状态。然而,随着 Composition API 的出现,现在可以将状态提取到外部函数。这允许跨多个组件重用逻辑。以下可组合函数是使用 Composition API将上述组件提取到外部useCounter()的示例。useCounter.ts import { ref } from "vue"; export const useCounter = () => { const count = ref(0); const increment = () => { count.value++; }; return { count, increment, }; };组件可以调用和使用它们。APP.vue <script setup> import { useCounter } from "./useCounter"; const { count, increment } = useCounter(); </script>useCounter()通过创建 ,不仅简化了组件内部的描述,而且好处是可以在其他组件中重用相同的逻辑。通常,每次需要时都必须创建这样的可组合函数,但人们已经意识到存在经常使用的可组合函数。
2023年06月06日
175 阅读
1 评论
1 点赞
2023-04-10
CSS背景边框滚动效果
通过圆锥渐变设置背景,再控制背景旋转 <div class="container"> <a class="card-bg" href="#"></a> <a class="card" href="#"></a> </div>// 自定义渐变角度属性 @property --gradient-angle { syntax: "<angle>"; initial-value: 0turn; inherits: false; } .card { animation: 2s gradient-angle infinite linear; border: 2px solid transparent; background-image: linear-gradient(#584827, #2d230f), conic-gradient( from var(--gradient-angle), #584827 0%, #c7a03c 37%, #f9de90 30%, #c7a03c 33%, #584827 40%, #584827 50%, #c7a03c 77%, #f9de90 80%, #c7a03c 83%, #584827 90% ); background-clip: padding-box, border-box; background-origin: padding-box, border-box; } .card-bg { animation: 2s gradient-angle infinite linear; border: 2px solid transparent; background-image: conic-gradient( from var(--gradient-angle), #584827 0%, #c7a03c 37%, #f9de90 30%, #c7a03c 33%, #584827 40%, #584827 50%, #c7a03c 77%, #f9de90 80%, #c7a03c 83%, #584827 90% ); background-clip: border-box; background-origin: border-box; } @keyframes gradient-angle { to { --gradient-angle: 1turn; } } html, body { background: #141819; } .container { display: flex; justify-content: center; } .card,.card-bg { display: grid; min-width: 200px; margin:20px; padding: 20px; color: currentColor; border-radius: 20px; aspect-ratio: 1/1; }@property@property 是一个 CSS Houdini API,它允许开发人员定义自定义 CSS 属性。在你的例子中, --gradient-angle 可能是你想要定义的一个自定义渐变角度属性。通过使用 @property,你可以为这个属性指定类型、初始值等信息。你可以尝试下面这样定义 --gradient-angle 自定义属性:@property --gradient-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }在这个示例中,我们定义了 --gradient-angle 的语法为 (表示一个角度值),不继承父元素的值,并且初始值为 0deg。在 CSS 中,@property 规则中的 syntax 值用于定义属性值的语法规则。以下是一些常见的 syntax 值::表示长度值,比如 px, em, rem 等。:表示百分比值,比如 50%, 100% 等。:表示颜色值,比如 red, #00ff00, rgba(255, 0, 0, 0.5) 等。:表示角度值,比如 0deg, 90deg, 180deg 等。:表示数字值,可以带小数点,比如 1, 2.5, -10.75 等。:表示字符串值,需要用引号括起来,比如 "Hello", 'World' 等。:表示 URL 值,比如 url('example.com/image.jpg').:表示自定义标识符(identifier),通常用于自定义属性名称。
2023年04月10日
124 阅读
0 评论
0 点赞
2023-04-09
CSS 动画-渐变段落-按钮边框
渐变段落<div style="background:#000"> <p class="text-flowLight"> 我是一段文字,看看看我的效果 </p> </div>.text-flowLight { position:relative; background-image:-webkit-linear-gradient(left,#1A3375,#b2c8ff,#1A3375 100%); -webkit-text-fill-color:transparent; -webkit-background-clip:text; -webkit-background-size:200% 100%; -webkit-animation:masked-animation 5s forwards linear infinite; font-weight:700; white-space:nowrap } @keyframes masked-animation { from { background-position:0 0 } to { background-position:-200% 0 } }按钮边框<div class="rabut"> <a href="###">炫酷边框特效</a> </div>body { background-color: black; } .rabut { width: 200px; height: 50px; color: #69ca62; /* 外面围绕的边框是真边框,眼睛看见的边框是阴影效果 */ box-shadow: inset 0 0 0 1px rgba(105, 202, 98, 0.5); background-color: #0f222b; } .rabut { text-align: center; margin: 100px auto; } .rabut, .rabut::before, .rabut::after { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .rabut::before, .rabut::after { content: ""; margin: -5%; box-shadow: inset 0 0 0 2px; animation: clipMe 8s linear infinite; } .rabut::before { animation-delay: -4s; } .rabut:hover::after, .rabut:hover::before { background-color: rgba(255, 0, 0, 0.3); } /* 核心:更改宽高后这下面的动画效果也需修改 */ @keyframes clipMe { 0%, 100% { /* 上 右 下 左*/ /* 上-下=-2px,右-右=220px 显示盒子上边框 */ clip: rect(0px, 220px, 2px, 0px); } 25% { /* 上-下=-70px,右-右=2px 显示盒子左边框 */ clip: rect(0px, 2px, 70px, 0px); } 50% { /* 上-下=-2px,右-右=220px 显示盒子下边框 */ clip: rect(68px, 220px, 70px, 0px); } 75% { /* 上-下=-70px,右-右=2px 显示盒子右边框 */ clip: rect(0px, 220px, 70px, 218px); } } .rabut a { font-size: 20px; line-height: 50px; text-decoration: none; color: #404d5b; }
2023年04月09日
80 阅读
0 评论
0 点赞
2023-03-10
CSS 实现漂亮的鼠标悬停效果
CSS Filter 是一种 CSS 功能,可让您获得模糊和颜色调整等图形效果只需指定您要应用的CSS属性filter的类型。例如,如果指定以下内容,则 HTML 元素将显示应用的效果。使用亮度的表现brightness()我们使用亮度调节方法。要使鼠标悬停在照片上时显得更亮,:hover只需为正常时间和时间设置不同的滤镜值,并使用 CSS Transition 添加动画即可。.effect-brightness { transition: filter 0.3s ease; filter: brightness( 1 ); /* 因为是默认值,所以可以省略这一行 */ } .effect-brightness:hover { filter: brightness(1.75); /* 添加亮度 */ }使用亮度的表现(闪烁)您只需更改 CSS 过渡即可创建各种变体。通过添加将鼠标悬停在其上方时瞬间闪烁的表情,可以给人一种轻快运动的印象。通过添加边框,可以给人留下鲜明的印象。transition生产的技巧是为正常时间和悬停时间指定不同的属性。.effect-flash { border: 1px solid rgba(255, 255, 255, 0%); filter: brightness(1.0); transition: filter 1s, border-color 1s ; } .effect-flash:hover { border: 1px solid rgba(255, 255, 255, 100%); transition: border-color 0.2s; animation: bright-flash 0.2s linear forwards; /* CSS Animation 动画。最后维持最终态 */ } @keyframes bright-flash { 0% { filter: brightness(2.5); } 100% { filter: brightness(1.25); } }使用饱和度一种将正常状态设置为单色并在鼠标悬停时取消单色的技术。通过将其设为单色,您可以用它来表达整体优雅的设计。这种表达对于化妆品和服装等品牌广告网站非常有用。.effect-mono { filter: grayscale(100); transition: filter 0.2s; } .effect-mono:hover { filter: grayscale(0); }使用亮度的表现(最适合按钮)brightness()此表达式非常适合具有多态设计的按钮。光滑的设计与亮度的变化相得益彰,单个按钮图像营造出漂亮的效果。即使设计者只提供普通的按钮图像,它也很有用,因为它很容易设置。.btn { filter: brightness(1); transition: filter 0.3s; } .btn:hover { filter: brightness(1.15); } .btn:active { filter: brightness(0.85); }使用模糊的表现一种当鼠标悬停时显示附加信息的技术。.effect-blur-thumb { transition: all 0.3s ease; width: 100%; } .effect-blur:hover .effect-blur-thumb { /* 悬停时调整亮度 */ filter: blur(8px) brightness(1.5); transform: scale(1.1); }
2023年03月10日
145 阅读
0 评论
0 点赞
2023-03-09
Promise.all
promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果。promise.all中只要有一个失败了,走.catch(),在.catch()中获取第一个失败请求rejected抛出的结果。在 Promise.all 中,如果其中任何一个 Promise 被 rejected 或抛出异常,则整个 Promise.all 将会立即被 reject,而不会等到其他 Promise 完成。具体地说,一旦一个 Promise 失败,Promise.all 就会中止并返回一个新的拒绝状态的 Promise。然后**,其他未完成的 Promise 将会继续运行,但是它们的结果将会被忽略,不会进一步处理。等待多个 Promise创建一些模拟任务并逐一等待它们:const tasks = [ { id: 'A', durationMs: 2000, fulfills: true }, { id: 'B', durationMs: 3000, fulfills: true }, { id: 'C', durationMs: 1000, fulfills: true }, ]; try { for (const task of tasks) { await doTask(task); } console.log('success'); } catch (e) { console.log('failure'); }输出:Promise A: fulfilled ✅约 2 秒后 ( t=2)。Promise B: fulfilled ✅约 3 秒后 ( t=5)。Promise C: fulfilled ✅约 1 秒后 ( t=6)。这段代码可以运行,但速度很慢,因为它在循环的每次迭代中一次构造一个 Promise for-of,因此未来的 Promise 只有在之前的 Promise 都已实现后才会构造。如果第一个 Promise 需要很长时间才能实现,但未来的 Promise 需要的时间较少,我们最终会浪费时间,因为我们本可以安排那些更快的 Promise 回调更早运行。事实上,在实际实现中,doTask可能会向服务器发出网络请求。使用我们当前的方法,这意味着我们一次发出一个网络请求,这不必要地慢,因为浏览器支持并发网络请求。同步构建 Promise提前构建所有 Promise 然后等待它们会更有效率。这样,如果 Promise 执行器函数发出网络请求,这些请求可以由运行时并发处理。const tasks = [ { id: 'A', durationMs: 2000, fulfills: true }, { id: 'B', durationMs: 3000, fulfills: true }, { id: 'C', durationMs: 1000, fulfills: true }, ]; try { const promises = tasks.map((task) => doTask(task)); for (const promise of promises) { await promise; } console.log('success'); } catch (e) { console.log('failure'); }在此示例中,我们将每个任务映射到 的结果doTask,该结果返回一个 Promise。因此,我们得到了一个待定 Promises 数组:[Promise {<pending>}, ..., Promise {<pending>}]这一次,如果doTask浏览器发出网络请求,它可以发出多个并发请求,因为我们提前构造了所有 Promises。我们仍然会按照构造顺序一次等待一个 Promises,但不同之处在于其他网络请求可以在后台处理,而无需我们等待。如果任何单个 Promise 拒绝,上述代码实际上会抛出未捕获的错误解决方案:Promise.allPromise.all接受一个 Promise 的可迭代对象并返回一个新的外部 Promise,一旦所有单个 Promise 都已实现,该外部 Promise 便会实现,而一旦单个 Promise 拒绝,该外部 Promise 便会拒绝。此外,如果Promise.all实现,它会使用所有单个已实现值的数组来实现。try { const values = await Promise.all([p1, p2, ..., pn]); console.log('All promises fulfilled', values); } catch (e) { console.log('A promise rejected'); }Promise.all这比一次等待一个 Promises 更快,因为在调用时 Promises 已经构造好了。const tasks = [ { id: 'A', durationMs: 2000, fulfills: true }, { id: 'B', durationMs: 3000, fulfills: true }, { id: 'C', durationMs: 1000, fulfills: true }, ]; try { await Promise.all(tasks.map((task) => doTask(task))); console.log('Promise.all fulfilled'); } catch (e) { console.log('Promise.all rejected'); }如果 Promise 执行器函数doTask发起网络请求,我们可以看到性能的大幅提升,因为一旦构建了 Promise,浏览器就会同时执行这些网络请求。相比之下,在我们的第一个for-of循环方法中,我们必须在循环的每次迭代中一次发出一个网络请求。如果第一个请求需要很长时间才能解决,那么后续可能在很长一段时间内都不会被创建。但是,不要误Promise.all以为这是真正的并行;Promise回调仍会在事件循环中一次排队一个,并且永远不会同时运行。队列总是一次弹出一个项目,事件循环每次只运行一件事。失败状态const tasks = [ { id: 'A', durationMs: 2000, fulfills: true }, { id: 'B', durationMs: 3000, fulfills: true }, { id: 'C', durationMs: 1000, fulfills: false }, // rejects ]; try { await Promise.all(tasks.map((task) => doTask(task))); console.log('Promise.all fulfilled'); } catch (e) { console.log('Promise.all rejected'); } Promise C: rejected ❌ Promise.all rejected Promise A: fulfilled ✅ Promise B: fulfilled ✅请注意 Promise C 会提前拒绝,因为我们不会等待其他 Promise 解决后再构造并等待它。但更重要的是,Promise.all根据规范,Promise C 拒绝后会立即拒绝。这很棒,因为这意味着我们不必等待其余 Promise 解决 - 只要一个 Promise 拒绝,我们就可以立即开始处理错误情况。此行为称为快速失败。Promise.all不会立即取消Promise.all剩余的待处理 Promise。因此,剩余的 Promise 回调仍然会在事件循环中排队,并在轮到它们时运行。因此,即使在 Promise C 被拒绝后被拒绝,Promise A 和 B 仍然有机会解决。只是我们不必等待其他Promise 解决后再拒绝外部 Promise,这使我们能够更快地处理拒绝。如果 Promise A 或 Promise B 在被拒绝后又被拒绝,会发生什么情况Promise.all?从技术上讲,它们只会拒绝Promise.all已经被拒绝的 Promise。而拒绝已解决的 Promise 不会产生任何效果。
2023年03月09日
122 阅读
0 评论
0 点赞
2023-01-06
CSS动画实现
“关闭”的变形动画{collapse}{collapse-item label="代码实现" } .container-bg { background-image: linear-gradient(135deg, #8ecbe6, #e743c3); } .hm-line-top, .hm-line-middle, .hm-line-bottom { --height: 3px; display: block; width: 100%; height: var(--height); transition: 0.3s; transform-origin: center; background-color: #fff; position: absolute; top: calc(50% - var(--height) / 2); left: 0; } .hm-line-top { translate: 0 14px; } .hm-line-bottom { translate: 0 -14px; } .hm-button { position: relative; display: inline-flex; width: 48px; height: 48px; appearance: none; background: none; border: none; cursor: pointer; &.active { .hm-line-middle { opacity: 0; rotate: 90deg; } .hm-line-top { translate: 0 0; rotate: -135deg; } .hm-line-bottom { translate: 0 0; rotate: 135deg; } } } <div class="container container-bg"> <button class="hm-button" aria-label="开启"> <span class="hm-line-top"></span> <span class="hm-line-middle"></span> <span class="hm-line-bottom"></span> </button> </div> const button = document.querySelector(".hm-button"); button.addEventListener("click", () => { const current = button.classList.contains("active"); const next = !current; button.classList.toggle("active", next); button.setAttribute("aria-label", next ? "关闭" : "开启"); });{/collapse-item}{/collapse}圆形按钮悬停动画中心有图标的圆形按钮的悬停动画。心形随着旋转而改变颜色,背景圆圈变为透明的旋转虚线。{collapse}{collapse-item label="代码实现" } .content-bg-heart { background-image: linear-gradient(135deg, #ffc46e, #f043bf 100%); } .heart-button { position: relative; display: grid; width: 90px; height: 90px; cursor: pointer; place-items: center; appearance: none; border: none; background: none; user-select: none; &:hover { .heart-button-label { color: #fff; transform: rotate3d(0, 0, 0, 180deg) scale(1.2, 0.9); } .heart-button-back-inner { border: 1px dashed #fff; background-color: rgb(255 255 255 / 0); transform: scale(1.5); } } } .heart-button-label { position: relative; color: #f78198; font-size: 3rem; transform: scaleY(0.8); transition: 0.35s ease-in-out; line-height: 1; } .heart-button-back { position: absolute; width: 100%; height: 100%; animation: rotation 4s infinite linear; } .heart-button-back-inner { position: absolute; border: 2px solid #fff; width: 100%; height: 100%; border-radius: 50%; background-color: #fff; transition: 0.2s ease; top: 0; left: 0; box-sizing: border-box; } @keyframes rotation { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } <section class="container content-bg-heart"> <button class="heart-button" > <span class="heart-button-back"> <span class="heart-button-back-inner"></span> </span> <span class="heart-button-label"></span> </button> </section>{/collapse-item}{/collapse}复选标记动画{collapse}{collapse-item label="代码实现"} .content-bg-check { background-image: linear-gradient( -135deg, #9cece3 0%, #7496ea 40%, #7393ea 60%, #4b3cf2 100% ); } .circle { position: relative; border-radius: 50%; width: 80px; height: 80px; box-shadow: inset 0 0 0 2px #fff; --ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035); --ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1); --circle-bg-color: #7393ea; &.animation { animation: circle-filling-animation 0.3s ease 1.2s forwards; .circle-cover-1::before { animation: circle-draw-animation 0.4s var(--ease-in-expo) 0.4s forwards; } .circle-cover-2::before { animation: circle-draw-animation 0.4s var(--ease-out-expo) 0.8s forwards; } .circle-illust { animation: circle-check-animation 0.9s 1.4s forwards; animation-timing-function: linear( 0, 1.32, 0.87, 1.05, 0.98, 1.01, 1, 1 ); } } } .circle-cover-1, .circle-cover-2 { position: absolute; overflow: hidden; width: 50%; height: 100%; &::before, &::before { position: absolute; content: ""; } } .circle-cover-1 { left: 50%; &:before { width: 100%; height: 200%; background: var(--circle-bg-color); transform-origin: 0 25%; } } .circle-cover-2::before { left: -10%; width: 110%; height: 120%; background: var(--circle-bg-color); transform-origin: 100% 40%; } .circle-illust { --size: 64px; position: absolute; width: var(--size); height: var(--size); color: var(--circle-bg-color); top: calc(50% - var(--size) / 2); left: calc(50% - var(--size) / 2); transform-origin: 50% 50%; opacity: 0; svg { width: 100%; height: 100%; } } @keyframes circle-draw-animation { 0% { transform: rotate(0deg); } 100% { transform: rotate(180deg); } } @keyframes circle-filling-animation { 0% { box-shadow: inset 0 0 0 9px #ffffff; } 100% { box-shadow: inset 0 0 0 50px #ffffff; } } @keyframes circle-check-animation { 0% { transform: scale(0) rotate(-10deg); opacity: 0; } 100% { transform: scale(1) rotate(0deg); opacity: 1; } } <div class="container content-bg-check"> <div class="circle animation"> <span class="circle-cover-1"></span> <span class="circle-cover-2"></span> <span class="circle-illust"> <svg viewBox="0 0 24 24" fill="none"> <path d="M9 16.2L4.8 12L3.4 13.4L9 19L21 7L19.6 5.6L9 16.2Z" fill="currentColor" /> </svg> </span> </div> </div> setInterval(() => { const el = document.querySelector(".circle"); el.classList.remove("animation"); setTimeout(() => { el.classList.add("animation"); }, 16); }, 4000);{/collapse-item}{/collapse}摇晃加载图标{collapse}{collapse-item label="代码实现" } .container-bg-loading { background-color: #f9f9f9; box-shadow: inset 0 0 0 1px #ddd; } .loading { position: relative; width: 100px; height: 100px; user-select: none; } .loading::after { border-radius: 40%; content: ""; display: block; width: 100%; height: 100%; background: linear-gradient( to bottom, #ee88aa, rgb(250 238 255 / 0.3) 90%, rgb(230 238 255 / 0.5) ); animation: loading-circle-opacity 3s infinite linear; } .loading-circle-1, .loading-circle-2, .loading-circle-3 { opacity: 0.4; position: absolute; background: #0af; /* 水色 */ width: 100px; height: 100px; transform-origin: 50% 47%; border-radius: 40%; animation: loading-circle-rotation 3s infinite linear; } .loading-circle-2 { opacity: 0.2; background: #ff0; /* 黄色 */ animation: loading-circle-rotation 5s infinite linear; } .loading-circle-3 { animation: loading-circle-rotation 2.5s infinite linear; } .loading-label { position: absolute; top: 33px; width: 100%; z-index: 1; color: #fff; text-align: center; font-size: 0.7rem; line-height: 2rem; letter-spacing: 0.15em; animation: loading-label-opacity 300ms infinite linear; } @keyframes loading-circle-rotation { from { rotate: 0deg; } to { rotate: 360deg; } } @keyframes loading-circle-opacity { 0% { opacity: 1; } 50% { opacity: 0.7; } } @keyframes loading-label-opacity { 0% { opacity: 1; } 25% { opacity: 0.8; } 50% { opacity: 0.9; } 75% { opacity: 0.6; } }<div class="container container-bg-loading"> <div class="loading"> <span class="loading-label">LOADING</span> <span class="loading-circle-1"></span> <span class="loading-circle-2"></span> <span class="loading-circle-3"></span> </div> </div>{/collapse-item}{/collapse}
2023年01月06日
203 阅读
6 评论
0 点赞
2023-01-03
btn 抖动问题
button将span一个元素放入其中并使用button: hover进行动画处理span。button哈:只是用来接hover的假人,主体处于span一个状态。但是,如果只使用: hover ,则当鼠标指针移动 到button动画后span的位置(范围外)时,它会返回,所以:hover 也必须定义。<html><body> <div class="wrap"> <button><span class="type-1">按钮1</span></button> <button><span class="type-2">按钮2</span></button> <button><span class="type-3">按钮3</span></button> </div> </body></html>*, *:before, *:after { box-sizing: border-box; margin: 0; padding: 0; border: 0; background: transparent; } html, body { width: 100%; height: 100%; } .wrap { display: flex; height: 100%; justify-content: center; align-items: center; flex-wrap: wrap; } button { margin: 1em; cursor: pointer; outline: none; font-size: 2em; } button span { display: block; padding: .5em 2em; border-radius: 5px; transition: 500ms; } .type-1 { background: #222; color: #fff; } .type-1:hover, button:hover .type-1, button:focus .type-1 { transform: translateY(-1em); } .type-2 { background: #222; color: #fff; } .type-2:hover, button:hover .type-2, button:focus .type-2 { transform: rotateZ(20deg); } .type-3 { background: #222; color: #fff; } .type-3:hover, button:hover .type-3, button:focus .type-3 { transform: scale(.8); }
2023年01月03日
113 阅读
0 评论
0 点赞
2022-12-09
使用Git进行版本控制
什么是GitGit是由Linus Torvalds创造的一种版本控制工具,旨在提供高效的分布式版本控制系统。通过Git,开发者可以跟踪文件变更、合并代码、撤销修改等操作,使团队协作更加高效。Git的基本概念仓库(Repository)Git中的仓库是存储项目代码的地方,可以是本地仓库或远程仓库。每个仓库都包含完整的项目历史记录。提交(Commit)提交是Git中最小的版本单元,表示一次代码修改的记录。每次提交都有一个唯一的哈希值,用于区分不同的提交。分支(Branch)分支是指向某次提交的指针,可以用来独立开发某个特性或修复bug,不影响主线代码。合并分支时,可以保持代码的整洁性。合并(Merge)合并是将不同的分支或提交整合在一起,避免代码冲突并保留所有更改。合并后的代码将包含所有相关的修改内容。Git的常用命令克隆仓库git clone <repository_url>添加文件到暂存区git add <file_name>提交更改git commit -m "Commit message"查看状态git status查看提交历史git log创建并切换分支git checkout -b <branch_name>合并分支git merge <branch_name>Git的技巧利用 .gitignore 文件排除不需要跟踪的文件和目录。使用 git rebase 重新整理提交历史,使提交记录更清晰。学习如何解决合并冲突,确保合并分支时代码的质量。掌握使用标签(tag)对重要版本进行标记,方便日后查找。git 使用规范 commit 的类别● feat:新增功能(feature)● fix:修复补丁(bug)● docs:修订文档,如 Readme, Change Log, Contribute 等● refactor:代码重构,未新增任何功能和修复任何 bug● style: 仅调整空格、格式缩进等(不改变代码逻辑的变动)● perf:优化相关,改善性能和体验的修改● test:测试用例的增加/修改● chore:非 src 和 test 的修改● merge:合并分支或冲突等● revert: 回滚到上一个版本● build:改变构建流程,新增依赖库、工具等(例如 webpack、maven 修改)● ci:自动化流程配置修改Git关联多个远程仓库的方法本地仓库关联多个远程库,比如同时关联GitHub和Gitee,操作方法如下本地创建好文件夹及文件初始化gitgit init分别在GitHub和Gitee上创建好远程仓库回到本地关联远程仓库git remote add github git@github.com:shthah/note.gitgit remote add gitee git@gitee.com:shthah/note.git执行以下命令,查看关联的远程仓库git remote -v会显示gitee https://gitee.com/shthah/notes.git (fetch)gitee https://gitee.com/shthah/notes.git (push)github git@github.com:shthah/notes.git (fetch)github git@github.com:shthah/notes.git (push)说明关联成功。同步远程代码git pull gitee(别名) master当有修改推送到远程的时候,分别推送即可git push github mastergit push gitee master可关联master分支,使用git push github等直接提交,不用再写默认master分支名 git push --set-upstream github master git push --set-upstream gitee master如果已关联一个远程,可使用以下命令,先删除远程关联,再重新关联即可git remote rm origin也可直接修改远程仓库名称git remote rename gitee mayun
2022年12月09日
216 阅读
3 评论
0 点赞
1
2
3