moveable 一個可實現前端海報編輯器的 js 庫

目錄

  • 緣由-胡扯
  • 本文實驗環境
  • 通用流程
  • 1.基礎移動
    • 1.1 基礎代碼
      • 1.1.1 data-* 解釋
    • 1.2 操作元素創建
    • 1.3 css 修飾
    • 1.4 cdn 引入
    • 1.5 js 實現元素可移動
    • 1.6 圖片拖拽
    • 2.縮放
    • 3.旋轉
    • 4.裁剪

懶得改文案了,海報編輯器換方案了,如果后面用別的再更。

緣由-胡扯

導火索:睡不著,現在是 25/1/25 快早上了

在這段時間突然有了一個新項目,該項目與前端通過 img 素材編輯一個海報有相同的需求點,又或者說該需求是弱于海報編輯的。

最開始,我是打算直接通過 js 直接實現對應的功能,但是總有一些小bug,剛好公司的前端推給我了 moveable,瞟了一眼后,發現需求完美符合,moveable 可實現前端對單個、多個元素的拖拽、組合、編輯、縮放、旋轉、拉扯等操作,甚至于有一種“殺雞焉用牛刀之感”。

但隨著項目的迭代,未來的需求不可得知,但用發展的眼光看待這個項目的話,直接實現一個海報編輯器是最優的選擇。

接下來我把我總結的 moveable 編寫為教程,包括海報編輯器的制作寫在該文之中,計劃上下兩篇,畢竟一篇使用基礎,另一篇就是編輯器的制作。

想必,各位也不想在二次開發的時候看不懂 moveable 的實現邏輯吧,能平滑過渡就平滑過渡吧,大家的腦子都不想承載過多的計算,張飛:俺也一樣。

本文實驗環境

系統:Windows
前端:html
框架:無
js:其實我不是前端,就當是原生吧,因為筆者并不熟悉標準
編輯器:vs code
參考示例:https://daybrush.com/moveable/storybook/index.html
GitHub:https://github.com/daybrush/moveable
apidoc:https://daybrush.com/moveable/release/latest/doc/

通用流程

首先在此通過 vs 編寫一個基礎的 html (快捷鍵感嘆號會自動彈出,選擇單感嘆號即可):
在這里插入圖片描述
此時選擇之后將會創建一個基礎的 html 基礎代碼(如果沒有的就直接復制吧):

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body></body>
</html>

1.基礎移動

1.1 基礎代碼

我們首先實現 moveable 對元素的基礎移動。

要實現 moveable 的基礎移動需要創建一個 div 為其根容器,此時我們在 body 元素下創建一個 div ,并給與樣式修飾 class="root",此處的樣式修飾并不是必須項,在此只是為了更好的進行演示,當然,在 storybook 上給與的官方示例也是如此。

此時在基礎的 html 元素中的 body 下,創建一個 div 為根節點,代碼如下:

<div class="root"></div>

那么此時根節點有了,接下來就需要創建 moveable 的容器。你聽的沒錯,這是一個比較通用的概念,實現某個特殊的元素時,使用一個容器作為存儲是一個非常常見的方式。

此時在根節點下,創建一個 div 為容器:

<div class="root"><div class="container" data-croffle-ref="element$0"></div>
</div>

在以上的 html 代碼中,樣式修飾為 class="container" 則是容器的元素節點,但可能你對這個節點的疑問在 data-croffle-ref="element$0",如果沒疑問就更好了,在此給一些不理解這個元素屬性的讀者做一下解釋。

1.1.1 data-* 解釋

在以上代碼中 data-croffle-ref 為 html5 引入的一種機制,這個機制簡單的來說是讓開發者在不影響本身元素的語義的情況下,為當前元素增加新的元數據,又或者說開發者自定義了當前元素的屬性

一般 data-* 自定義元數據可以與 document.querySelector 搭配,準確的找到對應的元數據,接下來在編寫 js 代碼時將會解釋這一部分。

在這里,讀者可以理解為此時定義了一個 moveable 的容器,并且自定義了一個屬性 croffle-ref,但由于自定義屬性的編寫方式為帶前綴 data-,即編寫為 data-croffle-ref="element$0",其中 element$0 為這個自定義屬性的值。

1.2 操作元素創建

當創建完操作元素的容器后,接下來創建用于控制的元素,則創建一個拖動、縮放、選擇等操作的元素。

