当前位置: 首页 > news >正文

React 实现爱心花园动画

主页:

import React, { useEffect, useRef, useState } from 'react';
import '@/assets/css/Love.less';
import { Garden } from '@/utils/GardenClasses';// 组件属性接口
interface LoveAnimationProps {startDate?: Date; // 可选的开始日期messages?: {      // 可自定义的文本消息initial?: string;   // 初始文字love?: string;      // 告白文字signature?: string; // 落款};
}// 默认开始日期:2010年11月2日20点
const DEFAULT_START_DATE = new Date(2010, 10, 2, 20, 0, 0);// 默认文本配置
const DEFAULT_MESSAGES = {initial: "亲爱的,这是我们相爱在一起的时光。",love: "爱你直到永永远远。",signature: "-爱你的人"
};const LoveAnimation: React.FC<LoveAnimationProps> = ({startDate = DEFAULT_START_DATE,messages = DEFAULT_MESSAGES
}) => {// ========== Refs定义 ==========const canvasRef = useRef<HTMLCanvasElement>(null);      // 画布引用const gardenRef = useRef<Garden | null>(null);          // 花园实例引用const loveHeartRef = useRef<HTMLDivElement>(null);      // 心形容器const contentRef = useRef<HTMLDivElement>(null);        // 内容容器const codeRef = useRef<HTMLDivElement>(null);           // 代码区域const wordsRef = useRef<HTMLDivElement>(null);          // 文字区域const messagesRef = useRef<HTMLDivElement>(null);       // 消息区域const loveURef = useRef<HTMLDivElement>(null);          // 告白区域const elapseClockRef = useRef<HTMLDivElement>(null);    // 计时器const errorMsgRef = useRef<HTMLDivElement>(null);       // 错误信息// ========== 状态定义 ==========const [showMessages, setShowMessages] = useState(false); // 是否显示消息const [showLoveU, setShowLoveU] = useState(false);      // 是否显示告白const [codeContent, setCodeContent] = useState('');     // 代码内容const [showCursor, setShowCursor] = useState(false);    // 是否显示光标const [clearVal, setClearVal] = useState(true);         // 清除标志const clearValRef = useRef(clearVal);                   // 清除标志的ref// 动画定时器存储const animationRefs = useRef<{ intervals: NodeJS.Timeout[]; // 间隔定时器timeouts: NodeJS.Timeout[];  // 延时定时器}>({ intervals: [], timeouts: [] });// 完整的代码内容(带HTML格式)const fullCodeContent = `<br />/**<br />*2013—02-14,<br />*2013-02-28.<br />*/<br />Boy name = <span class="keyword">Mr</span> ***<br />Girl name = <span class="keyword">Mrs</span> ***<br /><span class="comments">// Fall in love river.</span><br />The boy love the girl;<br /><span class="comments">// They love each other.</span><br />The girl loved the boy;<br /><span class="comments">// AS time goes on.</span><br />The boy can not be separated the girl;<br /><span class="comments">// At the same time.</span><br />The girl can not be separated the boy;<br /><span class="comments">// Both wind and snow all over the sky.</span><br /><span class="comments">// Whether on foot or 5 kilometers.</span><br /><span class="keyword">The boy</span> very <span class="keyword">happy</span>;<br /><span class="keyword">The girl</span> is also very <span class="keyword">happy</span>;<br /><span class="comments">// Whether it is right now</span><br /><span class="comments">// Still in the distant future.</span><br />The boy has but one dream;<br /><span class="comments">// The boy wants the girl could well have been happy.</span><br />I want to say:<br />Baby, I love you forever;`;// ========== 主要副作用 ==========useEffect(() => {if (!canvasRef.current || !loveHeartRef.current || !contentRef.current) return;// 检查浏览器是否支持canvasif (!document.createElement('canvas').getContext) {if (errorMsgRef.current) {errorMsgRef.current.innerHTML ="您的浏览器不支持HTML5!<br/>推荐使用 Chrome 14+/IE 9+/Firefox 7+/Safari 4+";}if (codeRef.current) {codeRef.current.style.display = "none";}return;}// 初始化画布const gardenCanvas = canvasRef.current;gardenCanvas.width = loveHeartRef.current.offsetWidth;gardenCanvas.height = loveHeartRef.current.offsetHeight;// 获取2D上下文const ctx = gardenCanvas.getContext('2d');if (!ctx) return;// 设置混合模式ctx.globalCompositeOperation = "lighter";// 创建花园实例gardenRef.current = new Garden(ctx, gardenCanvas);// 调整布局adjustLayout();// 花园渲染循环const renderInterval = setInterval(() => {gardenRef.current?.render();}, Garden.options.growSpeed);animationRefs.current.intervals.push(renderInterval);// 启动代码打字效果typeWriterCodeContent();// 光标闪烁效果const cursorInterval = setInterval(() => {if (clearValRef.current) {setShowCursor(prev => !prev);} else {clearInterval(cursorInterval);setShowCursor(false);}}, 600);animationRefs.current.intervals.push(cursorInterval);// 5秒后开始心形动画const heartTimeout = setTimeout(() => {startHeartAnimation();}, 5000);animationRefs.current.timeouts.push(heartTimeout);// 初始化计时器timeElapse(startDate);const timeInterval = setInterval(() => timeElapse(startDate), 500);animationRefs.current.intervals.push(timeInterval);// 窗口大小变化监听const handleResize = () => adjustLayout();window.addEventListener('resize', handleResize);// 清理函数return () => {animationRefs.current.intervals.forEach(interval => clearInterval(interval));animationRefs.current.timeouts.forEach(timeout => clearTimeout(timeout));window.removeEventListener('resize', handleResize);};}, [startDate]);// 显示消息后的副作用useEffect(() => {if (showMessages) {adjustWordsPosition();const timer = setTimeout(() => setShowLoveU(true), 5000);animationRefs.current.timeouts.push(timer);return () => clearTimeout(timer);}}, [showMessages]);// 显示告白后的副作用useEffect(() => {if (showLoveU && loveURef.current) {const loveUContent = `${messages.love}<br/><div class='signature'>${messages.signature}</div>`;loveURef.current.innerHTML = '';typeWriter(loveURef.current, loveUContent, 75);}}, [showLoveU, messages]);// 同步clearVal状态到refuseEffect(() => {clearValRef.current = clearVal;}, [clearVal]);// ========== 工具函数 ==========/*** 代码打字效果*/const typeWriterCodeContent = () => {setShowCursor(true);let i = 0;const speed = 10; // 打字速度(毫秒/字符)const typing = setInterval(() => {if (i < fullCodeContent.length) {setCodeContent(fullCodeContent.substring(0, i + 1));i++;} else {clearInterval(typing);setClearVal(false); // 打字完成,停止光标闪烁}}, speed);animationRefs.current.intervals.push(typing);};/*** 计算心形曲线上的点* @param angle 角度(弧度)* @returns [x, y]坐标*/const getHeartPoint = (angle: number): [number, number] => {// 心形曲线参数方程const x = 19.5 * (16 * Math.pow(Math.sin(angle), 3));const y = -20 * (13 * Math.cos(angle) - 5 * Math.cos(2 * angle) - 2 * Math.cos(3 * angle) - Math.cos(4 * angle));// 计算相对于心形容器中心的坐标const offsetX = loveHeartRef.current?.offsetWidth ? loveHeartRef.current.offsetWidth / 2 : 0;const offsetY = loveHeartRef.current?.offsetHeight ? loveHeartRef.current.offsetHeight / 2 - 55 : 0;return [offsetX + x, offsetY + y];};/*** 开始心形动画*/const startHeartAnimation = () => {const interval = 50; // 花朵生成间隔(毫秒)const speed = 0.2;   // 角度变化速度let angle = 10;      // 起始角度const points: [number, number][] = []; // 已生成的点const animation = setInterval(() => {const point = getHeartPoint(angle);let valid = true;// 检查新点与已有点的距离for (const p of points) {const distance = Math.sqrt(Math.pow(p[0] - point[0], 2) + Math.pow(p[1] - point[1], 2));if (distance < Garden.options.bloomRadius.max * 1.3) {valid = false;break;}}// 如果点有效,创建花朵if (valid && gardenRef.current) {points.push(point);gardenRef.current.createRandomBloom(point[0], point[1]);}// 动画结束条件if (angle >= 30) {clearInterval(animation);setShowMessages(true); // 显示消息} else {angle += speed; // 继续动画}}, interval);animationRefs.current.intervals.push(animation);};/*** 通用打字机效果* @param element 目标DOM元素* @param text 要显示的文本* @param speed 打字速度(毫秒/字符)*/const typeWriter = (element: HTMLElement, text: string, speed: number) => {let i = 0;element.innerHTML = '';const typing = setInterval(() => {if (i < text.length) {const char = text.substr(i, 1);// 跳过HTML标签if (char === '<') {const closingIndex = text.indexOf('>', i);i = closingIndex === -1 ? text.length : closingIndex + 1;} else {i++;}// 更新内容并添加光标element.innerHTML = text.substring(0, i) + (i % 2 ? '_' : '');} else {clearInterval(typing);}}, speed);animationRefs.current.intervals.push(typing);};/*** 计算并显示恋爱时长* @param date 开始日期*/const timeElapse = (date: Date) => {if (!elapseClockRef.current) return;const now = new Date();const seconds = (now.getTime() - date.getTime()) / 1000;// 计算天数const days = Math.floor(seconds / (3600 * 24));let remaining = seconds % (3600 * 24);// 计算小时const hours = Math.floor(remaining / 3600);remaining %= 3600;// 计算分钟const minutes = Math.floor(remaining / 60);remaining %= 60;// 格式化显示(补零)const formattedHours = hours < 10 ? `0${hours}` : hours.toString();const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes.toString();const formattedSeconds = remaining < 10 ? `0${Math.floor(remaining)}` : Math.floor(remaining).toString();// 更新DOMelapseClockRef.current.innerHTML = `<span class="digit">${days}</span> 天 <span class="digit">${formattedHours}</span> 小时 <span class="digit">${formattedMinutes}</span> 分钟 <span class="digit">${formattedSeconds}</span> 秒`;};/*** 调整文字位置*/const adjustWordsPosition = () => {if (!wordsRef.current || !canvasRef.current) return;const garden = canvasRef.current;const words = wordsRef.current;words.style.position = 'absolute';words.style.top = `${garden.offsetTop + 195}px`;words.style.left = `${garden.offsetLeft + 70}px`;};/*** 调整代码区域位置*/const adjustCodePosition = () => {if (!codeRef.current || !canvasRef.current) return;const garden = canvasRef.current;const code = codeRef.current;code.style.marginTop = `${(garden.offsetHeight - code.offsetHeight) / 2}px`;};/*** 响应式布局调整*/const adjustLayout = () => {if (!contentRef.current || !loveHeartRef.current || !codeRef.current) return;const content = contentRef.current;const loveHeart = loveHeartRef.current;const code = codeRef.current;// 计算合适尺寸const width = loveHeart.offsetWidth + code.offsetWidth;const height = Math.max(loveHeart.offsetHeight, code.offsetHeight);// 设置容器尺寸(考虑窗口边界)content.style.width = `${Math.min(width, window.innerWidth - 40)}px`;content.style.height = `${Math.min(height, window.innerHeight - 40)}px`;// 居中显示content.style.marginTop = `${Math.max((window.innerHeight - content.offsetHeight) / 2, 10)}px`;content.style.marginLeft = `${Math.max((window.innerWidth - content.offsetWidth) / 2, 10)}px`;// 调整代码区域垂直居中adjustCodePosition();};/*** 渲染代码区域*/const renderCodeContent = () => {return (<div id="code" ref={codeRef}>{/* 使用dangerouslySetInnerHTML显示带HTML格式的代码 */}<div dangerouslySetInnerHTML={{ __html: codeContent }} />{/* 闪烁的光标(心形) */}{showCursor && (<span className="heart-cursor" style={{ color: 'red' }}></span>)}</div>);};// ========== 组件渲染 ==========return (<div className="btnbg lovePage">{/* 背景层 */}<div id="mainDiv">{/* 主内容容器 */}<div id="content" ref={contentRef}>{/* 左侧:代码区域 */}{renderCodeContent()}{/* 右侧:心形动画区域 */}<div id="loveHeart" ref={loveHeartRef}>{/* 花园画布 */}<canvas id="garden" ref={canvasRef}></canvas>{/* 情话文本区域(默认隐藏) */}<divid="words"ref={wordsRef}style={{display: showMessages ? 'block' : 'none',opacity: showMessages ? 1 : 0,transition: 'opacity 1s ease-in-out'}}>{/* 初始消息 */}<div id="messages" ref={messagesRef}>{messages.initial}{/* 恋爱计时器 */}<div id="elapseClock" ref={elapseClockRef}></div></div>{/* 最终告白(默认隐藏) */}<divid="loveu"ref={loveURef}style={{display: showLoveU ? 'block' : 'none',opacity: showLoveU ? 1 : 0,transition: 'opacity 1s ease-in-out'}}/></div></div></div></div>{/* 浏览器兼容性错误提示 */}<div id="errorMsg" ref={errorMsgRef}></div></div>);
};export default LoveAnimation;

