前端小案例 | 喵喵大王立大功 | 一个带便利贴功能的todolist面板

本文主要是介绍前端小案例 | 喵喵大王立大功 | 一个带便利贴功能的todolist面板,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 📚html
  • 📚css
  • 📚js
    • 🐇stickynote.js
    • 🐇todolist.js
    • 🐇clock.js

📚html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>喵喵大王立大功</title><link rel="stylesheet" href="./style.css">
</head>
<body><main id="board"><!-- 代办框 --><section class="container"><!-- 标题 --><div class="heading"><img class="heading__img" src="./src/吐舌.png"><h1 class="heading__title">To-Do List</h1></div><form class="form"><div><!-- ~ Today I need to ~ --><label class="form__label" for="todo">~ Today I need to ~</label><!-- 背景音乐 --><audio src="./src/Fall.ogg" controls loop preload="metadata"></audio><!-- 待办事项输入框 --><input class="form__input"type="text" id="todo" name="to-do"size="30"required><!-- 提交按钮 --><button class="button"><span>Submit</span></button></div></form><div><!-- 代办事项列表 --><ul class="toDoList"></ul></div><div><!-- 代办框右下角那三个猫爪图片 --><img class="cute1" src="./src/cute.png"><img class="cute2" src="./src/cute2.png"><img class="cute3" src="./src/cute3.png"></div></section><!-- 时钟部分 --><div class="clock"><!-- 小时 --><div class="hours"><div class="first"><div class="number">0</div></div><div class="second"><div class="number">0</div></div></div><div class="tick">:</div><!-- 分钟 --><div class="minutes"><div class="first"><div class="number">0</div></div><div class="second"><div class="number">0</div></div></div><div class="tick">:</div><!-- 秒 --><div class="seconds"><div class="first"><div class="number">0</div></div><div class="second infinite"><div class="number">0</div></div></div></div><!-- 底下的小猫照片 --><img class="xixi" src="./src/xixi.png"></main>
</body>
<script src="https://unpkg.com/gsap@3/dist/gsap.min.js"></script>
<script src="https://unpkg.com/gsap@3/dist/Draggable.min.js"></script>
<script src="https://assets.codepen.io/16327/InertiaPlugin.min.js"></script>
<script src="./js/stickynote.js"></script>
<script src="./js/todolist.js"></script>
<script src="./js/clock.js"></script>
</html>

📚css

