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; }
}

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77628.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77628.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77628.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從零開始了解數據采集(二十一)——電子制造行業趨勢分析案例

這次分享一個偏行業性的趨勢分析案例,在項目中為企業實實在在的提高了良品率。不懂什么是趨勢分析的同學,可以翻看前面的文章。 在廣東某電子制造廠中,管理層發現最近幾個月生產良品率有所波動,但無法明確波動原因,也無法預測未來的趨勢。為了優化生產過程并穩定良品率,…

在 Git 中,撤銷(回退)merge 操作有多種方法

在 Git 中&#xff0c;撤銷&#xff08;回退&#xff09;merge 操作有多種方法&#xff0c;具體取決于是否已提交、是否已推送&#xff0c;以及是否需要保留歷史記錄。以下是幾種常見的撤銷 merge 的方法&#xff1a; 1. 未提交 merge&#xff08;未 commit&#xff09; 如果 …

基于 Python 的實現:居民用電量數據分析與可視化

基于 Python 的實現:居民用電量數據分析與可視化 本文將介紹如何利用 Python 技術棧(包括 pymysql、pandas、matplotlib 等庫)對居民用電量數據進行分析和可視化,以幫助我們更好地理解用電行為模式。 數據準備 在MySQL數據庫中創建數據,,數據庫表結構如下: date:記錄…

Flow原理