GardenClasses.ts文件:

// GardenClasses.ts
export interface VectorProps {x: number;y: number;
}export interface PetalOptions {stretchA: number;stretchB: number;startAngle: number;angle: number;growFactor: number;bloom: Bloom;
}export interface BloomOptions {p: Vector;r: number;c: string;pc: number;garden: Garden;
}export interface GardenOptions {petalCount: { min: number; max: number };petalStretch: { min: number; max: number };growFactor: { min: number; max: number };bloomRadius: { min: number; max: number };density: number;growSpeed: number;color: {rmin: number;rmax: number;gmin: number;gmax: number;bmin: number;bmax: number;opacity: number;};tanAngle: number;
}export class Vector {x: number;y: number;constructor(x: number, y: number) {this.x = x;this.y = y;}rotate(angle: number): Vector {const x = this.x;const y = this.y;this.x = Math.cos(angle) * x - Math.sin(angle) * y;this.y = Math.sin(angle) * x + Math.cos(angle) * y;return this;}mult(factor: number): Vector {this.x *= factor;this.y *= factor;return this;}clone(): Vector {return new Vector(this.x, this.y);}length(): number {return Math.sqrt(this.x * this.x + this.y * this.y);}subtract(v: Vector): Vector {this.x -= v.x;this.y -= v.y;return this;}set(x: number, y: number): Vector {this.x = x;this.y = y;return this;}
}export class Petal {stretchA: number;stretchB: number;startAngle: number;angle: number;bloom: Bloom;growFactor: number;r: number;isfinished: boolean;constructor(options: PetalOptions) {this.stretchA = options.stretchA;this.stretchB = options.stretchB;this.startAngle = options.startAngle;this.angle = options.angle;this.bloom = options.bloom;this.growFactor = options.growFactor;this.r = 1;this.isfinished = false;}draw(): void {const ctx = this.bloom.garden.ctx;const e = new Vector(0, this.r).rotate(Garden.degrad(this.startAngle));const d = e.clone().rotate(Garden.degrad(this.angle));const c = e.clone().mult(this.stretchA);const b = d.clone().mult(this.stretchB);ctx.strokeStyle = this.bloom.c;ctx.beginPath();ctx.moveTo(e.x, e.y);ctx.bezierCurveTo(c.x, c.y, b.x, b.y, d.x, d.y);ctx.stroke();}render(): void {if (this.r <= this.bloom.r) {this.r += this.growFactor;this.draw();} else {this.isfinished = true;}}
}export class Bloom {p: Vector;r: number;c: string;pc: number;petals: Petal[];garden: Garden;constructor(options: BloomOptions) {this.p = options.p;this.r = options.r;this.c = options.c;this.pc = options.pc;this.petals = [];this.garden = options.garden;this.init();this.garden.addBloom(this);}draw(): void {let isFinished = true;this.garden.ctx.save();this.garden.ctx.translate(this.p.x, this.p.y);for (const petal of this.petals) {petal.render();isFinished = isFinished && petal.isfinished;}this.garden.ctx.restore();if (isFinished) {this.garden.removeBloom(this);}}init(): void {const angle = 360 / this.pc;const startAngle = Garden.randomInt(0, 90);for (let i = 0; i < this.pc; i++) {this.petals.push(new Petal({stretchA: Garden.random(Garden.options.petalStretch.min, Garden.options.petalStretch.max),stretchB: Garden.random(Garden.options.petalStretch.min, Garden.options.petalStretch.max),startAngle: startAngle + i * angle,angle: angle,growFactor: Garden.random(Garden.options.growFactor.min, Garden.options.growFactor.max),bloom: this,}));}}
}export class Garden {blooms: Bloom[];element: HTMLCanvasElement;ctx: CanvasRenderingContext2D;static options: GardenOptions = {petalCount: { min: 8, max: 15 },petalStretch: { min: 0.1, max: 3 },growFactor: { min: 0.1, max: 1 },bloomRadius: { min: 8, max: 10 },density: 10,growSpeed: 1000 / 60,color: {rmin: 128,rmax: 255,gmin: 0,gmax: 128,bmin: 0,bmax: 128,opacity: 0.1,},tanAngle: 60,};constructor(ctx: CanvasRenderingContext2D, element: HTMLCanvasElement) {this.blooms = [];this.element = element;this.ctx = ctx;}render(): void {for (const bloom of this.blooms) {bloom.draw();}}addBloom(bloom: Bloom): void {this.blooms.push(bloom);}removeBloom(bloom: Bloom): void {const index = this.blooms.indexOf(bloom);if (index !== -1) {this.blooms.splice(index, 1);}}createRandomBloom(x: number, y: number): void {this.createBloom(x,y,Garden.randomInt(Garden.options.bloomRadius.min, Garden.options.bloomRadius.max),Garden.randomrgba(Garden.options.color.rmin,Garden.options.color.rmax,Garden.options.color.gmin,Garden.options.color.gmax,Garden.options.color.bmin,Garden.options.color.bmax,Garden.options.color.opacity),Garden.randomInt(Garden.options.petalCount.min, Garden.options.petalCount.max));}createBloom(x: number, y: number, radius: number, color: string, petalCount: number): void {new Bloom({p: new Vector(x, y),r: radius,c: color,pc: petalCount,garden: this,});}clear(): void {this.blooms = [];this.ctx.clearRect(0, 0, this.element.width, this.element.height);}static random(min: number, max: number): number {return Math.random() * (max - min) + min;}static randomInt(min: number, max: number): number {return Math.floor(Math.random() * (max - min + 1)) + min;}static readonly circle = 2 * Math.PI;static degrad(angle: number): number {return (Garden.circle / 360) * angle;}static raddeg(angle: number): number {return (angle / Garden.circle) * 360;}static rgba(r: number, g: number, b: number, a: number): string {return `rgba(${r},${g},${b},${a})`;}static randomrgba(rmin: number,rmax: number,gmin: number,gmax: number,bmin: number,bmax: number,a: number): string {const r = Math.round(Garden.random(rmin, rmax));const g = Math.round(Garden.random(gmin, gmax));const b = Math.round(Garden.random(bmin, bmax));const threshold = 5;if (Math.abs(r - g) <= threshold &&Math.abs(g - b) <= threshold &&Math.abs(b - r) <= threshold) {return Garden.rgba(rmin, rmax, gmin, gmax, bmin, bmax, a);} else {return Garden.rgba(r, g, b, a);}}
}