@import url('https://fonts.googleapis.com/css?family=Gochi+Hand:wght@400;500;600&display=swap');
html, body {display: flex;justify-content: center;align-items: center;color: hsl(198, 1%, 29%);font-family: 'Gochi Hand', cursive;text-align: center;font-size: 130%;  
}* {padding: 0;margin: 0;
}/* 整个面板 */
#board {position: relative;/* 铺满整个视口 */width: 100vw;height: 100vh;background-color: #f1eee5;overflow: hidden;perspective: 1600px;display: grid;box-sizing: border-box;padding: 50px;
}/* 底图 */
.xixi{width: 720px;height: 120px;position: absolute;left: 50%;bottom: 0;transform: translateX(-50%);
}/* #region代办框start */
/* 整个代办框 */
.container {position: relative;height: 500px;width: 500px;background: #f1f5f8;/* 背景圆点绘制,每个重复的小方块大小为 ​25px × 25px​ */background-image: radial-gradient(#bfc0c1 7.2%, transparent 0);background-size: 25px 25px;border-radius: 20px;box-shadow: 4px 3px 7px 2px #00000040;padding: 1rem;box-sizing: border-box;/* 水平居中对齐 */margin: 0 auto;
}/* 标题 */
.heading {display: flex;align-items: center;justify-content: center;margin-bottom: 1rem;
}
/* To-Do List部分样式 */
.heading__title {transform: rotate(2deg);padding: 0.2rem 1.2rem;border-radius: 20% 5% 20% 5%/5% 20% 25% 20%;background-color: hsla(53, 100%, 93%, 0.708);font-size: 1.5rem;
}
/* 图片元素的宽度为父元素宽度的24% */
.heading__img {width: 24%;
}/* ~ Today I need to ~ */
.form__label {display: block;margin-top: -20px;margin-bottom: 0.5rem;
}
/* 音频 */
audio {width: 280px;height: 15px;margin: 0px auto;border: 1px solid #e0dfc6;border-radius: 8px;
}
/* 输入框 */
.form__input {box-sizing: border-box;background-color: transparent;padding: 0.3rem;/* 边框设置 */border-bottom-right-radius: 15px 3px;border-bottom-left-radius:3px 15px;border: solid 3px transparent;border-bottom: dashed 3px #c6beb1;/* 字体设置 */font-family: 'eryamaomiti', cursive;font-size: 1rem;color: hsla(260, 2%, 25%, 0.7);width: 70%;margin-bottom: 20px;/* 获得焦点时 */&:focus {/* 去掉默认的外边框样式 */outline: none;/* 框变为实线,颜色为#c6beb1 */border: solid 3px #c6beb1;}
}/* submit按钮 */
.button {padding: 0;border: none;/* 顺时针旋转4度 */transform: rotate(4deg);/* 变换的起点为中心点 */transform-origin: center;font-family: 'eryamaomiti', cursive;text-decoration: none;padding-bottom: 3px;border-radius: 5px;/* 添加一个垂直的盒子阴影效果 */box-shadow: 0 2px 0 hsl(198, 1%, 29%);/* 过渡效果的时间和缓动函数 */transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);/* Base64编码的背景图像 */background-image: url('data:image/gif;base64,R0lGODlhBAAEAIABAAAAAAAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjEgNjQuMTQwOTQ5LCAyMDEwLzEyLzA3LTEwOjU3OjAxICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgV2luZG93cyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo5NUY1OENCRDdDMDYxMUUyOTEzMEE1MEM5QzM0NDVBMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo5NUY1OENCRTdDMDYxMUUyOTEzMEE1MEM5QzM0NDVBMyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjk1RjU4Q0JCN0MwNjExRTI5MTMwQTUwQzlDMzQ0NUEzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjk1RjU4Q0JDN0MwNjExRTI5MTMwQTUwQzlDMzQ0NUEzIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAAIfkEAQAAAQAsAAAAAAQABAAAAgYEEpdoeQUAOw==');background-color: hsla(0, 0%, 100%, 0.7);
}
/* 按钮内文本样式 */
.button span {background: #f1f5f8;display: block;padding: 0.5rem 1rem;border-radius: 5px;border: 2px solid hsl(198, 1%, 29%);
}
/* 按钮在激活状态和获取焦点时 */
.button:active, .button:focus {transform: translateY(4px);padding-bottom: 0px;outline: 0;
}/* 代办事项列表 */
.toDoList {padding-left: 2.5rem;text-align: left;
}
li {position: relative;padding-top: 0.2rem;font-size: 24px;color: #3c4654;font-family: 'eryamaomiti', cursive;
}
/* 悬停时添加删除线效果 */
li:hover {text-decoration: line-through #d5c8a0;
}/* 右下角的三个爪子 */
.cute1{position: absolute; bottom: 5px; right: 70px; width: 100px;height: 100px;
}
.cute2{position: absolute; bottom: 70px; right: 5px; width: 100px;height: 100px;
}
.cute3{position: absolute; bottom: 0; right: 0; width: 100px;height: 100px;
}
/* #endregion代办框end *//* #region便利贴start */
/* 便利贴样式 */
.stickynote {position: absolute;width: 200px;height: 200px;box-sizing: border-box;padding: 10px;transform: rotateX(5deg);box-shadow: -1px 10px 5px -4px rgba(0, 0, 0, 0.02), inset 0 24px 30px -12px rgba(0, 0, 0, 0.2);/* 之后便利贴内文本框居中 */display: flex;justify-content: center;align-items: center;
}
/* 便利贴文本框 */
.stickynote-text {border-radius: 10px;color: #686a67;font-size: 20px;font-weight: 400;border: none;background: transparent;outline: none;text-align: center;resize: none;overflow: hidden;font-family: 'eryamaomiti', cursive;
}
/* 获得焦点时 */
.stickynote-text:focus {background-color: rgba(0,0,0,0.2);
}
/* 占位符(输入文本前的文本显示) */
.stickynote-text::placeholder {color: #686a67;opacity: 30%;
}
/* #endregion便利贴end *//* #region时钟start */
.clock {margin: -80px auto;height: 10vh;color: #e2a2aca1;font-size: 10vh;font-family: 'eryamaomiti';line-height: 10vh;display: flex;position: relative;overflow: hidden;
}
.clock > div {display: flex;
}
.tick {line-height: 7vh;
}
.tick-hidden {opacity: 0;
}
/* 线性过渡,持续时间为1s */
.move {animation: move linear 1s infinite;
}
@keyframes move {from {transform: translateY(0vh);}to {transform: translateY(-10vh);}
}
/* #endregion时钟end */