fun main() {runBlocking {launch {flow4.collect{println("---collect-4")}println("---flow4")}}val flow4 flow<Boolean>{delay(5000)emit(false) } 我們分析下整個流程 1.flow為什么之后在collect之后才會發送數據 2.collect的調用流程 我…

設備接入與APP(應用程序)接入華為云iotDA平臺的路徑元素有哪些不同?

目錄 壹、設備接入華為云iotDA &#x1f3e2; 形象比喻&#xff1a;設備 員工&#xff0c;IoTDA 平臺 安保森嚴的總部大樓 一、&#x1f4cd; 平臺接入地址 總部大樓地址 二、&#x1f9fe; 接入憑證 出入證 / 門禁卡 / 工牌 1. 設備密鑰或證書 2. 預置接入憑證密鑰&a…

JavaScript基礎知識合集筆記2——數組排序、數組轉換字符串、迭代方法

文章目錄 排序方法reverse()sort() 轉換方法join() 迭代方法some()every()forEach()filter()map() 排序方法 組有兩個方法可以用來對元素重新排序&#xff1a; reverse()sort() reverse() 顧名思義&#xff0c;將數組元素方向反轉。會直接改變原數組&#xff0c;請謹慎使用…

Redis 筆記(三)-Redis 基本知識及五大數據類型

一、redis 基本知識 redis 默認有 16個 數據庫&#xff0c;config get databases 查看數據庫數量 127.0.0.1:6379> config get databases # 查看數據庫數量 1) "databases" 2) "16"默認使用的是第 0個 16 個數據庫為&#xff1a;DB 0 ~ DB 15&am…

springboot項目文件上傳到服務器本機,返回訪問地址

文件上傳到服務器本機&#xff0c;然后給出訪問地址&#xff1a; 具體如下&#xff1a; 1、添加必要的工具類依賴 <!-- 文件上傳工具類 --><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId>…

巧用 Element - UI 實現圖片上傳按鈕的智能隱藏

引言 在前端開發中&#xff0c;使用 Element - UI 組件庫來構建用戶界面是非常常見的操作。其中圖片上傳功能更是在許多項目中頻繁出現&#xff0c;比如用戶頭像上傳、商品圖片上傳等場景。有時候&#xff0c;我們會有這樣的需求&#xff1a;當上傳圖片達到一定數量后&#xf…

Golang|工廠模式

工廠模式是一種創建型設計模式&#xff0c;它的核心思想是&#xff1a;把對象的創建過程封裝起來&#xff0c;不直接在代碼中 new 一個對象&#xff0c;而是通過一個“工廠”來生成對象。這樣做的好處是&#xff1a; 降低了代碼之間的耦合&#xff08;依賴具體類減少&#xff0…

CentOS 使用國內鏡像安裝 nvm 和 Node.js 完整指南

前言?&#xff1a; 本文是實踐過程中的個人總結&#xff0c;介紹在 CentOS 系統上通過國內鏡像快速安裝 nvm&#xff08;Node Version Manager&#xff09;&#xff0c;并配置鏡像源加速 Node.js 的下載和依賴管理&#xff0c;解決因網絡問題導致的安裝失敗或速度緩慢。 一、…

ComfyUI 學習筆記:安裝篇及模型下載

背景 去年在掘金看到一個博主使用 ComfyUI 進行 AI 繪畫&#xff0c;并基于此工具展開個人業務。知道了這個東西&#xff0c;感覺很厲害的樣子。 前段時間玩 DeepSeek 的時候&#xff0c;嘗試用它寫《歷史是一群喵》的漫畫&#xff0c;給出了 AI 作畫的提示詞&#xff0c;但是…

人腦、深思考大模型與其他大模型的區別科普

文章目錄 大模型的基本概念與特點深思考大模型的獨特之處深思考大模型與其他大模型的對比架構與技術訓練數據應用場景提示詞編寫 大模型給出答案的方式&#xff1a;基于概率還是真的會分析問題&#xff1f;人腦的思考過程基本單位與網絡大腦結構與功能分區信息處理流程思維模式…

圖像保邊濾波之BEEPS濾波算法

目錄 1 簡介 2 算法原理 3 代碼實現 4 演示Demo 4.1 開發環境 4.2 功能介紹 4.3 下載地址 參考 1 簡介 BEEPS&#xff08;Bias Elimination in Edge-Preserving Smoothing&#xff09; 是一種基于偏微分方程&#xff08;PDE&#xff09;的邊緣保留平滑濾波算法。它能夠…

怎樣給MP3音頻重命名?是時候管理下電腦中的音頻文件名了

在處理大量音頻文件時&#xff0c;給這些文件起一個有意義的名字可以幫助我們更高效地管理和查找所需的內容。通過使用專業的文件重命名工具如簡鹿文件批量重命名工具&#xff0c;可以極大地簡化這一過程。本文將詳細介紹如何利用該工具對 MP3 音頻文件進行重命名。 步驟一&am…

uniapp實現統一添加后端請求Header方法

uniapp把請求寫完了&#xff0c;發現需要給接口請求添加頭部&#xff0c;每個接口去添加又很麻煩&#xff0c;uniapp可以統一添加&#xff0c;并且還能給某些接口設置不添加頭部。 一般用于添加token登錄驗證信息。 在 main.js 文件中配置。 代碼如下&#xff1a; // 在…

Qt/C++面試【速通筆記四】—Qt中的MVC模式

在軟件開發中&#xff0c;設計模式是為了讓代碼結構更加清晰、可維護和擴展的工具。MVC&#xff08;Model-View-Controller&#xff0c;模型-視圖-控制器&#xff09;模式就是其中一種經典的設計模式&#xff0c;它被廣泛應用于圖形界面&#xff08;GUI&#xff09;應用程序中。…

機器學習-入門-線性模型(2)

機器學習-入門-線性模型(2) 3.4廣義線性回歸 一般形式&#xff1a; y g ? 1 ( w T x b ) y g^{-1} \left( w^T x b \right) yg?1(wTxb) 單調可微的聯系函數 (link function) 令 g ( ? ) ln ? ( ? ) g(\cdot) \ln (\cdot) g(?)ln(?) 則得到對數線性回歸 ln ?…

Scratch——第20課 輾轉相除法/繩子算法

輾轉相除法是用于求取最大公約數時需要用到的方法&#xff0c;它還有個名字稱為繩子算法&#xff0c;這類題目只要理解輾轉相處的原理即可拿下。 一、輾轉相除法的基本原理 兩個整數的最大公約數不變&#xff0c;當較大數減去較小數后&#xff0c;得到的差值與較小數的最大公…

【Keil5-開發指南】

Keil5-編程指南 ■ Keil5 介紹■ Keil5 生成bin文件■ 新建工程后debug在 BX R0 不動了■ J-Flash 使用■ Keil5-Debug調試工具 Jlink---STLink---DAP仿真器■ Keil5 使用 AStyle插件格式化代碼■ Keil5-編譯4個階段■ Keil5-Boot和APP配置■ Keil5-報錯■ 芯片手冊區別 ■ Kei…