Love.less

// 主色调(基于 #ffc0cb 扩展的渐变色系)
@color-1: #ffc0cb; // 粉红
@color-2: #ffb6c1; // 稍暗的粉
@color-3: #ffd1dc; // 浅粉
@color-4: #ffdfed; // 更浅的粉
@color-5: #ffecf2; // 接近白色
@font-face {font-family: digit;src: url('digital-7_mono.ttf') format("truetype");
}
// 动画定义
.keyframes() {@keyframes gentleFlow {0% {background-position: 0% 50%;}50% {background-position: 100% 50%;}100% {background-position: 0% 50%;}}
}// 主背景样式
.lovePage {min-height: 100vh;background: linear-gradient(45deg,@color-1,@color-2,@color-3,@color-4,@color-5,@color-1 );background-size: 300% 300%;animation: gentleFlow 12s ease infinite;position: relative;overflow: hidden;.keyframes();// 光斑效果(增强层次感)&::before {content: '';position: absolute;width: 200%;height: 200%;background:radial-gradient(circle at 70% 20%, rgba(255, 255, 255, 0.2) 0%, transparent 30%),radial-gradient(circle at 30% 80%, rgba(255, 255, 255, 0.15) 0%, transparent 30%);animation: gentleFlow 20s linear infinite reverse;}}canvas {padding: 0;margin: 0;
}div.btnbg {width: 100%;height: 100%;}#code,#messages,#loveu{color: #333;
}
#mainDiv {width: 100%;height: 100%
}#loveHeart {width: 670px;height: 625px
}#garden {width: 100%;height: 100%
}#elapseClock {text-align: right;font-size: 18px;margin-top: 10px;margin-bottom: 10px
}#words {font-family: "sans-serif";width: 500px;font-size: 24px;color: #666
}#elapseClock .digit {font-family: "digit";font-size: 36px
}#loveu {padding: 5px;font-size: 22px;margin-top: 40px;margin-right: 120px;text-align: right;display: none
}#loveu .signature {margin-top: 10px;font-size: 20px;font-style: italic
}#clickSound {display: none
}
#content{display: flex;justify-content: center;align-items: center;
}#code {width: 440px;height: 400px;color: #333;font-family: "Consolas","Monaco","Bitstream Vera Sans Mono","Courier New","sans-serif";font-size: 12px;margin: 0 !important;
}.string {color: #2a36ff
}.keyword {color: #7f0055;font-weight: bold
}.placeholder {margin-left: 15px
}.space {margin-left: 7px
}.comments {color: #3f7f5f
}#copyright {margin-top: 10px;text-align: center;width: 100%;color: #666
}#errorMsg {width: 100%;text-align: center;font-size: 24px;position: absolute;top: 100px;left: 0
}#copyright a {color: #666
}
.heart-cursor {animation: blink 1s infinite;font-size: 1em;vertical-align: middle;
}@keyframes blink {0%, 100% { opacity: 1; }50% { opacity: 0; }
}

