怎么做交易貓釣魚網(wǎng)站短視頻剪輯培訓班速成
概述
HTML和XML采用類似的標簽形式。
之前在Godot中以函數(shù)庫形式實現(xiàn)了網(wǎng)頁標簽和內(nèi)容生成。能用,但是缺點也很明顯。函數(shù)之間沒有從屬關系,但是多有依賴,而且沒有劃分出各種對象和類型。
如果以完全的面向對象形式來設計標簽類或者元素類,將可以更貼近HTML或XML的本來面目。也更容易生成。
整體思路是設計如下的類繼承結構:
實現(xiàn)之后,將可以充分的定義和生成HTML、XML和SVG標簽,并用于內(nèi)容生成或文檔解析。
通用標簽類
因為HTML和XML標簽的語法格式和要素是類似的,因此可以通過創(chuàng)建一個通用的標簽類,來生成HTML或XML標簽。
MLtag
就是這個通用的標簽類,它定義了幾個核心的屬性:
tag_name
:標簽名稱attrs
:包含標簽所有屬性的字典is_single
:是否為單標簽,默認為false
content
:標簽的子內(nèi)容,可以直接賦值,也可以使用append()
方法追加。單標簽(is_single
為true
)時被忽略get_end_tag()
:獲取結束標簽,單標簽時返回空字符串append()
:追加當前標簽的子內(nèi)容,可以是字符串形式,也可以是SVG標簽實例(會自動調(diào)用to_string()
方法轉化為字符串)
# =============================================
# 名稱:MLtag
# 類型:類
# 描述:HTML、XML通用標簽類,用于定義和生成HTML、XML標簽字符串
# 作者:巽星石
# 創(chuàng)建時間:2024年7月16日17:48:01
# 最后修改時間:2024年7月16日22:27:53
# =============================================
class_name MLTag# ====================== 屬性 ======================
var tag_name = "" # 標簽名稱
var attrs:Dictionary = {} # 屬性字典
var is_single = false # 是否單標簽
var content = "" # 子內(nèi)容 # ====================== 方法 ======================
# 獲取結束標簽
func get_end_tag() -> String:return "" if is_single else "</%s>" % tag_name# 追加子內(nèi)容
func append(new_content) -> void:if new_content is String:content += "\n" + new_contentelse:content += "\n" + new_content.to_string()# ====================== 虛函數(shù) ======================
# 轉化為字符串
func _to_string() -> String:var tag_str:String# 獲取屬性字典的字符串var attr = ""for key in attrs.keys():if attrs[key] != "":attr += "%s=\"%s\" " % [key,attrs[key]]tag_str = "<%s%s/>" % [tag_name," " + attr] if is_single else "<%s%s>%s</%s>" % [tag_name," " + attr,content,tag_name]return tag_str
測試:
@tool
extends EditorScriptfunc _run() -> void:var tag = MLTag.new() # 創(chuàng)建一個標簽tag.name = "a" # 名稱tag.attrs["id"] = "a1" # 設定屬性tag.attrs["href"] = "https://www.runoob.com/"tag.content = "菜鳥教程"print(tag)
默認是雙標簽,也就是帶有起始標簽和結束標簽的標簽對。
<a id="a1" href="https://www.runoob.com/" >菜鳥教程</a>
is_single
設為true
后,就被認為是單標簽:
@tool
extends EditorScriptfunc _run() -> void:var tag = MLTag.new() # 創(chuàng)建一個標簽tag.name = "a" # 名稱tag.attrs["id"] = "a1" # 設定屬性tag.attrs["href"] = "1.com"tag.innerHTML = "hahah"tag.is_single = true # 設為標簽print(tag)
打印輸出的結果也就變了:
<a id="a1" href="https://www.runoob.com/" />
可以看到?jīng)]有了結束標簽,子內(nèi)容部分也自動省略。
HTML標簽基類
# =============================================
# 名稱:HTMLtag
# 類型:類
# 描述:HTML標簽基類
# 作者:巽星石
# 創(chuàng)建時間:2024年7月16日19:05:46
# 最后修改時間:2024年7月16日19:29:34
# =============================================
class_name HTMLTag extends MLTag# ====================== 屬性 ======================
# ID
var id:String:set(val):attrs["id"] = valget:return attrs["id"]
# name
var name:String:set(val):attrs["name"] = valget:return attrs["name"]
# css類名
var className:String:set(val):attrs["class"] = valget:return attrs["class"]
# 行內(nèi)CSS樣式
var style:String:set(val):attrs["style"] = valget:return attrs["style"]
# ====================== 初始化 ======================
func _init() -> void:# HTML標簽通用屬性attrs = {"id" = "", # ID"name" = "", # name屬性"class" = "", # css類名"style" = "", # 行內(nèi)樣式}
測試代碼:
@tool
extends EditorScriptfunc _run() -> void:var tag = HTMLTag.new() # 創(chuàng)建一個標簽tag.tag_name = "a" # 名稱# 設定HTML標簽通用屬性tag.id = "a2"tag.name = "a2"tag.className = "url"tag.style = "font-size:16px;"tag.innerHTML = "一個超鏈接"print(tag)
輸出:
<a id="a2" name="a2" class="url" style="font-size:16px;" >一個超鏈接</a>
HTML<a>標簽
# =============================================
# 名稱:HTMLtagA
# 類型:類
# 描述:HTML的<a>標簽類
# 作者:巽星石
# 創(chuàng)建時間:2024年7月16日19:32:47
# 最后修改時間:2024年7月16日22:30:57
# =============================================
class_name HTMLTagA extends HTMLTag# ====================== 屬性 ======================
# 鏈接地址
var href:String:set(val):attrs["href"] = valget:return attrs["href"]
# 指定鏈接如何在瀏覽器中打開
var target:String:set(val):attrs["target"] = valget:return attrs["target"]
# 鼠標提示文本
var title:String:set(val):attrs["title"] = valget:return attrs["title"]
# 指定與鏈接目標的關系,如 nofollow、noopener 等
var rel:String:set(val):attrs["rel"] = valget:return attrs["rel"]# ====================== 初始化 ======================
func _init() -> void:super() # 初始化父類,否則無法繼承相關的默認屬性# 確定標簽名稱以及是否單標簽tag_name = "a"is_single = false# <a>標簽可用屬性attrs["href"] = "" # 鏈接地址attrs["target"] = "" # 指定鏈接如何在瀏覽器中打開attrs["title"] = "" # 鼠標提示文本attrs["rel"] = "" # 指定與鏈接目標的關系,如 nofollow、noopener 等
測試代碼:
@tool
extends EditorScriptfunc _run() -> void:var link = HTMLTagA.new() # 創(chuàng)建一個標簽# 設定<a>標簽屬性link.href = "https://www.runoob.com/"link.innerHTML = "菜鳥教程"print(link)
輸出:
<a href="https://www.runoob.com/" >菜鳥教程</a>
SVG標簽類
我發(fā)現(xiàn)專門做一個XML標簽基類是沒有必要的,XML本身就沒有固定的標簽,所以由MLTag定義完全可以解決XML標簽定義和生成的功能。
而<svg>
本身既可以算HTML標簽,也可以看做是XML標簽。這里為了簡化,我創(chuàng)建SVG類,代表<svg>
標簽,并直接繼承自MLTag
類型。
# =============================================
# 名稱:SVG
# 類型:類
# 描述:SVG的<svg>標簽類
# 作者:巽星石
# 創(chuàng)建時間:2024年7月16日21:37:24
# 最后修改時間:2024年7月16日21:44:04
# =============================================
class_name SVG extends MLTag# ====================== 屬性 ======================
# SVG畫布寬度
var width:String:set(val):attrs["width"] = valget:return attrs["width"]
# SVG畫布高度
var height:String:set(val):attrs["height"] = valget:return attrs["height"]# ====================== 初始化 ======================
func _init() -> void:tag_name = "svg"# HTML標簽通用屬性attrs = {"version"="1.1","baseProfile"="full","width"="200","height"="200","xmlns"="http://www.w3.org/2000/svg",}
SVGShape
SVG的形狀和路徑有許多共同的屬性,所以抽象出一個SVGShape
類型,用來承載共同屬性。
# =============================================
# 名稱:SVGShape
# 類型:類
# 描述:SVG所有形狀和路徑標簽類的基類,承載共同屬性
# 作者:巽星石
# 創(chuàng)建時間:2024年7月16日21:51:00
# 最后修改時間:2024年7月16日23:07:46
# =============================================
class_name SVGShape extends MLTag# ====================== 屬性 ======================
# 填充顏色
var fill:String:set(val):attrs["fill"] = valget:return attrs["fill"]# 描邊顏色
var stroke:String:set(val):attrs["stroke"] = valget:return attrs["stroke"]# 描邊寬度
var stroke_width:int:set(val):attrs["stroke-width"] = str(val)get:return int(attrs["stroke-width"])# ====================== 初始化 ======================
func _init() -> void:tag_name = "svg"# svg形狀和路徑標簽通用屬性attrs["fill"] = "#fff"attrs["stroke"] = "#000"attrs["stroke-width"] = "1"
矩形
基于SVGShape
類型,我們可以創(chuàng)建SVG具體的形狀和路徑類型。SVGRect
就是SVG矩形
# =============================================
# 名稱:SVGRect
# 類型:類
# 描述:SVG的<rect>標簽類
# 作者:巽星石
# 創(chuàng)建時間:2024年7月16日21:47:43
# 最后修改時間:2024年7月16日22:16:54
# =============================================
class_name SVGRect extends SVGShape# ====================== 屬性 ======================# ---------------------- 位置 ----------------------
# 矩形左上角x坐標
var x:String:set(val):attrs["x"] = valget:return attrs["x"]# 矩形左上角y坐標
var y:String:set(val):attrs["y"] = valget:return attrs["y"]
# ---------------------- 尺寸 ----------------------
# 矩形寬度
var width:String:set(val):attrs["width"] = valget:return attrs["width"]# 矩形高度
var height:String:set(val):attrs["height"] = valget:return attrs["height"]
# ---------------------- 圓角 ----------------------
# 矩形圓角半徑(水平方向)
var rx:String:set(val):attrs["rx"] = valget:return attrs["rx"]# 矩形圓角半徑(垂直方向)
var ry:String:set(val):attrs["ry"] = valget:return attrs["ry"]# ====================== 初始化 ======================
func _init() -> void:super() # 初始化父類,否則無法繼承相關的默認屬性tag_name = "rect"# HTML標簽通用屬性attrs["x"] = "0"attrs["y"] = "0"attrs["width"] = "100"attrs["height"] = "100"attrs["rx"] = "0"attrs["ry"] = "0"
測試代碼:
@tool
extends EditorScriptfunc _run() -> void:var svg = SVG.new() # 創(chuàng)建SVG標簽var rect = SVGRect.new() # 創(chuàng)建矩形svg.append(rect)print(svg)
獲得的SVG代碼:
<svg version="1.1" baseProfile="full" width="200" height="200" xmlns="http://www.w3.org/2000/svg" >
<rect fill="#fff" stroke="#000" stroke-width="1" x="0" y="0" width="100" height="100" rx="0" ry="0" ></rect></svg>
SVG預覽如下:
@tool
extends EditorScriptfunc _run() -> void:var svg = SVG.new(100,200) # 創(chuàng)建SVG標簽var rect = SVGRect.new(0,0,100,200,12,12) # 創(chuàng)建矩形# 設定矩形屬性rect.stroke = "red"rect.stroke_width = 2# 將矩形追加到svg內(nèi)容的末尾svg.append(rect)print(svg) # 打印SVG代碼
獲得的SVG代碼:
<svg version="1.1" baseProfile="full" width="100" height="200" xmlns="http://www.w3.org/2000/svg" >
<rect fill="#fff" stroke="red" stroke-width="2" x="0" y="0" width="100" height="200" rx="12" ry="12" ></rect></svg>
預覽如下:
總結
- 純面向對象的設計,尤其是基于繼承的多個類組成的體系在某些方面還是很有用的。比如HTML、XML、SVG這樣本身就很明顯的繼承設計。
- 基于繼承或許會寫出一堆類,但是輔以類圖和文檔,還是能讓別人比較輕松的理解和掌握的。
- 靜態(tài)函數(shù)庫則完全是一個很差的設計形式,很有可能會被一堆函數(shù)搞得特別臃腫。
- 適當?shù)挠妙惡皖惖睦^承形式取代靜態(tài)函數(shù)庫形式是我正在做的嘗試