畢竟我們的目標就是添加不同的圖片到當前編輯器,并對這些圖片進行拖拽、旋轉、縮放等操作。

此時在容器下添加一個 div 用于存放對應的操作元素,此時 body 下的html 代碼如下:

<div class="root"><div class="container" data-croffle-ref="element$0"><div class="target" data-croffle-ref="targetRef">Target</div></div>
</div>

以上代碼中,樣式修飾為 class="target" 的 div 元素則為我們的操作元素,并且這個元素由于 moveable 的機制,給與了 data-croffle-ref="targetRef" 的自定義屬性,并且這個 div 的內容為 Target 文本。

1.3 css 修飾

其實也不需要修飾,但是沒有樣式的話可能讀者會覺得很奇怪,讀者可以將 css 刪除查看效果,最后發現還是加上 css 的為好(示例摘抄于 storybook 但做了精簡和增加了便于文章講解的額外內容)。

css 直接復制在 head 上即可,在此處已經給與了 style 標簽:

<style>
.root {position: relative;
}.container {position: relative;margin-top: 50px;
}.target {position: absolute;width: 100px;height: 100px;top: 150px;left: 100px;line-height: 100px;text-align: center;background: #ee8;color: #333;font-weight: bold;border: 1px solid #333;box-sizing: border-box;
}
</style>

以上標簽中,給與了 root 根元素與容器 root 的定位方式為相對定位,接著給與了操作元素 target 的樣式為一個黃色的矩形框。

css 的話我不做多的解釋,其實這是布局設計問題,咱們若不是前端就直接看詳細的功能實現即可,若是前端頁不用說對吧,如果不懂的直接復制即可,畢竟這是個樣式,沒有設計到特效動效制作。

接下來 cdn 引入后會給出這一部分的代碼:

1.4 cdn 引入

以下是 moveable 的 cdn:

<script src="https://cdnjs.cloudflare.com/ajax/libs/moveable/0.53.0/moveable.min.js"integrity="sha512-gFIuV9WCEJeWYkY1ZdJXugypot9ooEtwJf6U8In5JR6z5ZvV1xAvAQe9mQ7IYBXiF9ICXyiCeqgCJzqf64wh7A=="crossorigin="anonymous" referrerpolicy="no-referrer"></script>

如果 cdn 引入有問題,可以在 https://cdnjs.com/libraries/moveable 查看。

此處我也給予 moveable.min.js 的下載地址:TODO