在这里插入图片描述

相关文章:

React 实现爱心花园动画

主页&#xff1a; import React, { useEffect, useRef, useState } from react; import /assets/css/Love.less; import { Garden } from /utils/GardenClasses;// 组件属性接口 interface LoveAnimationProps {startDate?: Date; // 可选的开始日期messages?: { // 可…...

CAPL编程_03

1_文件操作的相关函数&#xff1a; 读文本文件内容 读取文本文件操作的三部曲 1&#xff09;打开文件 —— openFileRead ( ) 2&#xff09;逐行读取 —— fileGetString ( ) 、fileGetStringSZ ( ) 3&#xff09;关闭文件 —— fileClose ( ) char content[100];…...

网络准入控制系统:2025年网络安全的坚固防线

在当今数字化时代&#xff0c;网络安全已成为至关重要的议题。阳途网络准入控制系统作为保障网络安全的关键机制&#xff0c;发挥着不可替代的作用。 阳途网络准入控制系统核心目的在于确保只有合法、合规的设备与用户能够接入网络。从本质上讲&#xff0c;它通过一系列技术手段…...

【音视频】⾳频处理基本概念及⾳频重采样

一、重采样 1.1 什么是重采样 所谓的重采样&#xff0c;就是改变⾳频的采样率、sample format、声道数等参数&#xff0c;使之按照我们期望的参数输出。 1.2 为什么要重采样 为什么要重采样? 当然是原有的⾳频参数不满⾜我们的需求&#xff0c;⽐如在FFmpeg解码⾳频的时候…...