📚js

🐇stickynote.js

// 获取id为board的元素
const board = document.querySelector("#board"); // 循环创建102个便利贴
for (let i = 0; i < 102; i++) {// 创建div元素作为便利贴的容器,并添加类名"stickynote"const sticky = document.createElement("div"); sticky.classList.add("stickynote");  if((i + 1) % 6 == 0){// 红sticky.style.background='#f0c2a2';}else if((i + 1) % 6 == 5){// 黄sticky.style.background='#fffbc7';}else if((i + 1) % 6 == 4){// 蓝sticky.style.background='#aed0ee';}else if((i + 1) % 6 == 3){// 粉sticky.style.background='#f9d3e3';}else if((i + 1) % 6 == 2){// 绿sticky.style.background='#bfd1b1';}else if((i + 1) % 6 == 1){// 紫sticky.style.background='#dcc7e1';}// 创建一个textarea元素作为便利贴的文本框const text = document.createElement("textarea"); // 设置输入类型为文本text.type = "text"; // 设置占位符文本为"Drag Me"text.placeholder = "Drag Me"; // 设置最大字符长度为100text.maxLength = 100; // 添加类名"stickynote-text"到便利贴文本框text.classList.add("stickynote-text"); // 将文本框添加到便利贴容器中sticky.appendChild(text); // 将便利贴容器添加到板块中board.appendChild(sticky); 
}// 自适应便利贴文本框高度
document.querySelectorAll('textarea').forEach(textarea => {function setHeight() {// 先重置高度textarea.style.height = 'auto'; // 根据实际内容设置高度textarea.style.height = `${textarea.scrollHeight}px`; }setHeight();// 输入时自动调整高度textarea.addEventListener('input', setHeight);// 内容改变时自动调整高度textarea.addEventListener('change', setHeight); 
});// 创建可拖动便利贴的对象
const draggables = Draggable.create(".stickynote", {// 设置拖动方向为水平和垂直type: "x,y", // 拖动开始时的回调函数onDragStart: function () { // 启用惯性动画,外部js库InertiaPlugin.track(this.target, "x"); // 拖动开始时的动画效果grabNoteAnimation(this.target); const inputField = this.target.querySelector('.stickynote-text');// 修改文本框的占位符文本inputField.placeholder = "Stick Me"; },// 拖动中的回调函数onDrag: function () { // 获取水平方向上的速度let dx = InertiaPlugin.getVelocity(this.target, "x"); // 调用GSAP库gsap.to(this.target, { // 根据速度旋转便利贴(所以会有越快越歪)rotation: dx * -0.003, duration: 0.5,ease: "elastic.out(1.8, 0.6)",// 动画完成后的回调函数onComplete: function () { // 旋转回初始状态gsap.to(this.target, { rotation: 0,duration: 0.5,ease: "elastic.out(1.8, 0.6)"});}});},// 拖动结束时的回调函数onDragEnd: function () {releaseNoteAnimation(this.target); const inputField = this.target.querySelector('.stickynote-text');// 贴好了,就是"Write On Me"inputField.placeholder = "Write On Me"; },// 避免拖动时误触发内部元素的点击事件dragClickables: false, 
});// 拖动便利贴时的抓取动画
function grabNoteAnimation(target) {// 创建动画时间线对象const timeline = gsap.timeline(); timeline.to(target, {rotateX: 30, boxShadow: "-1px 14px 40px -4px rgba(0, 0, 0, 0.12), inset 0 14px 20px -12px rgba(0, 0, 0, 0.3)", // 添加阴影效果duration: 0.3}).to(target, {// 将便利贴旋转回初始状态rotation: 0, rotateX: 5,// 缩放便利贴scale: 1.1, boxShadow: "-1px 14px 40px -4px rgba(0, 0, 0, 0.12), inset 0 24px 30px -12px rgba(0, 0, 0, 0.3)", // 调整阴影效果// 弹性缓动效果ease: "elastic.out(0.8, 0.5)" }, 0.15);timeline.play();
}// 释放便利贴时的动画
function releaseNoteAnimation(target) {const timeline = gsap.timeline(); timeline.to(target, {rotateX: 30, boxShadow: "-1px 10px 5px -4px rgba(0, 0, 0, 0.02), inset 0 24px 30px -12px rgba(0, 0, 0, 0.2)", // 调整阴影效果duration: 0.3}).to(target, {// 还原缩放scale: 1 }, 0).to(target, {// 将便利贴旋转回初始状态rotateX: 5, boxShadow: "-1px 10px 5px -4px rgba(0, 0, 0, 0.02), inset 0 24px 30px -12px rgba(0, 0, 0, 0.2)", // 调整阴影效果ease: "elastic.out(0.8, 0.5)"}, 0.2);timeline.play();
}// 双击便利贴删除
document.querySelectorAll(".stickynote").forEach((sticky) => {sticky.addEventListener("dblclick", function() {const dragInstance = draggables.find((instance) => instance.target === sticky);if (dragInstance) {dragInstance.disable();}sticky.remove();});
});// 输入框获得焦点时禁用拖动
// 输入框失去焦点时重新启用拖动
document.querySelectorAll(".stickynote-text").forEach((textField) => {textField.addEventListener("focus", () => {draggables.forEach((instance) => {if (instance.target.contains(textField)) {instance.disable();}});});textField.addEventListener("blur", () => {draggables.forEach((instance) => {if (instance.target.contains(textField)) {instance.enable();}});});
});

🐇todolist.js

(() => { // 锁定元素const form = document.querySelector(".form"); const input = form.querySelector(".form__input"); const ul = document.querySelector(".toDoList"); // 代办提交时form.addEventListener('submit', e => {// 阻止表单的默认提交行为e.preventDefault(); // 生成唯一的idlet itemId = String(Date.now()); // 获取输入框中的待办事项内容let toDoItem = input.value; // 如果待办事项列表已经有6个或以上的项if (ul.children.length >= 6) { alert("喵喵大王处理不过来啦!"); return;}// 将待办事项添加到页面中const li = document.createElement('li'); li.setAttribute("data-id", itemId); li.innerText = toDoItem; ul.appendChild(li);// 清空输入框input.value = ''; });// 点击删除时ul.addEventListener('click', e => {// 获取被点击项的idlet id = e.target.getAttribute('data-id') // 如果被点击的不是待办事项,则退出函数if (!id) return // 弹出确认对话框,确认是否删除该待办事项if (confirm("喵喵大王会把它销毁哦——")) { // 从页面中删除该待办事项var li = document.querySelector('[data-id="' + id + '"]'); ul.removeChild(li); }});
})();

🐇clock.js

// 锁定元素
var hoursContainer = document.querySelector('.hours') 
var minutesContainer = document.querySelector('.minutes') 
var secondsContainer = document.querySelector('.seconds') 
var tickElements = Array.from(document.querySelectorAll('.tick')) // 保存上一次时间,初始值为0。
var last = new Date(0) 
// 设置为-1,以确保首次更新所有时间显示
last.setUTCHours(-1) 
// 用于记录动画效果的状态
var tickState = true // 更新时间
function updateTime () {var now = new Date var lastHours = last.getHours().toString() var nowHours = now.getHours().toString()// 如果上一次时间的小时和当前时间的小时不相等if (lastHours !== nowHours) {// 更新小时的显示updateContainer(hoursContainer, nowHours) }// 分钟和秒同理var lastMinutes = last.getMinutes().toString() var nowMinutes = now.getMinutes().toString() if (lastMinutes !== nowMinutes) { updateContainer(minutesContainer, nowMinutes) }var lastSeconds = last.getSeconds().toString() var nowSeconds = now.getSeconds().toString() if (lastSeconds !== nowSeconds) {updateContainer(secondsContainer, nowSeconds) }// 更新上一次时间为当前时间last = now 
}// 切换'tick'元素的CSS类'tick-hidden'以实现闪烁效果
function tick () {tickElements.forEach(t => t.classList.toggle('tick-hidden')) 
}// 更新显示
function updateContainer (container, newTime) {var time = newTime.split('') if (time.length === 1) { //单个数字补0time.unshift('0') }// 更新显示var first = container.firstElementChild if (first.lastElementChild.textContent !== time[0]) { updateNumber(first, time[0]) }var last = container.lastElementChild if (last.lastElementChild.textContent !== time[1]) { updateNumber(last, time[1])}
}// 变更动画实现
function updateNumber (element, number) {var second = element.lastElementChild.cloneNode(true) second.textContent = number element.appendChild(second) element.classList.add('move') setTimeout(function () {element.classList.remove('move')}, 975)//选用975而非1000会更平滑setTimeout(function () {element.removeChild(element.firstElementChild) }, 975)
}setInterval(updateTime, 100) 

更新,解决删除便利贴颜色混乱的问题

  • 不用以下方法给便利贴设置颜色,这会导致删除便利贴时,颜色重置混乱

    .stickynote:nth-child(n) {background: #dcc7e1;
    }
    .stickynote:nth-child(2n) {background: #bfd1b1;
    }
    .stickynote:nth-child(3n) {background: #f9d3e3;
    }
    .stickynote:nth-child(4n) {background: #aed0ee;
    }
    .stickynote:nth-child(5n) {background: #fffbc7;
    }
    .stickynote:nth-child(6n) {background: #f0c2a2;
    }
    
  • 直接在js生成便利贴时,6个一循环设置好颜色

     if((i + 1) % 6 == 0){// 红sticky.style.background='#f0c2a2';}else if((i + 1) % 6 == 5){// 黄sticky.style.background='#fffbc7';}else if((i + 1) % 6 == 4){// 蓝sticky.style.background='#aed0ee';}else if((i + 1) % 6 == 3){// 粉sticky.style.background='#f9d3e3';}else if((i + 1) % 6 == 2){// 绿sticky.style.background='#bfd1b1';}else if((i + 1) % 6 == 1){// 紫sticky.style.background='#dcc7e1';}
    

这篇关于前端小案例 | 喵喵大王立大功 | 一个带便利贴功能的todolist面板的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/349316

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

【 html+css 绚丽Loading 】000046 三才归元阵

前言:哈喽,大家好,今天给大家分享html+css 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 📚一、效果📚二、信息💡1.简介:💡2.外观描述:💡3.使用方式:💡4.战斗方式:💡5.提升:💡6.传说: 📚三、源代码,上代码,可以直接复制使用🎥效果🗂️目录✍️

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

【区块链 + 人才服务】可信教育区块链治理系统 | FISCO BCOS应用案例

伴随着区块链技术的不断完善,其在教育信息化中的应用也在持续发展。利用区块链数据共识、不可篡改的特性, 将与教育相关的数据要素在区块链上进行存证确权,在确保数据可信的前提下,促进教育的公平、透明、开放,为教育教学质量提升赋能,实现教育数据的安全共享、高等教育体系的智慧治理。 可信教育区块链治理系统的顶层治理架构由教育部、高校、企业、学生等多方角色共同参与建设、维护,支撑教育资源共享、教学质量评估、