此時的代碼(除 js 外應該是這樣):

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>csdn 1_bit moveable how to use</title><style>.root {position: relative;}.container {position: relative;margin-top: 50px;}.target {position: absolute;width: 100px;height: 100px;top: 150px;left: 100px;line-height: 100px;text-align: center;background: #ee8;color: #333;font-weight: bold;border: 1px solid #333;box-sizing: border-box;}</style>
</head><body><div class="root"><div class="container" data-croffle-ref="element$0"><div class="target" data-croffle-ref="targetRef">Target</div></div></div>
</body></html>

1.5 js 實現元素可移動

在 moveable 中,若想讓一個元素可移動其實很簡單,在此我先列出代碼:

const element$0 = document.querySelector(`[data-croffle-ref="element$0"]`);
const targetRef = document.querySelector(`[data-croffle-ref="targetRef"]`);const moveable$0 = new Moveable(element$0, {target: targetRef,draggable: true,throttleDrag: 1,edgeDraggable: false,startDragRotate: 0,throttleDragRotate: 0}
);moveable$0.on("drag", e => {e.target.style.transform = e.transform;
});

首先我們看最開始的兩行,這兩行都是通過 document.querySelector 尋找元素,其中一個元素是[data-croffle-ref="element$0"] 為容器元素,另一個為 [data-croffle-ref="targetRef"] 為操作元素。

容器元素與操作元素的獲取這兩者是必不可少的,通過確定這倆者從而進行控制。

之前也說過 document.querySelector 與自定義元素搭配即可精確找到元素,在此列出代碼后不再贅述了。

在找到元素后,直接 new 一個 Moveable,其中第一個參數傳入的是在 html 中定義的 element$0;第二個參數則是操作參數,則你需要如何操作這個元素。

第二個參數為一個字典,在字典中指定了操作的元素 targettargetRef,當前全部 key 鍵的解釋如下:

  • target 操作的目標元素
  • draggable 目標元素是否可拖動
  • throttleDrag 拖動的延時毫秒數,設置為 0 則表示實時更新
  • edgeDraggable 表示目標的邊緣是否可拖動
  • startDragRotate 當鼠標旋轉多少后才使元素進行轉動
  • throttleDragRotate 旋轉的延時毫秒數,設置為 0 則表示實時更新

你可能在思考,當前操作只是移動目標元素,并沒有進行旋轉等操作,為什么會有這些參數。

其實當前示例時摘抄于 storybook 之上,在此列出為方便 查看 storybook 演示的讀者作為解釋,當前示例并不需要那么多的參數,只需要傳入如下字典即可實現拖拽操作:

{target: targetRef,//目標元素draggable: true//是否可拖拽
}

那么最后的代碼:

moveable$0.on("drag", e => {e.target.style.transform = e.transform;
});

則表示為 Moveable 實例的 drag 事件添加一個事件監聽器,當目標元素被拖動時,會觸發這個事件監聽器;其中代碼為 e.target.style.transform = e.transform; 則表示事件對象 e 包含了拖動操作的相關信息,其中 e.transform 是拖動后的變換樣式,將 e.transform 的值賦給目標元素的 style.transform 屬性,更新目標元素的位置。

此時當前拖拽的所有代碼如下(省略了 style 樣式,直接復制在 1.3 中的 css 即可):

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>csdn 1_bit moveable how to use</title><script src="https://cdnjs.cloudflare.com/ajax/libs/moveable/0.53.0/moveable.min.js"integrity="sha512-gFIuV9WCEJeWYkY1ZdJXugypot9ooEtwJf6U8In5JR6z5ZvV1xAvAQe9mQ7IYBXiF9ICXyiCeqgCJzqf64wh7A=="crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head><body><div class="root"><div class="container" data-croffle-ref="element$0"><div class="target" data-croffle-ref="targetRef">Target</div></div></div><script>const element$0 = document.querySelector(`[data-croffle-ref="element$0"]`);const targetRef = document.querySelector(`[data-croffle-ref="targetRef"]`);const moveable$0 = new Moveable(element$0, {target: targetRef,draggable: true});moveable$0.on("drag", e => {e.target.style.transform = e.transform;});</script>
</body></html>

此時效果如下:
請添加圖片描述
你可能會想,如果咱們可是使用的是圖片,并不是文字,不要擔心,圖片他來了。

1.6 圖片拖拽

此時在 html 中,操作元素是通過一個容器進行包裹的,既然是容器,那么是包裹整個操作元素的,那么此時我們只需要將操作元素下添加一個圖片即可。

例如在操作元素下添加一個 img 標簽:

<div class="target" data-croffle-ref="targetRef"><img src="1.jpg" alt="" style="width: 100px;height: 100px;">
</div>

此時我給與了這個 img 的樣式修飾 style="width: 100px;height: 100px;",此時的樣式修飾是為了滿足操作元素的大小,否則將會超出(雖然不會影響當前的功能,但美觀上接收不了,之后將會用更加“優雅”的方式解決這個問題)。

圖片各位自己放到自己的路徑下即可,在此不在贅述,此時的結果如下:
請添加圖片描述

2.縮放

注意:以下 html 代碼與 第 1 小點 相同
使用 moveable 還可以對添加的圖片進行縮放,只需要 new 一個Moveable 時傳入不同的參數即可:

const moveable$0 = new Moveable(element$0, {target: targetRef,scalable: true,// 啟用縮放功能,設置為 true 表示允許對目標元素進行縮放操作keepRatio: false,// 將 keepRatio 變量的值賦給配置對象的 keepRatio 屬性,控制縮放時是否保持寬高比renderDirections: renderDirections
});

其中參數定義如下:

  • scalable 啟用縮放功能,設置為 true 表示允許對目標元素進行縮放操作
  • keepRatio 控制縮放時是否保持寬高比
  • false為不保持 renderDirections 控制顯示縮放的控制點

其中 scalable 與 keepRatio 都比較好理解,只有 renderDirections 較為陌生。

renderDirections 是一個 list,這個list 存儲了要顯示控制點的內容,例如這個 renderDirections 的代碼為 const renderDirections = ["n", "s"]; 則表示在北部和南部有一個控制點,即如下圖所示:

在這里插入圖片描述
此時具體 js 代碼部分如下:

const renderDirections = ["n", "s"];
const element$0 = document.querySelector(`[data-croffle-ref="element$0"]`);
const targetRef = document.querySelector(`[data-croffle-ref="targetRef"]`);
const moveable$0 = new Moveable(element$0, {target: targetRef,scalable: true,// 啟用縮放功能,設置為 true 表示允許對目標元素進行縮放操作keepRatio: false,// 控制縮放時是否保持寬高比renderDirections: renderDirections
});moveable$0.on("scale", e => {e.target.style.transform = e.drag.transform;
});

其中代碼:

moveable$0.on("scale", e => {e.target.style.transform = e.drag.transform;
});

為表示監聽 scale 縮放事件,通過 e.drag.transform 得到最新的樣式信息給予到目標元素即可改變以及重新繪制。

此時還可以更改 renderDirections 為 const renderDirections = ["nw","n","ne","w","e","sw","s","se"];,其中 nw 表示東南、ne 表示西南、以此類推運行代碼后展現如下:
在這里插入圖片描述
其展示效果如下:
請添加圖片描述
若將 keepRatio: false,// 控制縮放時是否保持寬高比 改成 true,效果如下:

請添加圖片描述

3.旋轉

設定目標是否可進行旋轉也只是需要 new 一個 moveable 時傳入的參數即可:

const moveable$0 = new Moveable(element$0, {target: targetRef,rotatable: true,rotationPosition: rotationPosition
});

參數說明如下:

  • rotatable 控制目標元素是否可旋轉 true 為允許
  • rotationPosition 指定旋轉控制點的位置

以上代碼中 rotationPosition 設置為字符串類型的 val 為 “top” 即可,即:const rotationPosition = "top";

之后為 moveable$0 設置 rotate 事件監聽:

moveable$0.on("rotate", e => {e.target.style.transform = e.drag.transform;
});

那么即可設置目標元素的響應。

完整的 js 代碼如下:

const rotationPosition = "top";
const element$0 = document.querySelector(`[data-croffle-ref="element$0"]`);
const targetRef = document.querySelector(`[data-croffle-ref="targetRef"]`);
const moveable$0 = new Moveable(element$0, {target: targetRef,rotatable: true,// 控制目標元素是否可旋轉rotationPosition: rotationPosition// 指定旋轉控制點的位置
});
moveable$0.on("rotate", e => {e.target.style.transform = e.drag.transform;
});

此時的 html 代碼并不需要修改,此時頁面所展示的內容如下:

在這里插入圖片描述
此時的控制點在頂部,若設置 rotationPosition 為 bottom const rotationPosition = "bottom"; 時頁面展示效果如下:

在這里插入圖片描述
此時的操作效果如下:
請添加圖片描述

4.裁剪

在 moveable 中,一般情況下,只需要在 new moveable 時傳入不同的參數即可對操作目標開啟不同的操作,最后再為其添加對應操作的事件響應,即可完成對開啟的操作完成監聽。

以下是一個完成裁剪功能的 moveable 代碼:

const moveable$0 = new Moveable(element$0, {target: targetRef,draggable: true,clippable: true,clipTargetBounds: false,
});

以下為各個新增參數的解釋:

  • draggable 控制目標元素是否可拖動
  • clippable 控制目標元素是否可裁剪
  • clipRelative 控制裁剪區域的定位方式
  • clipTargetBounds 控制裁剪區域是否受目標元素邊界限制

此時讀者可能發現,以上再 new moveable 時允許目標可拖動以及目標可剪切,那我該怎么樣監聽兩個事件呢?其實很簡單,只需要使用 on 監聽兩個事件即可,即:

moveable$0.on("drag", e => {e.target.style.transform = e.transform;
});
moveable$0.on("clip", e => {e.target.style.clipPath = e.clipStyle;
});

再 drag 時給與 e.transform 到 e.target.style.transform 的 transform 即可,再 clip 時給與 e.clipStyle 到 e.target.style.clipPath 即可。

接下來我們繼續回到參數之中,其中 clipTargetBounds 表示在裁剪時會不會超出區域了還可以裁剪,當設置為 true 時不允許過邊界(藍框裁剪),結果如下:

請添加圖片描述
如果設置為 false則允許過邊界,效果如下(也演示了拖拽效果):
請添加圖片描述
此時完整的js 代碼如下(html 不需要進行修改):

const element$0 = document.querySelector(`[data-croffle-ref="element$0"]`);
const targetRef = document.querySelector(`[data-croffle-ref="targetRef"]`);const moveable$0 = new Moveable(element$0, {target: targetRef,draggable: true,clippable: true,clipTargetBounds: false,
});moveable$0.on("drag", e => {e.target.style.transform = e.transform;
});moveable$0.on("clip", e => {e.target.style.clipPath = e.clipStyle;
});

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

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

相關文章

Apollo 9.0 速度動態規劃決策算法 – path time heuristic optimizer

文章目錄 1. 動態規劃2. 采樣3. 代價函數3.1 障礙物代價3.2 距離終點代價3.3 速度代價3.4 加速度代價3.5 jerk代價 4. 回溯 這一章將來講解速度決策算法&#xff0c;也就是SPEED_HEURISTIC_OPTIMIZER task里面的內容。Apollo 9.0使用動態規劃算法進行速度決策&#xff0c;從類名…

【Day41 LeetCode】單調棧問題

一、單調棧問題 單調棧問題通常是在一維數組中尋找任一個元素的右邊或者左邊第一個比自己大或者小的元素的位置。 1、每日溫度 739 這題的目的是對于當天&#xff0c;找到未來溫度升高的那一天&#xff0c;也就是當前元素的右邊第一個比自己大的元素。所以我們需要維護一個單…

Cherno C++ P55 宏

這篇文章我們講一下C當中的宏。其實接觸過大型項目的朋友可能都被詭異的宏折磨過。 宏是在預處理當中&#xff0c;通過文本替換的方式來實現一些操作&#xff0c;這樣可以不用反復的輸入代碼&#xff0c;幫助我們實現自動化。至于預處理的過程&#xff0c;其實就是文本編輯&am…

web第三次作業

彈窗案例 1.首頁代碼 <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>綜合案例</title><st…

深入解析LVS命令參數及DR模式下的ARP抑制原理

深入解析LVS命令參數及DR模式下的ARP抑制原理 一、LVS簡介 Linux Virtual Server (LVS) 是基于Linux內核的高性能負載均衡解決方案&#xff0c;支持NAT、DR&#xff08;Direct Routing&#xff09;和TUN&#xff08;IP Tunneling&#xff09;三種模式。其中&#xff0c;ipvsad…

阿里云一鍵部署DeepSeek-V3、DeepSeek-R1模型

目錄 支持的模型列表 模型部署 模型調用 WebUI使用 在線調試 API調用 關于成本 FAQ 點擊部署后服務長時間等待 服務部署成功后&#xff0c;調用API返回404 請求太長導致EAS網關超時 部署完成后&#xff0c;如何在EAS的在線調試頁面調試 模型部署之后沒有“聯網搜索…

Win10環境借助DockerDesktop部署大數據時序數據庫Apache Druid

Win10環境借助DockerDesktop部署最新版大數據時序數據庫Apache Druid32.0.0 前言 大數據分析中&#xff0c;有一種常見的場景&#xff0c;那就是時序數據&#xff0c;簡言之&#xff0c;數據一旦產生絕對不會修改&#xff0c;隨著時間流逝&#xff0c;每個時間點都會有個新的…

【第13章:自監督學習與少樣本學習—13.1 自監督學習最新進展與實現方法】

凌晨三點的實驗室,博士生小王盯著屏幕里正在"自娛自樂"的神經網絡——這個沒有吃過一張標注圖片的模型,正在通過旋轉、拼圖、填色等游戲任務,悄悄掌握著理解世界的秘訣。這種魔法般的修煉方式,正是當今AI領域最炙手可熱的技術:自監督學習。 一、打破數據枷鎖:自…

數據庫報錯1045-Access denied for user ‘root‘@‘localhost‘ (using password: YES)解決方式

MySQL 報錯 1045 表示用戶root從localhost連接時被拒絕訪問&#xff0c;通常是因為密碼錯誤、權限問題或配置問題。以下是解決該問題的常見方法&#xff1a; 方法一&#xff1a;檢查用戶名和密碼 ? 確認用戶名和密碼是否正確&#xff1a; 確保輸入的用戶名和密碼完全正確&am…

八大排序——簡單選擇排序

目錄 1.1基本操作&#xff1a; 1.2動態圖&#xff1a; 1.3代碼&#xff1a; 代碼解釋 1. main 方法 2. selectSort 方法 示例運行過程 初始數組 每輪排序后的數組 最終排序結果 代碼總結 1.1基本操作&#xff1a; 選擇排序&#xff08;select sorting&#xff09;也…

與傳統光伏相比 城電科技的光伏太陽花有什么優勢?

相比于傳統光伏&#xff0c;城電科技的光伏太陽花有以下優勢&#xff1a; 一、發電效率方面 智能追蹤技術&#xff1a;光伏太陽花通過內置的智能追蹤系統&#xff0c;采用全球定位跟蹤算法&#xff0c;能夠實時調整花瓣&#xff08;即光伏板&#xff09;的角度&#xff0c;確…

FPGA的星辰大海

編者按 時下風頭正盛的DeepSeek,正值喜好宏大敘事的米國大統領二次上崗就業,OpenAI、軟銀、甲骨文等宣布投資高達5000億美元“星際之門”之際,對比尤為強烈。 某種程度上,,是低成本創新理念的直接落地。 包括來自開源社區的諸多贊譽是,并非體現技術有多“超越”,而是…

Elasticsearch:15 年來致力于索引一切,找到重要內容

作者&#xff1a;來自 Elastic Shay Banon 及 Philipp Krenn Elasticsearch 剛剛 15 歲了&#xff01;回顧過去 15 年的索引和搜索&#xff0c;并展望未來 15 年的相關內容。 Elasticsearch 剛剛成立 15 周年。一切始于 2010 年 2 月的一篇公告博客文章&#xff08;帶有標志性的…

嵌入式軟件、系統、RTOS(高軟23)

系列文章目錄 4.2嵌入式軟件、系統、RTOS 文章目錄 系列文章目錄前言一、嵌入式軟件二、嵌入式系統三、嵌入式系統分類四、真題總結 前言 本節講明嵌入式相關知識&#xff0c;包括軟件、系統。 一、嵌入式軟件 二、嵌入式系統 三、嵌入式系統分類 四、真題 總結 就是高軟筆記…

數據結構 day02

3. 線性表 3.1. 順序表 3.1.3. 順序表編程實現 操作&#xff1a;增刪改查 .h 文件 #ifndef __SEQLIST_H__ #define __SEQLIST_H__ #define N 10 typedef struct seqlist {int data[N];int last; //代表數組中最后一個有效元素的下標 } seqlist_t;//1.創建一個空的順序表 seq…

數據恢復-01-機械硬盤的物理與邏輯結構

磁盤存儲原理 磁盤存儲數據的原理&#xff1a; 磁盤存儲數據的原理是利用磁性材料在磁場作用下的磁化性質&#xff0c;通過在磁盤表面上劃分成許多小區域&#xff0c;根據不同的磁化方向來表示0和1的二進制數據&#xff0c;通過讀寫磁頭在磁盤上的移動&#xff0c;可以實現數據…

wordpress get_footer();與wp_footer();的區別的關系

在WordPress中&#xff0c;get_footer() 和 wp_footer() 是兩個不同的函數&#xff0c;它們在主題開發中扮演著不同的角色&#xff0c;但都與頁面的“頁腳”部分有關。以下是它們的區別和關系&#xff1a; 1. get_footer() get_footer() 是一個用于加載頁腳模板的函數。它的主…

DeepSeek 通過 API 對接第三方客戶端 告別“服務器繁忙”

本文首發于只抄博客&#xff0c;歡迎點擊原文鏈接了解更多內容。 前言 上一期分享了如何在本地部署 DeepSeek R1 模型&#xff0c;但通過命令行運行的本地模型&#xff0c;問答的交互也要使用命令行&#xff0c;體驗并不是很好。這期分享幾個第三方客戶端&#xff0c;涵蓋了桌…

跟著李沐老師學習深度學習(十一)

經典的卷積神經網絡 在本次筆記中主要介紹一些經典的卷積神經網絡模型&#xff0c;主要包含以下&#xff1a; LeNet&#xff1a;最早發布的卷積神經網絡之一&#xff0c;目的是識別圖像中的手寫數字&#xff1b;AlexNet&#xff1a; 是第一個在大規模視覺競賽中擊敗傳統計算機…

使用JavaScript實現深淺拷貝

1. 拷貝的基本概念和必要性 在 JavaScript 中&#xff0c;數據類型分為基本數據類型&#xff08;如 Number、String、Boolean、Null、Undefined、Symbol&#xff09;和引用數據類型&#xff08;如 Object、Array&#xff09;。基本數據類型存儲的是值本身&#xff0c;而引用數…