自然语言处理将如何颠覆未来教育?个性化学习新纪元

教育领域正经历着自印刷术发明以来最深刻的变革。自然语言处理&#xff08;NLP&#xff09;技术突破传统教育框架的桎梏&#xff0c;正在重塑人类知识传递的基本范式。这场变革的实质不在于教学工具的数字化升级&#xff0c;而在于重新定义了"教"与"学"的本…...

4月25日星期五今日早报简报微语报早读

4月25日星期五&#xff0c;农历三月廿八&#xff0c;早报#微语早读。 1、祝贺&#xff01;神舟二十号载人飞船发射取得圆满成功&#xff1b; 2、文旅部&#xff1a;今年一季度国内出游人次17.94亿&#xff0c;同比增长26.4%&#xff1b; 3、2025五一档新片预售票房破1000万&…...

秒级到毫秒:BFD的速度革命

一、BFD技术概述 ​​双向转发检测&#xff08;BFD&#xff09;​​是一种轻量级的网络协议&#xff0c;专门用于快速检测、监控网络链路或IP路由的连通性状态。作为网络领域的"心跳检测器"&#xff0c;BFD通过毫秒级&#xff08;默认1000ms&#xff09;的快速探测机…...

systemctl 命令详解与常见问题解决

在 Linux 系统中&#xff0c;service 命令和 chkconfig 命令一直用于管理服务&#xff0c;但随着 systemd 的引入&#xff0c;systemctl 命令逐渐成为主流。systemctl 命令不仅功能强大&#xff0c;而且使用简单。本文将详细介绍 systemctl 命令的作用以及常见问题的解决方法。…...

5.6 Microsoft Semantic Kernel:专注于将LLM集成到现有应用中的框架

5.6.1 Semantic Kernel概述 Microsoft Semantic Kernel&#xff08;以下简称SK&#xff09;是一个开源的软件开发工具包&#xff08;SDK&#xff09;&#xff0c;旨在帮助开发者将大型语言模型&#xff08;LLM&#xff09;无缝集成到现有的应用程序中。它支持C#、Python和Java…...

vite+vue构建的网站项目localhost:5173打不开

原因&#xff1a;关掉了cmd命令提示符&#xff0c;那个端口就没有被配置上&#xff0c;打开就是这样的。 解决方法&#xff1a;重新在工作目录下打开cmd&#xff0c;输入npm run dev重新启动项目。 重新出现这样的界面说明已经成功启动项目&#xff0c;再次在浏览器中刷新并输入…...

电脑屏幕录制软件Captura源码编译(Win10,VS2022)

屏幕录像的意义&#xff1a; 教育教学方面 制作教学资源&#xff1a;教师可以通过录制屏幕来制作教学视频&#xff0c;演示软件操作、讲解复杂的知识点等。学生可以随时观看这些视频&#xff0c;便于复习和巩固知识&#xff0c;尤其对于一些抽象的概念或难以在课堂上一次性掌握…...

