整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          TaskBuilder用echarts第三方水球插件實現動態水球波紋圖表的方法

          /準備echarts腳本文件

          官網下載最新版本:https://echarts.apache.org/zh/download.html

          開源庫下載:https://cdn.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js

          //5.33改成最新版本的版本號 就可以下載最新版本了

          下載第三方水球庫插件:https://github.com/ecomfe/echarts-liquidfill

          1. 打開軟件 新建一個頁面 添加一個容器組件 用于綁定圖表對象 組件名稱隨便填寫 后面要用到

          2.添加一個事件來加載圖表腳本,我用的的頁面加載時 ,也可以添加后臺服務組件,通過后臺服務組件事件:服務響應時來調用腳本 可以很方便的綁定數據

          3.添加剛才下載echarts腳本文件

          添加第三方水球插件:

          引入腳本

          一個簡單的例子

          要創建液體填充圖表,您需要有一個類型為'liquidFill'. 一個基本選項可能是:

          option = { series: [{ type: 'liquidFill', data: [0.6] }] };

          多波

          很容易創建一個帶有多個波浪的液體填充圖表,或者表示多個數據,或者提高圖表的視覺效果。

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3]}]};

          這將在 60%、50%、40% 和 30% 的位置創建一個帶有波浪的圖表。

          顏色和不透明度

          要為液體填充圖表系列設置顏色,請設置color為顏色數組。要設置不透明度,請使用itemStyle.opacity和itemStyle.emphasis.opacity用于普通樣式和懸停樣式。

          option = { series: [{ type: 'liquidFill', data: [0.5, 0.4, 0.3], color: ['red', '#0f0', 'rgb(0, 0, 255)'], itemStyle: { opacity: 0.6 }, emphasis: { itemStyle: { opacity: 0.9 } } }] };

          您還可以通過以下方式設置單個數據項的顏色和不透明度:

          option = { series: [{ type: 'liquidFill', data: [0.5, 0.4, { value: 0.3, itemStyle: { color: 'red', opacity: 0.6 }, emphasis: { itemStyle: { opacity: 0.9 } } }] }] };

          靜波

          為了防止波浪向左或向右移動,您可以簡單地設置waveAnimation為false。要禁用波浪上升的動畫,請將animationDuration和設置animationDurationUpdate為 0。

          option = { series: [{ type: 'liquidFill', waveAnimation: false, animationDuration: 0, animationDurationUpdate: 0, data: [0.6, 0.5, 0.4, 0.3] }] };

          靜止波

          您可以將 設置amplitude為 0 以產生靜止波。

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3], amplitude: 0, waveAnimation: 0 }] };

          在這種情況下建議設置waveAnimation為 false 以禁用動畫以考慮性能。

          改變單個波

          要更改單個波形,請覆蓋數據項中的選項。

          option = { series: [{ type: 'liquidFill', data: [0.6, { value: 0.5, direction: 'left', itemStyle: { color: 'red' } }, 0.4, 0.3] }] };

          背景樣式

          您可以使用 backgroundStyle 選項來設置背景形狀的筆觸、填充樣式。

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3], backgroundStyle: { borderWidth: 5, borderColor: 'red', color: 'yellow' } }] };

          輪廓樣式

          要隱藏輪廓,只需設置outline.show為false。

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3], outline: { show: false } }] };

          形狀

          水填充圖表的形狀。有可能:

          • //默認形狀:'circle',圓形 'rect'正方形, 'roundRect'圓角正方形, 'triangle'三角形, 'diamond'菱形, 'pin'氣球形, 'arrow'多邊三角形;
          • 'container':完全填滿容器的形狀。
          • 'path://'以.開頭的 SVG 路徑
          options = [{ series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3], shape: 'diamond' }] }];

          option = {
              series: [{
                  type: 'liquidFill',
                  data: [0.5, 0.4, 0.3, 0.2],
                  shape: 'container',
                  outline: {
                      show: false
                  }
              }]
          };

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.55, 0.4, 0.25], radius: '60%', outline: { show: false }, backgroundStyle: { borderColor: '#156ACF', borderWidth: 1, shadowColor: 'rgba(0, 0, 0, 0.4)', shadowBlur: 20 }, shape: 'path://M367.855,428.202c-3.674-1.385-7.452-1.966-11.146-1.794c0.659-2.922,0.844-5.85,0.58-8.719 c-0.937-10.407-7.663-19.864-18.063-23.834c-10.697-4.043-22.298-1.168-29.902,6.403c3.015,0.026,6.074,0.594,9.035,1.728 c13.626,5.151,20.465,20.379,15.32,34.004c-1.905,5.02-5.177,9.115-9.22,12.05c-6.951,4.992-16.19,6.536-24.777,3.271 c-13.625-5.137-20.471-20.371-15.32-34.004c0.673-1.768,1.523-3.423,2.526-4.992h-0.014c0,0,0,0,0,0.014 c4.386-6.853,8.145-14.279,11.146-22.187c23.294-61.505-7.689-130.278-69.215-153.579c-61.532-23.293-130.279,7.69-153.579,69.202 c-6.371,16.785-8.679,34.097-7.426,50.901c0.026,0.554,0.079,1.121,0.132,1.688c4.973,57.107,41.767,109.148,98.945,130.793 c58.162,22.008,121.303,6.529,162.839-34.465c7.103-6.893,17.826-9.444,27.679-5.719c11.858,4.491,18.565,16.6,16.719,28.643 c4.438-3.126,8.033-7.564,10.117-13.045C389.751,449.992,382.411,433.709,367.855,428.202z', label: { position: ['38%', '40%'], formatter: function() { return 'ECharts\nLiquid Fill'; }, fontSize: 40, color: '#D94854' } }] };

          動畫

          一般來說,液體填充圖表中有兩種類型的動畫。
          第一種是初始動畫,具有升浪的效果。此動畫的緩動方法由 控制,animationEasing其持續時間由控制animationDuration。
          第二種是更新動畫,通常在數據變化、波高變化時使用。它們由animationEasingUpdate和控制animationDurationUpdate。
          例如,要禁用提升動畫并將更新動畫時間設置為 2 秒cubicOut,可以使用以下選項:

          var mytubiao = echarts.init(document.getElementById("mytb"))

          option = {
          series: [{
          type: 'liquidFill',
          data: [0.6, 0.5, 0.4, 0.3],
          animationDuration: 0,
          animationDurationUpdate: 2000,
          animationEasingUpdate: 'cubicOut'
          }]
          };
          mytubiao.setOption(option);
          setTimeout(function () {
          mytubiao.setOption({
          series: [{
          type: 'liquidFill',
          data: [0.8, 0.6, 0.4, 0.2]
          }]
          })
          }, 3000);

          更改文本

          默認情況下,液體填充圖表的文本標簽顯示第一個數據的百分比。例如,對于帶有 data 的圖表[0.6, 0.5, 0.4, 0.3],默認文本是60%.

          要更改文本,您可以使用label.formatter,它可以設置為字符串或函數。

          如果是字符串,{a}則表示系列名稱、{b}數據名稱和{c}數據值。

          option = { series: [{ type: 'liquidFill', name: 'Liquid Fill', data: [{ name: 'First Data', value: 0.6 }, 0.5, 0.4, 0.3], label: { formatter: '{a}\n{b}\nValue: {c}', fontSize: 28 } }] };
          此示例的標簽文本為'Liquid Fill\nFirst Data\nValue: 0.6'.

          formatter這與作為函數使用的結果相同:

          option = { series: [{ type: 'liquidFill', name: 'Liquid Fill', data: [{ name: 'First Data', value: 0.6 }, 0.5, 0.4, 0.3], label: { formatter: function(param) { return param.seriesName + '\n' + param.name + '\n' + 'Value:' + param.value; }, fontSize: 28 } }] };
          文本位置默認在中心。label.position可以設置為'inside', 'left', 'right', 'top', 'bottom', 或水平和垂直位置,例如['10%', '20%'],表示'10%'向左(由 控制label.align,可以是'left'、'center'或'right')和'20%'頂部(由 控制label.baseline,可以是'top'、'middle'或'bottom')。
          陰影
          默認情況下,波浪和輪廓上有陰影。以下是如何更改它們。

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3], itemStyle: { shadowBlur: 0 }, outline: { borderDistance: 0, itemStyle: { borderWidth: 5, borderColor: '#156ACF', shadowBlur: 20, shadowColor: 'rgba(255, 0, 0, 1)' } } }] };

          工具提示

          添加工具提示:
          option = { series: [{ type: 'liquidFill', data: [0.6], name: 'Liquid Fill' }], tooltip: { show: true } };

          點擊事件

          要在 wave 上添加點擊事件:

          chart.setOption(option); chart.on('click', function() { console.log(arguments); // do something useful here });

          與任何其他圖表類型一樣,上述代碼只會觸發波事件。如果要跟蹤整個畫布或特定元素上的事件,可以將偵聽器添加到 zrender,例如:

          chart.getZr().on('click', function() { console.log(arguments); });

          不可交互

          要使元素(例如,波浪)不可交互,只需設置silent為true.

          option = { series: [{ type: 'liquidFill', data: [0.6, 0.5, 0.4, 0.3], silent: true }] };

          API

          液體填充圖表的默認選項是:

          {

          data: [],

          color: ['#294D99', '#156ACF', '#1598ED', '#45BDFF'],

          center: ['50%', '50%'],

          radius: '50%',

          amplitude: '8%',

          waveLength: '80%',

          phase: 'auto',

          period: 'auto',

          direction: 'right',

          shape: 'circle',

          waveAnimation: true,

          animationEasing: 'linear',

          animationEasingUpdate: 'linear',

          animationDuration: 2000,

          animationDurationUpdate: 1000,

          outline: {

          show: true,

          borderDistance: 8,

          itemStyle: {

          color: 'none',

          borderColor: '#294D99',

          borderWidth: 8,

          shadowBlur: 20,

          shadowColor: 'rgba(0, 0, 0, 0.25)'

          }

          },

          backgroundStyle: {

          color: '#E3F7FF'

          },

          itemStyle: {

          opacity: 0.95,

          shadowBlur: 50,

          shadowColor: 'rgba(0, 0, 0, 0.4)'

          },

          label: {

          show: true,

          color: '#294D99',

          insideColor: '#fff',

          fontSize: 50,

          fontWeight: 'bold',

          align: 'center',

          baseline: 'middle'

          position: 'inside'

          },

          emphasis: {

          itemStyle: {

          opacity: 0.8

          }

          }

          }

          數據{(數字|對象)[]}

          每個數據項的值應介于 0 和 1 之間。

          數據項也可以是配置單個項的選項的對象。

          option = {

          series: [{

          type: 'liquidFill',

          data: [0.6, {

          value: 0.5,

          itemStyle: {

          color: 'red'

          }

          }, 0.4, 0.3]

          }]

          };

          這定義了具有第二波紅色的圖表。

          顏色 {string[]}

          波浪顏色。

          形狀 {字符串}

          水填充圖表的形狀。它可以是默認符號之一:'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'. 或者,以 . 開頭的 SVG 路徑'path://'。

          中心{字符串[]}

          圖表的位置。第一個值是 x 位置,第二個值是 y 位置。每個值都可以是一個相對值,例如'50%',它是相對于容器寬度和高度的較小值的,也可以是一個絕對值,例如100px。

          半徑 {字符串}

          圖表的半徑,可以是相對值,如'50%',相對于容器寬度和高度的較小值,也可以是絕對值,如100px。

          幅度{數}

          波的幅度,以像素或百分比為單位。如果它是百分比,它是相對于直徑的。

          波長 {字符串|數字}

          波的波長,可以是相對值,例如'50%',它是相對于直徑的,也可以是絕對值,例如'100px'或100。

          階段{編號}

          波的相位,以弧度表示。默認情況下'auto',當每個波的相位Math.PI / 4大于前一個時,它被設置為 。

          周期 {number|'auto'|function}

          向前移動一個波長所需的毫秒數。默認情況下,'auto'當前面的波速度較大時,它被設置為 。

          它也可以是格式化程序功能。

          option = {

          series: [{

          type: 'liquidFill',

          data: [0.6, 0.5, 0.4, 0.3],

          radius: '70%',

          phase: 0,

          period: function (value, index) {

          // This function is called four times, each for a data item in series.

          // `value` is 0.6, 0.5, 0.4, 0.3, and `index` is 0, 1, 2, 3.

          return 2000 * index + 1000;

          }

          }]

          }

          方向 {字符串}

          波浪移動的方向,應該是'right'或'left'。

          waveAnimation {boolean}

          是否啟用向左或向右移動的波浪。

          動畫緩動 {字符串}

          初始動畫的緩動方法,當波浪從底部開始上升時。

          animationEasingUpdate {字符串}

          其他動畫的緩動方法,例如,當數據值改變和波浪位置改變時。

          動畫持續時間 {數字}

          初始動畫持續時間,以毫秒為單位。

          animationDurationUpdate {數字}

          其他動畫持續時間,以毫秒為單位。

          大綱.show {布爾}

          是否顯示輪廓。

          大綱.borderDistance {number}

          邊界和內圈之間的距離。

          outline.itemStyle.borderColor {字符串}

          邊框顏色。

          outline.itemStyle.borderWidth {number}

          邊框寬度。

          outline.itemStyle.shadowBlur {number}

          輪廓陰影模糊大小。

          outline.itemStyle.shadowColor {字符串}

          輪廓陰影顏色。

          backgroundStyle.color {字符串}

          背景填充顏色。

          backgroundStyle.borderWidth {字符串}

          背景描邊線寬。

          backgroundStyle.borderColor {字符串}

          背景描邊線寬。

          backgroundStyle.itemStyle.shadowBlur {number}

          背景陰影模糊大小。

          backgroundStyle.itemStyle.shadowColor {字符串}

          背景陰影顏色。

          backgroundStyle.itemStyle.opacity {number}

          背景不透明度。

          itemStyle.opacity {number}

          波浪不透明度。

          itemStyle.shadowBlur {number}

          波浪陰影寬度。

          itemStyle.shadowColor {字符串}

          波浪陰影顏色。

          強調.itemStyle.opacity {number}

          懸停時波浪不透明度。

          標簽.show {布爾}

          是否顯示標簽文本。

          label.color {字符串}

          在背景上顯示時文本的顏色。

          label.insideColor {字符串}

          在波形上顯示時文本的顏色。

          label.fontSize {數字}

          標簽字體大小。

          標簽.fontWeight {字符串}

          標簽字體粗細。

          標簽對齊{字符串}

          文本對齊,應該是'left', 'center', 或'right'.

          label.baseline {字符串}

          文本垂直對齊,應為'top'、'middle'或'bottom'。

          標簽位置 {string|string[]}

          文本位置默認在中心。label.position可以設置為'inside', 'left', 'right', 'top', 'bottom', 或水平和垂直位置,例如['10%', '20%'],表示'10%'左側和'20%'頂部。

          需要JavaScript,也不需要圖片,只用純CSS就能實現多種炫酷的Loading特效!我這次創作的兩個圓形Loading特效,大小不斷變換,就像是在呼吸一樣,讓人忍不住一直盯著它看。如果你也想要讓你的網站更加吸引人,不妨試試用純CSS來實現自己的Loading特效吧!

          經在只有 Objective-C. 的日子里,封裝只能使用類~(真是累。。。)

          然而現在 Swift 中有三個選擇——枚舉,結構,類

          結合協議 ,這些類型看以發灰經人的威力,雖然他們有很多共同的能力。但是他們也有很多重要的區別。

          那么今天跟大家分享的是

          ● 枚舉,結構,類的使用經驗

          ● 關于如何使用他們的直覺

          ● 了解他們的工作原理

          根據這些先決條件,Vergil. 在這邊假設大家有一些 Swift 基礎還有面向對象的編成經驗(只有 Objective-C 基礎也可以唷)

          一切都跟這些類型有關。

          Swift 三大賣點就是 安全 快速 簡易,安全意味著很少會因為意外的方式運行錯誤的代碼,破壞內存并產生難以發現的錯誤。 Seift 會在編譯的時候顯示問題,而不是在運行的時候顯示出來,從而是其變的更明顯。

          另外,Swift. 可以清楚的表達意圖,因此可以幫助你的代碼快速運行。

          Swift 語言的核心就是簡單還和高度的規范化,這是建立在驚人的少量概念上的。盡管規則比較簡單,但是還是可以用它做出驚人的事情,食蟹這一目標的關鍵就是 Swift. 系統

          Swift 類型是強大的~盡管只有六個。沒錯。

          不像其他語言多達十幾種內置類型的語言。

          Swift. 只有六種。他們分別是:協議,枚舉,結構體,類。另外兩個則是復合類型:元祖,函數。

          其他你能想到的基本類型,比方說 Bool,Int,UInt,Float,Double,Character,String,Array,Set,Dictionary,Optional,等

          那么今天我們的重點就放在 enum, struct 還有 class.

          ————————

          這邊有段 HTML5 的代碼,然後我們的目標是要實現這個效果

          <!DOCTYPE html><html><body><svg width='250' height='250'><rect x='110.0' y='10.0' width='100.0' height='130.0' stroke='teal' fill='aqua' stroke-width='5' /><circle cx='80.0' cy='160.0' r='60.0' stroke='red' fill='yellow' stroke-width='5' /></svg></body></html>

          那麼我們就需要一個顏色來表示啦~ 在 SVG 中是可以使用指定名稱來表示 RGB 類型的。

          如果說要在 SVG. 中使用顏色,那麼我們就要指定某一個圖形的一部分屬性,比方說 fill = 'gray' 這樣的一個簡單的方式在 swfit 就是幾這個 String 做一個轉換

          let fill = 'gary'

          但是他也有明顯的缺點的~

          1. 任何不屬于顏色的文字都會被運行~比方說 ‘grayy’,’grey’ 之類的,很多時候我們自己都不知道錯在哪里了~

          2. 智能提示不會提示 String, 這讓人很蛋疼 Xcode. 稱霸世界的就是他的智能提示了

          3. 當我們把它當作參數傳遞顏色的時候,可能不是很明顯地表示這個名字是一種顏色

          enum 登場

          小伙伴這個時候想說~ 哼哼~ 我自定義一個類型不就可以解決了嗎?

          這個時候肯定已經在想封裝一個 UIColor. 的類。但是這個時候~他真的是唯一的選擇嗎?

          小伙伴們可能想要這樣子實現~

          enum ColorName: String {

          case black = "black"

          case silver = "silver"

          case gray = "gray"

          case white = "white"

          case maroon = "maroon"

          case red = "red"

          // ... and so on ...

          }

          這種很類似 C.的風格~ 也是 Objective-C小伙伴的反射思考,但是 Swfit. 不太一樣,Swift 可以選定一種類型來表示每種情況~

          什么意思呢?就是說我們可以指定一個 backing store 類型的枚舉被叫做 RawRepresentable 因為他們會自動采用 RawRepresentable 協議,因此我們可以指定 ColorNameas 的類型 String 并為每個案例分配一個值

          enum ColorName: String {

          case black = "black"

          case silver = "silver"

          case gray = "gray"

          case white = "white"

          case maroon = "maroon"

          case red = "red"

          // ... and so on ...

          }

          但是 String 代表性的枚舉做了特別的事情!如果沒有指定特別的情況,編譯器就會自動使 String. 與案例名稱相同。這意味著我們只需要寫案例的名字。

          enum ColorName: String {

          case black

          case silver

          case gray

          case white

          case maroon

          case red

          // ... and so on ...

          }

          當然啦~ 我們也可以透過 , 來區分。減少我們的輸入

          enum ColorName: String {

          case black, silver, gray, white, maroon, red, purple, fuchsia, green, lime, olive, yellow, navy, blue, teal, aqua

          }

          現在我們擁有一個一流的訂制類型的好處~享受它吧

          Associated Values 相關值

          ColorName 對于顏色的命名~

          當然是好的,但是 CSS 里面到底有多少種顏色表示:named, RGB, HSL 等等~

          我們又要怎么模擬這些呢?

          Swift 中的枚舉非常適合用于建模具有多種表現形式的東西,比方說 CSS 的顏色,每個枚舉都可以有自己的數據配對,這些數據就叫做關聯值

          CSSColor 通過將他添加近來定義使用枚舉:

          enum CSSColor {

          case named(ColorName)

          case rgb(UInt8, UInt8, UInt8)

          }

          通過這個定義,我們可以給 CSSColor 模型兩種狀態。

          1. 它可以是 named, 在這種情況下,相關連的數據就是一個 ColorName

          2. 它可以是 rgb 在這種情況下,他的相關數據就是 紅 藍 綠 (0-255)的數字

          具有枚舉的協議和方法 Protocols and Methods with an Enum

          現在我們想要打印出多個實例 CSSColor ,在 Swfit. 中枚舉和大家一樣,也可以使用協議的,很特別吧!我們來試試看使用神奇的協議吧。

          extension CSSColor: CustomStringConvertible {

          var description: String {

          switch self {

          case .named(let colorName):

          return colorName.rawValue

          case .rgb(let red, let green, let blue):

          return String(format: "#%02X%02X%02X", red,green,blue)

          }

          }

          }

          這個 CSSColor 結合了 CustomStringConvertible,這是告訴 Swift 我們的 CSSColor. 類型,可以轉換成字符串。我們告訴他怎么通過 description 計算屬性。

          那么在這邊, self. 切換到底層模型是否為 RGB 類型。在這種情況下,我們可以將顏色轉換成所需要的字符串形式。命名的時候我們只返回字符串名稱,RGB 的時候我們則返回所需要的 紅 藍 綠的數值。

          我們來看看吧~

          let color1 = CSSColor.named(.red)

          let color2 = CSSColor.rgb(0xAA, 0xAA, 0xAA)

          print("color1 = \(color1), color2 = \(color2)") // prints color1 = red, color2 = #AAAAAA

          一切都在編譯的時候被檢查出來是正確的!是不是比當初我們只用 String. 來顯示顏色好多了呢?

          > 注意:雖然我們可以對于 CSSColor. 定義并對他進行修改,但是我們不需要這么做!我們只需要接著去擴展他,并且遵循新的協議就可以了。

          > 擴展是很好的!因為它使我們定義符合了特定的協議,在這種狀況下 CustomStringConvertible 需要給 description 定義一個字符串屬性實現一個 getter

          伴隨枚舉的初始化

          就像 Swift 中的類和結構一樣,我們可以往枚舉里面添加自訂義初始化值

          extension CSSColor {

          init(gray: UInt8) {

          self = .rgb(gray, gray, gray)

          }

          }

          然後我們來使用它試試看~

          let color3 = CSSColor(gray: 0xaa)

          print(color3) // prints #AAAAAA

          現在我們比更方便的來創建灰色的色彩了~!

          伴隨枚舉的命名空間

          命名的類型可以當作命名空間來保持複雜性的最小化,像我們創造了 ColorName 和 CSSColor,如果我們可以隱藏 ColorName 在 CSSColor 裡面,那不是更好嗎?

          extension CSSColor {

          enum ColorName: String {

          case black, silver, gray, white, maroon, red, purple, fuchsia, green, lime, olive, yellow, navy, blue, teal, aqua

          }

          }

          > 注意:Swift. 里面有一個很大的特點就是,你會發現聲明的順序通常不重要,編譯器會多次掃瞄文件,并將他們編號。不需要像是。C/ C++ /Objective-C 一樣照順序聲明。

          枚舉也可以設置單純的命名空間,比方說我們需要用到一個數學常數黃金比例。phi

          enum Math {

          static let phi = 1.6180339887498948482 // golden mean

          }

          這個 Math 不包含了任何的 case , 并且在擴展里面添加新的 case 是非法的~這個時候我們就可以在枚舉里面處理了,這個 phi. 是個靜態長涼,不需要實例化,沒當我們需要黃金比例數字的時候可以用簡單的 Math.phi 就可以拿到,而不是記住所有的數字!

          記錄枚舉

          到目前為止我們可以知道 枚舉在 Swift. 中比在其他語言中強大的太多太多,因為我們可以將它擴展,可以創建自定義初始化方法,提供命名空間并且封裝相關操作。

          那么我們現在已經習慣了 enum 的 CSS. 顏色模塊,這樣很好~ 因為CSS的顏色很好理解,就是遵循 W3C. 規范

          枚舉對於眾所週知的事物挑選有很好的作用,比方說一週中的第幾天,硬幣的正反面什麼的,毫無疑問。 Swift. 的可選功能(optionals) 是具有 .none 或是 .some. 的狀態來實現的!

          好的,現在我們進入下個模型類型 結構!?

          結構體

          完成了顏色之後,我們希望用戶能夠在 SVC. 中字定義自己喜歡的形狀,所以這個時候使用 enum 就不是一個很好的選擇。

          因為新的 enum 不能在裡面擴展方法,所以我們交給 struct. 還有 class 來做~

          protocol Drawable {

          func draw(with context: DrawingContext)

          }

          protocol DrawingContext {

          func draw(circle: Circle)

          // more primitives will go here ...

          }

          這裡有一個 Drawable 協議 裡面有一個繪製的方法,叫做draw

          我們要用它來繪製其他的幾何圖形,比方說圓形,矩形。

          我們會發現這個時候他抱錯~

          因為我們沒有實現 Circle. 的繪製方法,所以我們就來實現一下吧~

          struct Circle : Drawable {

          var strokeWidth = 5

          var strokeColor = CSSColor.named(.red)

          var fillColor = CSSColor.named(.yellow)

          var center = (x: 80.0, y: 160.0)

          var radius = 60.0

          // Adopting the Drawable protocol.

          func draw(with context: DrawingContext) {

          context.draw(circle: self)

          }

          }

          當然啦~我們還有很多選擇~SVG,HTML5 Canvas,Core Graphics,OpenGL,Metal 都是不錯的選擇,這邊只是跟大家說明他的用法,接下來我們要準備好讓 Circle. 繼承的 Drawable

          在一個中struct,您將存儲的屬性組合在一起。在這里您已經實現了以下屬性:

          ● strokeWidth:行的寬度。

          ● strokeColor:線條的顏色。

          ● fillColor:填充圓的顏色。

          ● center:圓的中心點。

          ● radius:圓的半徑。

          結構體跟類有關鍵的差異,最大的區別就是結構體是 值 類型,而類是引用類型。

          值和參考值Value vs. Reference Types

          值跟參考值是兩個單獨且不同的實體,典型的值就是一個整數。比方說 Int

          var a = 10

          var b = a

          a = 30 // b仍然具有值10.

          a == b

          對於 Circle (使用 struct)

          var a = Circle()

          a.radius = 60.0

          var b = a

          a.radius = 1000.0 // b.radius仍然具有值60.0

          如果我們已經從一個類型創建了 Circle. 那麼他被賦予的就是參考值,表示說他引用了一個底層對象。

          使用這個值來創建新對象的時候,會複製這個值,當屎引用類型相同的對象的時候,新的變量會引用相同的對象,這就是 class. 跟 struct 的關鍵差異了!

          矩形模型

          我們來畫一個矩形吧

          struct Rectangle : Drawable {

          var strokeWidth = 5

          var strokeColor = CSSColor.named(.teal)

          var fillColor = CSSColor.named(.aqua)

          var origin = (x: 110.0, y: 10.0)

          var size = (width: 100.0, height: 130.0)

          func draw(with context: DrawingContext) {

          context.draw(rectangle: self)

          }

          }

          我們還需要使用 DrawingContext 協議,讓他知道如何去繪製。

          protocol DrawingContext {

          func draw(_ circle: Circle)

          func draw(_ rectangle: Rectangle)

          // more primitives would go here ...

          }

          這兩個方法都是遵循協議的時候要做的,現在我們可以來畫一個具有 SCV. 風格的圖了

          final class SVGContext : DrawingContext {

          private var commands: [String] = []

          var width = 250

          var height = 250

          // 1

          func draw(circle: Circle) {

          commands.append("<circle cx='\(circle.center.x)' cy='\(circle.center.y)\' r='\(circle.radius)' stroke='\(circle.strokeColor)' fill='\(circle.fillColor)' stroke-width='\(circle.strokeWidth)' />")

          }

          // 2

          func draw(rectangle: Rectangle) {

          commands.append("<rect x='\(rectangle.origin.x)' y='\(rectangle.origin.y)' width='\(rectangle.size.width)' height='\(rectangle.size.height)' stroke='\(rectangle.strokeColor)' fill='\(rectangle.fillColor)' stroke-width='\(rectangle.strokeWidth)' />")

          }

          var svgString: String {

          var output = "<svg width='\(width)' height='\(height)'>"

          for command in commands {

          output += command

          }

          output += "</svg>"

          return output

          }

          var htmlString: String {

          return "<!DOCTYPE html><html><body>" + svgString + "</body></html>"

          }

          }

          SVGContext 是一個包含了一組私有命令字符串的類,在第一還有第二部份中,我們使用 DrawingContext 協議,繪制方法只是附加一個帶有正確的XML大字符串形式

          最後,我們需要一個可以包含許多 Drawable 對象的結構

          struct SVGDocument {

          var drawables: [Drawable] = []

          var htmlString: String {

          let context = SVGContext()

          for drawable in drawables {

          drawable.draw(with: context)

          }

          return context.htmlString

          }

          mutating func append(_ drawable: Drawable) {

          drawables.append(drawable)

          }

          }

          這裏~ htmlString 是一個計算 SVGDocument 的屬性,創建一個 SVGContext 從上到下完整的 htmlString

          顯示SVG

          好了~最後我們就要看到效果了~

          var document = SVGDocument()

          let rectangle = Rectangle()

          document.append(rectangle)

          let circle = Circle()

          document.append(circle)

          let htmlString = document.htmlString

          print(htmlString)

          我們可以看到,成功的整合出了文件~

          我們試試看按住。Command-Option-Return 可以在助理編輯器里面看到 web. 的效果

          到目前為止,我們使用了結構和協議的組合來實現可繪制的模型。

          即使現在你不用他,了解這種方法對你還是有幫助的!

          那么在代碼中,他看起來是不是有點像是下面的代碼~這邊只是參考,可以不用把他加進去

          class Shape {

          var strokeWidth = 1

          var strokeColor = CSSColor.named(.black)

          var fillColor = CSSColor.named(.black)

          var origin = (x: 0.0, y: 0.0)

          func draw(with context: DrawingContext) { fatalError("not implemented") }

          }

          class Circle: Shape {

          override init() {

          super.init()

          strokeWidth = 5

          strokeColor = CSSColor.named(.red)

          fillColor = CSSColor.named(.yellow)

          origin = (x: 80.0, y: 80.0)

          }

          var radius = 60.0

          override func draw(with context: DrawingContext) {

          context.draw(self)

          }

          }

          class Rectangle: Shape {

          override init() {

          super.init()

          strokeWidth = 5

          strokeColor = CSSColor.named(.teal)

          fillColor = CSSColor.named(.aqua)

          origin = (x: 110.0, y: 10.0)

          }

          var size = (width: 100.0, height: 130.0)

          override func draw(with context: DrawingContext) {

          context.draw(self)

          }

          }

          為了讓我們使用面向對象編程更安全,Swift.引入了 override. 關鍵字,他要求你自己去承認你覆寫了東西

          他可以防止意外的觸碰到現有的方法,或者不正確的覆蓋你以前的方法。在使用新版的庫的時候了解事情發生了變化,他可是一個救命者啊

          盡管如此,這種面向對象的‘分法還是存在一些缺點的,比方說,我們在幾類中實現的, Shape 想要被避免被濫用,他會呼吁 fatalError() 提醒我們需要覆蓋這個方法,不幸的是這個檢查是在運行的時候發生,而不是編譯的時候。

          其次 Circle. 還有 Rectangle 必須處理幾類數據的初始化。雖然這是一件很容易的事情,但是為了確保正確性,類的初始化還是可能變成一個有些涉及的過程。

          第三,往後會證明基類是一個棘手的東西。

          假如說,我們想要添加一個 drawable Line class. 那麼為了與現有的系統協同工作,他必須從中得出。Shape. 這是一個誤區。

          基於這點~我們可以重構我們的結構層次,然而項目一但大了,這是一個幾乎不可能的任務,我們甚至可能無法修改基類,而且通常都會有很多問題。

          最後,class. 存在一個之前討論過的問題,引用。雖然自動引用計數器(ARC) 大部分的時間都在處理事情,但是我們需要注意不要引入循環飲用,否則最後會導致內存泄露。

          如果我們將相同的shape導入到shape數組中,那麼假設當我們有一種形狀的顏色修改為紅色的時候,另一種形狀會令人驚訝的跟著修改。

          為什么只使用一個類?

          鑑於以上幾點,可能小夥伴就覺得奇怪了,為什麼會永遠想使用僅僅一個類?

          對於初學者來說,他們允許你採用成熟且經過測試的框架,比如說。Cocoa和 Cocoa touch

          另外,Class. 的確有更重要的用途,比如說 一個大的內存占用,昂貴的復制對象在類中包裝好的候選者, Class 也可以很好的模擬身份。我們可以看到很多 View顯示相同對象的情況。如果該對象被修改,所有的View也反映了模型中的修改。使用值類型,同步更新也會遇到問題~

          計算屬性

          所以命名的模型類型都可以創建不一定對應儲存屬性的自定義 setter 和 getter.

          假如我們想要添加一個直徑的 getter 和 setter. 到我們的 Circle 模型。在現有的 radius 很容易實現

          extension Circle {

          var diameter: Double {

          get {

          return radius * 2

          }

          set {

          radius = newValue / 2

          }

          }

          }

          在這實現了一個純碎的半徑的計算屬性。當我們想要獲得直徑的時候只要把半徑的長度乘上二就好了~

          相同的情況下,我們想要畫出一個圓的面積還有週長的時候可以這樣做,

          跟類的使用方法不同,在默認的情況下, Struct. 方法不允許修改,也就是 mutating. 如果我們把屬性聲明為 mutating 的話就看以這樣做了

          比方說~我們把這個方法添加到 Circle. 擴展中

          我們志個時候在自定義一個 Shift() 移動圓的方法,簡單的說就是改變他的圓心。

          但是這會改變 center.x 還有 center.y 所以他會抱錯~

          這個時候不要驚慌~ 我們把這個方法前面加上一個 mutating 就可以了!

          mutating func shift(x: Double, y: Double) {

          center.x += x

          center.y += y

          }

          這個故事告訴我們~ 我們其實是可以改變 struct. 的!

          追溯模型和類型約束

          Swift 有一大特點就是 追溯模型(Retroactive Modeling), 簡單的說它允許你擴展模型的行為,就算你沒有源代碼!

          這裡有個範例,假設說你是 SVG 開發者,並且希望添加 area 和 perimeter 屬性 to Rectangle

          extension Rectangle {

          var area: Double {

          return size.width * size.height

          }

          var perimeter: Double {

          return 2 * (size.width + size.height)

          }

          }

          以前我們想把方法透過 extenstion. 添加到現有的模型中,現在我們把這些方法都獲做協議

          protocol ClosedShape {

          var area: Double { get }

          var perimeter: Double { get }

          }

          這是一個官方協議~然后我們就可以告訴圓形還有矩形采用這個協議

          extension Circle: ClosedShape {}

          extension Rectangle: ClosedShape {}

          當然我們也可以定義一過寒數,例如,計算ClosedShape 協議的模型數組,的總周長,

          func totalPerimeter(shapes: [ClosedShape]) -> Double {

          return shapes.reduce(0) { >return shapes.reduce(0) { $0 + $1.perimeter }< + .perimeter }

          }

          totalPerimeter(shapes: [circle, rectangle])

          ————————

          好了

          我們今天分享了關于 enum. Struct. 還有 Class 的用法,這三者都有關鍵的相似之處,他們都可以封裝,都可以初始化,也具有計算屬性,可以采用協議,并且追溯模型

          但是他們也是有重要的區別的!

          • 枚舉是具有一個組案例的值類型,每種情況都可以具有不同的參考值。

          • 枚舉類型的每個直表示枚舉定義的單個大小,他們不能儲存任何屬性。

          • 結構體是值類型,也可以具有存儲的屬性。

          • 類,他也可以存儲,並切他們可以被建構到覆蓋屬性和方法類的結構層次中,因次 基類的初始化是一個需求,但是和其他人不同,類可以引用,也就是共享。

          希望今天的分享對你有幫助~


          主站蜘蛛池模板: 亚洲AV无码一区二区三区电影| 亚洲爽爽一区二区三区| 成人免费一区二区三区在线观看| 色一情一乱一伦一区二区三区日本| 亚洲av午夜福利精品一区人妖| 成人精品一区二区三区校园激情| 亚洲一区综合在线播放| 中文字幕一区二区三区有限公司 | 国产成人精品一区二三区熟女 | 日本精品一区二区在线播放 | 精品一区二区久久久久久久网站| 日本精品一区二区三区在线视频一 | 亚洲综合一区国产精品| 久久精品黄AA片一区二区三区| 99国产精品一区二区| 99久久精品国产高清一区二区| 久久精品国产亚洲一区二区三区| 日本在线观看一区二区三区| 免费人人潮人人爽一区二区| 精品免费国产一区二区三区| 夜夜高潮夜夜爽夜夜爱爱一区| 夜夜高潮夜夜爽夜夜爱爱一区| 国产精品视频无圣光一区| 成人免费一区二区无码视频| 国产精品99精品一区二区三区 | 国偷自产Av一区二区三区吞精| 岛国无码av不卡一区二区| 成人国内精品久久久久一区| 精品aⅴ一区二区三区| 日韩欧国产精品一区综合无码| 水蜜桃av无码一区二区| 中文字幕日韩一区二区三区不卡| 亚拍精品一区二区三区| 国产成人午夜精品一区二区三区| 精品视频一区在线观看| 久久精品无码一区二区日韩AV| 亚洲国产精品一区第二页| 91精品乱码一区二区三区| 国产精品盗摄一区二区在线| 久久精品人妻一区二区三区| 无码囯产精品一区二区免费 |