【版本控制】SVN + TortoiseSVN版本管理实用教程(附安装+开发常用操作)

摘要&#xff1a; 本文将带你从零开始掌握 SVN 版本控制系统&#xff0c;结合 TortoiseSVN 图形客户端工具&#xff0c;深入学习包括安装、检出、提交、更新、回滚、冲突解决等常用开发操作&#xff0c;快速上手团队协作&#xff01; &#x1f9e9; 什么是 SVN&#xff1f; SV…...

常见网络安全攻击类型深度剖析(二):SQL注入攻击——原理、漏洞利用演示与代码加固方法

常见网络安全攻击类型深度剖析(二):SQL注入攻击——原理、漏洞利用演示与代码加固方法 在Web应用安全领域,SQL注入(SQL Injection)是历史最悠久、危害最广泛的攻击类型之一。据OWASP(开放式Web应用安全项目)统计,SQL注入连续多年稳居“OWASP Top 10”漏洞榜单前列,每…...

DeepSeek智能时空数据分析(三):专业级地理数据可视化赏析-《杭州市国土空间总体规划(2021-2035年)》

序言&#xff1a;时空数据分析很有用&#xff0c;但是GIS/时空数据库技术门槛太高 时空数据分析在优化业务运营中至关重要&#xff0c;然而&#xff0c;三大挑战仍制约其发展&#xff1a;技术门槛高&#xff0c;需融合GIS理论、SQL开发与时空数据库等多领域知识&#xff1b;空…...

day49—双指针+贪心—验证回文串(LeetCode-680)

题目描述 给你一个字符串 s&#xff0c;最多 可以从中删除一个字符。 请你判断 s 是否能成为回文字符串&#xff1a;如果能&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;s "aba" 输出&#xff1a;true…...

AI电视里的达摩

2025年&#xff0c;所有电视都搭载了AI功能&#xff0c;所有电视厂商都在宣传AI能力。但问题是&#xff0c;消费者依旧没有对AI电视做出什么积极的回应。“AI电视是鸡肋”“AI只是电视的又一轮泡沫”等观点层出不穷。 为什么明明AI技术能够解决电视的很多问题&#xff0c;但AI电…...

算力网络(CFN)在跨校联合科研中的应用:安全性挑战与联邦调度实践

引言&#xff1a;科研协作的算力困境 上海交通大学与麻省理工学院联合开展的高能物理模拟实验&#xff0c;因算力资源分配不均导致部分节点连续72小时处于空转状态。这个典型案例揭示了当前跨机构科研协作的痛点&#xff1a;‌算力资源无法实现安全可信的细粒度共享‌。算力网…...

面向对象编程核心:封装、继承、多态与 static 关键字深度解析

面向对象编程核心&#xff1a;封装、继承、多态与 static 关键字深度解析 一、封装&#xff1a;数据安全与接口规范 1. 封装的本质与作用 核心定义&#xff1a;将数据&#xff08;属性&#xff09;与操作数据的方法&#xff08;行为&#xff09;绑定在类中&#xff0c;隐藏内…...

c++进阶——类与继承

文章目录 继承继承的基本概念继承的基本定义继承方式继承的一些注意事项 继承类模板 基类和派生类之间的转换继承中的作用域派生类的默认成员函数默认构造函数拷贝构造赋值重载析构函数默认成员函数总结 不能被继承的类继承和友元继承与静态成员多继承及其菱形继承问题继承模型…...

【CODEMATE】进制转换(transform) 粤港澳青少年信息学创新大赛 C/C++/Python 解题思路

目录 问题描述做题思路&#xff0c;解决过程思路&#xff1a;踩过的坑&#xff1a;核心代码C 语言 / C 切片&#xff1a;C 语言 / C 判断 ‘A’ 数量&#xff1a;Python 切片&#xff1a;Python 判断 ‘A’ 数量&#xff1a; 完整代码C 语言 完整代码C 完整代码Python 完整代码…...

window和ubuntu自签证书

window下 以管理员身份 运行 Windows PowerShell # CN192.168.0.100 (换成自己的IP或者域名) # O(组织) OU(组织单位) # Cert:\LocalMachine\My&#xff1a;证书存储位置 # test_10&#xff1a;自定义证书名称 .AddYears(10): 证书过期时间 10 年 $cert New-SelfSi…...

ES历史版本下载

下载地址 Past Releases of Elastic Stack Software | Elastic 安装步骤参考 windows 安装 Elasticsearch_windows安装elasticsearch-CSDN博客...

技术面试一面标准流程

0. 自我介绍 ...... 1. 拷打项目 项目干了啥&#xff1f; 难点是啥&#xff1f; 问项目中用到的东西&#xff1f; 扩展&#xff1f; ...... 2. 基础知识 数据结构、C基础、设计模式 数据结构&#xff1a; 堆&#xff1f; unordered_map 和 布隆过滤器 都是用于查找…...

第14篇:Linux设备驱动程序入门<一>

Q&#xff1a;如何简单的理解DE1-SoC-UP Linux系统的设备驱动程序&#xff1f; A&#xff1a;设备驱动程序&#xff08;Device Driver&#xff09;&#xff0c;简称驱动程序&#xff08;Driver&#xff09;。DE1-SoC-UP Linux系统中的设备驱动程序允许系统软件与DE1-SoC开发板…...

软件设计模式与体系结构:基于Java实现管道-过滤器架构

软件设计模式与体系结构&#xff1a;基于Java实现管道-过滤器架构 前言 在软件架构中&#xff0c;数据流风格是一种常见的架构模式&#xff0c;特别适用于需要对数据进行一系列处理的场景。管道-过滤器&#xff08;Pipe and Filter&#xff09;*架构是数据流风格的典型代表&a…...

Node.js 包管理工具介绍

Node.js 包管理工具介绍 Node.js 是一个基于 Chrome V8 JavaScript 引擎的服务器端运行环境&#xff0c;它允许开发者使用 JavaScript 进行后端开发。为了方便管理和维护项目中使用的第三方库和模块&#xff0c;Node.js 提供了多种包管理工具。本文将详细介绍几种常用的 Node.…...

Node.js 应用场景

Node.js 应用场景 引言 Node.js 是一个基于 Chrome V8 JavaScript 引擎的开源、跨平台 JavaScript 运行环境。它主要用于服务器端开发&#xff0c;通过非阻塞 I/O 模型实现了高并发处理能力。本文将详细介绍 Node.js 的应用场景&#xff0c;帮助你了解其在实际项目中的应用。…...

C/C++线程详解

一、C语言线程创建&#xff08;POSIX线程&#xff09; 1. 基本创建方法 POSIX线程&#xff08;pthread&#xff09;是C语言中创建线程的标准API&#xff1a; #include <pthread.h> #include <stdio.h>void* thread_func(void* arg) {printf("Thread runnin…...

动态ip与静态ip的概念、区别、应用场景

动态ip与静态ip的区别 前言 一、IP地址的概念和作用 1.1、IP地址的定义 1.2、IP地址的作用 二、动态IP和静态IP的区别 2.1、动态IP和静态IP的定义 2.2、动态IP和静态IP的特点 2.3、动态IP和静态IP的优缺点比较 三、动态IP和静态IP的应用场景 3.1. 动态IP的应用场景 3.2. 静态IP…...

P12167 [蓝桥杯 2025 省 C/Python A] 倒水

P12167 [蓝桥杯 2025 省 C/Python A] 倒水 题目描述 小蓝有 n n n 个装了水的瓶子&#xff0c;从左到右摆放&#xff0c;第 i i i 个瓶子里装有 a i a_i ai​ 单位的水。为了美观&#xff0c;小蓝将水循环染成了 k k k 种颜色&#xff0c;也就是说&#xff0c;第 i i i …...

Appium自动化开发环境搭建

自动化 文章目录 自动化前言 前言 Appium是一款开源工具&#xff0c;用于自动化iOS、Android和Windows桌面平台上的本地、移动web和混合应用程序。原生应用是指那些使用iOS、Android或Windows sdk编写的应用。移动网页应用是通过移动浏览器访问的网页应用(appum支持iOS和Chrom…...

【金仓数据库征文】金仓数据库:国产化浪潮下的技术突破与行业实践

目录 前言 技术突破&#xff1a;从追赶国际到引领创新 行业深耕&#xff1a;从医疗到航空航天的多领域落地 事务管理与ACID特性 事务管理概述 索引优化与性能调优 安全性与备份恢复策略 Json构造函数 总结 前言 在数字化转型的全球趋势下&#xff0c;数据库作为信息系…...

计算机操作系统

1. T0 时刻是否为安全状态&#xff1f; 步骤 1: 计算当前可用资源 总资源数量&#xff1a; A: 17B: 5C: 20 已分配资源&#xff1a; P1: (2, 1, 2)P2: (4, 0, 2)P3: (4, 0, 5)P4: (2, 0, 4)P5: (3, 1, 4) 当前可用资源&#xff1a; A: 17 - (2 4 4 2 3) 2B: 5 - (1 0 …...

linux系统问题杂谈

1.配置好anaconda之后&#xff0c;在一个终端中编辑好环境变量之后能够正常使用conda命令&#xff0c;但是新打开一个中断使用conda命令报错"无法识别conda"。 原因&#xff1a;使用“export PATH"/home/username/anaconda3/bin:$PATH"命令&#xff0c;临…...

百度打响第一枪!通用超级智能体时代,真的来了

Create2025百度AI开发者大会在武汉举行&#xff0c;K哥受邀参加&#xff0c;看到了许多有趣的创新技术和产品。其中最令我印象深刻的是一款全新发布的通用超级智能体——心响App。 这款App通过多智能体复杂组合、协作&#xff0c;满足用户能够「一站式」解决复杂问题的使用诉求…...

FWFT_FIFO和Standard_FIFO对比仿真

在FPGA中使用FIFO时&#xff0c;如果使用FPGA厂商提供的FIFO IP&#xff0c;一般都会有First Word Fall Through FIFO和Standard FIFO类型选项&#xff0c;那么这两种FIFO有什么差异么。两种FIFO的端口是一样的&#xff0c;看不出区别&#xff0c;只有通过仿真&#xff0c;才能…...

【网络原理】TCP提升效率机制(二):流量控制和拥塞控制

目录 一. 前言 二. 流量控制 三. 拥塞控制 一. 前言 TCP的可靠传输依靠确认应答机制&#xff0c;超时重传机制是对确认应答的一种补充&#xff0c;解决了丢包问题 为了提高传输效率&#xff0c;避免大量的时间都浪费在等待应答的过程&#xff0c;故引入了滑动窗口机制&…...

DeepSeek+Cline:开启自动化编程新纪元

目录 一、引言&#xff1a;AI 编程时代的曙光二、认识 DeepSeek 和 Cline2.1 DeepSeek 是什么2.2 Cline 详解2.3 两者结合的魅力 三、DeepSeek Cline 安装与配置全流程3.1 安装 VS Code3.2 安装 Cline 插件3.3 获取 DeepSeek API Key3.4 配置 Cline 与 DeepSeek 连接 四、实战演…...

【RedisLockRegistry】分布式锁

RedisLockRegistry分布式锁 介绍 RedisLockRegistry‌是Spring框架提供的一种分布式锁机制&#xff0c;它基于Redis来实现对共享资源的保护&#xff0c;防止多个进程同时对同一资源进行修改&#xff0c;从而避免数据不一致或其他问题‌ 基本原理 RedisLockRegistry通过Redi…...

脚本批量启动Node服务器

创建文件start-projects.ps1 定义项目路径&#xff08;使用PowerShell中更可靠的路径表示方式&#xff09; $变量A “E:/XXXX文件根目录” $变量B “E:/XXXX” $变量C “E:/XXXX” 打开变量A并执行npm run dev Start-Process powershell -ArgumentList “-NoExit”, “-Com…...

使用命令行加密混淆C#程序

C#作为托管语言编译生成的IL中间代码极易被反编译工具还原源码。据统计&#xff0c;超过83%的商业软件曾遭遇过代码逆向风险&#xff0c;导致核心算法泄露、授权被跳过. 因此对于C#语言开发的程序来说, 在发布前进行混淆和加密非常有必要. 本文主要介绍如何使用恒盾C#混淆加密…...

零基础上手Python数据分析 (23):NumPy 数值计算基础 - 数据分析的加速“引擎”

写在前面 —— 超越原生 Python 列表,解锁高性能数值计算,深入理解 Pandas 的底层依赖 在前面一系列关于 Pandas 的学习中,我们已经领略了其在数据处理和分析方面的强大威力。我们学会了使用 DataFrame 和 Series 来高效地操作表格数据。但是,你是否好奇,Pandas 为何能够…...

深度学习实战106-大模型LLM+股票MCP Server的股票分析和投资建议应用场景

大家好,我是微学AI,今天给大家介绍一下深度学习实战106-大模型LLM+股票MCP Server的股票分析和投资建议应用场景。 文章目录 一、项目背景(一)大型语言模型(LLM)在金融领域的应用趋势(二)模型上下文协议(MCP)的兴起(三)大模型LLM+股票MCP服务的需求二、开发流程(…...

IDEA配置将Servlet真正布署到Tomcat

刚开始只能IDEA运行完Servlet web application 并保持IDEA运行才能通过浏览器访问到我的Servlet&#xff0c;跟想象中的不一样&#xff0c;不应该是IDEA运行完项目以后只要打开Tomcat就能访问吗&#xff1f;事实时运行完项目只要关掉IDEA就不能再访问到应用了&#xff0c;而且T…...

交叉编译paho.mqtt.c和paho.mqtt.cpp(MQTT客户端)

一、参考资料 【MQTT】paho.mqtt.cpp 库的 介绍、下载、交叉编译、MQTT客户端例子源码-CSDN博客 【MQTT】paho.mqtt.c 库的“介绍、下载、交叉编译” 详解&#xff0c;以及编写MQTT客户端例子源码-CSDN博客 二、准备工作 1. 重要说明 paho.mqtt.cpp与paho.mqtt.c&#xff…...

Prometheus中部署Alertmanager

部署Alertmanager 是 Prometheus 生态系统中的一个重要步骤&#xff0c;用于管理和处理 Prometheus生成的告警。Alertmanager和Prometheus Server一样均采用Golang实现&#xff0c;并且没有第三方依赖。一般来说我们可以通过以下几种方式来部署Alertmanager&#xff1a;二进制包…...

van-field组件设置为textarea属性被软键盘遮挡问题

在移动端van-field 输入框当type为text时&#xff0c;调出软键盘输入框会被顶上去&#xff0c;但type为textarea时不会被顶上去&#xff0c;可以用下面方法来实现&#xff1a; 1. 来2个van-field type为text的输入框z-index: 1 type为textarea的输入框z-index: 9999&#x…...

websheet之 编辑器

一、默认编辑器 该单元格编辑器是控件自带的编辑器&#xff0c;用户不需要指定。 二、下拉选择 该单元格编辑器是控件自带的编辑器的一种。该控件需要你指定下拉的数据源。在下面的例子中&#xff0c;我们给C3和C6单元格指定了币种的下拉选择编辑器。参数见&#xff1a;六、 参…...

氢气泄漏应急预案应包括哪些内容?

氢气泄漏应急预案是科研实验室中应对氢气泄漏事故的重要文件&#xff0c;其内容需要全面覆盖预防、检测、响应和善后处理等环节&#xff0c;确保在紧急情况下能够快速、有序地采取措施&#xff0c;最大限度地减少事故风险和损失。以下是氢气泄漏应急预案应包括的主要内容&#…...

【每天一个知识点】IPv4(互联网协议版本4)和IPv6(互联网协议版本6)

IPv4&#xff08;互联网协议版本4&#xff09;和IPv6&#xff08;互联网协议版本6&#xff09;是用于在互联网上标识和定位设备的两种主要协议。它们的主要区别在于地址空间、结构、以及一些附加功能。以下是两者的对比&#xff1a; 1. 地址长度 IPv4: 地址长度为32位&#xf…...