Gox語言中用代碼繪圖顯示在圖形界面中并讓它實現(xiàn)自動旋轉(zhuǎn)效果-GX39

結(jié)合之前文章中的例子莺治,我們這次來用代碼繪制一個圖形耕漱,然后顯示在用Sciter制作的GUI圖形界面中,并且讓它自動旋轉(zhuǎn)羊异。

下面的例子中的信息量很大,除了之前的使用gg包進行代碼繪圖彤断,還演示了純用Gox代碼來操控HTML中的DOM元素(完全不使用Sciter中的TiScript)野舶,包括手動創(chuàng)建元素、選擇元素和設(shè)置其屬性等宰衙,并通過修改圖片標簽的transform樣式屬性平道,結(jié)合Go語言中的協(xié)程(類似線程)實現(xiàn)圖形不斷旋轉(zhuǎn)的效果。

先來看看最終實現(xiàn)的效果:

準備要做的界面就是這樣的供炼,簡簡單單巢掺,最上面是一個div,其中一個span顯示紅字劲蜻,下面就是一個img標簽裝載的圖形陆淀。程序運行后,圖形將以中心為軸每個1秒中順時針旋轉(zhuǎn)45度先嬉。

下面就是實現(xiàn)該效果的完整代碼:

// 設(shè)置image/color包的簡稱
// github.com/fogleman/gg包已經(jīng)默認簡稱gg
color = image_color

// 建立imagetk包的引用轧苫,注意該包的用法比較特殊
itk = imagetk.NewImageTK()

// 建立一個繪圖環(huán)境,圖片大小為 600×400 像素
contextT = gg.NewContext(600, 400)

// 用十六進制方式設(shè)置當(dāng)前顏色
contextT.SetHexColor("FFFFFF")

// 用當(dāng)前顏色來清空整個圖片
contextT.Clear()

// 設(shè)置線寬為 2 個像素
contextT.SetLineWidth(2)

// 設(shè)置RGB顏色疫蔓,每種顏色的數(shù)值范圍是 0.0 - 1.0
contextT.SetRGB(0.0, 0.0, 1.0)

// 畫一個圓含懊,以坐標為 (200, 200) 的點為圓心,半徑為 50像素
contextT.DrawCircle(250, 250, 60)

// 真正進行線條繪制衅胀,并且保留繪圖路徑以便后面填充顏色
contextT.StrokePreserve()

// 創(chuàng)建一個漸變色填充方案 gradientT
// 是兩點之間的圓環(huán)式漸變色
gradientT = gg.NewRadialGradient(250, 250, 0, 250, 250, 80)

// 創(chuàng)建一個顏色的基本方法
colorT = new(color.RGBA)
colorT.R = uint8(0)
colorT.G = uint8(0)
colorT.B = uint8(0)
colorT.A = uint8(255)

gradientT.AddColorStop(0, colorT)

// 注意創(chuàng)建顏色的快捷方法
gradientT.AddColorStop(1, itk.NewRGBA(0, 0, 255, 255))

// 設(shè)置用漸變色 gradientT 填充
contextT.SetFillStyle(gradientT)

// 真正進行填充岔乔,并清除繪畫路徑,因為后面已經(jīng)不需要了
contextT.Fill()

// 開始用填充的方式繪制一個矩形

// 用RGBA色彩體系設(shè)置當(dāng)前顏色
// 用 0 - 255 的數(shù)值范圍表示顏色和透明度
// 設(shè)置一定的透明度以便顯示出被覆蓋住的圖形(圓形)
contextT.SetRGBA255(0, 255, 0, 180)

// 繪制一個左上角點坐標為 (300, 200)滚躯,寬 100雏门,高 100的矩形
contextT.DrawRectangle(300, 200, 100, 100)

// 僅填充顏色不繪制邊線
contextT.Fill()

// 開始用路徑法畫一個三角形

// 用十六進制字符串設(shè)置顏色
// 可以加上前面的“#”號嘿歌,也可以后面加上一個字節(jié)表示透明度
contextT.SetHexColor("#FF000099")

// 將虛擬的畫筆移動到坐標為 (300, 120) 的點
contextT.MoveTo(300, 120)

// 從當(dāng)前點繪制一條線到坐標為 (240, 230)的點為止
// 當(dāng)前點將隨之移動到 (240, 230)
contextT.LineTo(240, 230)

// 繼續(xù)繪制一條直線到 (360, 230)
contextT.LineTo(360, 230)

// 繼續(xù)繪制一條直線到 (300, 120)
contextT.LineTo(300, 120)

// 創(chuàng)建一個新的線性漸變色
gradientT = gg.NewLinearGradient(240, 120, 360, 230)

// 注意從16進制數(shù)字創(chuàng)建顏色的方法
gradientT.AddColorStop(0, itk.NewRGBAFromHex("#00FF00FF"))
gradientT.AddColorStop(1, itk.NewRGBAFromHex("0000FFFF"))
gradientT.AddColorStop(0.5, itk.NewRGBAFromHex("FF0000"))

// 漸變色也可以用于線條顏色的漸變
contextT.SetStrokeStyle(gradientT)

// 設(shè)置粗一點的線寬以體現(xiàn)漸變色
contextT.SetLineWidth(10)

// 真正繪制三角形
contextT.Stroke()

// 從gg的畫布獲取Go語言中的image.Image對象
// 注意 := 和 = 作為賦值用,在Gox語言中是等價的
img := contextT.Image()


// 創(chuàng)建一個字節(jié)緩沖區(qū)茁影,用于存放圖片的二進制數(shù)據(jù)
bufT  = new(bytes.Buffer)

// 將生成的圖片以PNG格式編碼到緩沖區(qū)中
image_png.Encode(bufT, img)

// 獲取字節(jié)緩沖區(qū)的字節(jié)數(shù)組([]byte)類型引用
dataT =  bufT.Bytes()

// 設(shè)置github.com/sciter-sdk/go-sciter及其子包window的簡稱
sciter = github_scitersdk_gosciter
window = github_scitersdk_gosciter_window

// 將圖片的字節(jié)數(shù)組數(shù)據(jù)轉(zhuǎn)換為BASE64編碼的字符串
base64StrT := tk.EncodeToBase64(dataT)

// 設(shè)置Sciter格式的HTML網(wǎng)頁字符串
// 此處非常簡單宙帝,就是一個網(wǎng)頁框架
// 后續(xù)DOM操作將由Gox代碼來進行
// 注意,為了正確在Sciter中顯示中文募闲,最好加上兩種meta定義utf-8編碼
htmlT := `
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
</body>
</html>

`

// 鎖定GUI線程步脓,理論上GUI編程都要求在同一線程中更新界面元素
runtime.LockOSThread()

// 創(chuàng)建Sciter窗口,并指定窗口區(qū)域位置及大小
w, err := window.New(sciter.DefaultWindowCreateFlag, sciter.NewRect(0, 0, 800, 600))

checkError(err)

// 設(shè)置該窗口的一些屬性
w.SetOption(sciter.SCITER_SET_SCRIPT_RUNTIME_FEATURES, sciter.ALLOW_FILE_IO | sciter.ALLOW_SOCKET_IO | sciter.ALLOW_EVAL | sciter.ALLOW_SYSINFO)

// 載入HTML頁面框架
// 第二個參數(shù)是基URL(base url)浩螺,我們一般不用
w.LoadHtml(htmlT, "")

// 設(shè)置窗口標題靴患,注意是中文的
w.SetTitle("圖片轉(zhuǎn)向")

// 獲取Sciter頁面的根元素
rootT, _ := w.GetRootElement()

// 獲取body元素
bodyT, _ := rootT.SelectFirst("body")

// 創(chuàng)建一個div,其中文本為空(第二個參數(shù))
divT, _ := sciter.CreateElement("div", "")

// 在body元素中插入div要出,第二個參數(shù)是插入的位置
_ := bodyT.Insert(divT, 0)

// 設(shè)置div的innerHTML
// 第二個標志SIH_REPLACE_CONTENT表示替換innerHTML的全部
// 還有可用的標志位有SIH_INSERT_AT_START蚁廓、SIH_APPEND_AFTER_LAST
// SOH_REPLACE、SOH_INSERT_BEFORE厨幻、SOH_INSERT_AFTER相嵌,看名字即可知道大意
divT.SetHtml(`<span id="titleTextID">演示圖片</span>`, sciter.SIH_REPLACE_CONTENT)

// 設(shè)置div的id屬性
divT.SetAttr("id", "mainDivID")

// 設(shè)置div的style屬性(即CSS)
divT.SetStyle("margin-bottom", "10px")

// 獲取我們之前定義的span標簽
// 這是在設(shè)置div的HTML中用文本定義的
// 注意選擇器的快捷寫法
spanT, _ := bodyT.SelectFirst("span#titleTextID")

// 設(shè)置文字顏色為紅色
spanT.SetStyle("color", "#ff0000")


// 再創(chuàng)建一個img元素準備裝載圖片
imgT, _ := sciter.CreateElement("img", "")

// 在body中插入元素,序號為1况脆,也就是第二個元素饭宾,即在前面的div之后
_ := bodyT.Insert(imgT, 1)

// 設(shè)置該元素的src屬性為BASE64格式的圖片
imgT.SetAttr("src", `data:image/png;base64,`+base64StrT)

// 設(shè)置圖片初始的旋轉(zhuǎn)角度為0,即不旋轉(zhuǎn)
imgT.SetStyle("transform", "rotate(0deg)")

// 設(shè)置旋轉(zhuǎn)的旋轉(zhuǎn)軸為圖片中心點
imgT.SetStyle("transform-origin", "50% 50%")

// 輸出目前的根節(jié)點的HTML文本以供參考
// 第二個參數(shù)為true表示是outerHTML格了,否則是innerHTML
plv(rootT.Html(true))

// 啟動一個goroutine協(xié)程看铆,負責(zé)圖片旋轉(zhuǎn)
// 由于后面的w.Run是阻塞的,所以必須要用線程來處理旋轉(zhuǎn)
// 旋轉(zhuǎn)的方法是不斷修改img元素的transform樣式的角度值
// 每次順時針旋轉(zhuǎn)45度
go func() {
    angleT := 0

    for i= 0; i< 20; i ++ {
        // 旋轉(zhuǎn)20次盛末,每次間隔1秒
        tk.SleepSeconds(1)

        angleT += 45

        imgT.SetStyle("transform", fmt.Sprintf("rotate(%ddeg)", angleT))
    }
}()


// 顯示窗口并運行GUI圖形界面
w.Show()
w.Run()


代碼中依然有非常詳盡的注釋弹惦,實現(xiàn)思路也非常清晰。附加幾點說明:

  • 為代碼清晰悄但,一些異常情況還是沒有處理棠隐;
  • 輸出的結(jié)果HTML中,一些屬性可能會沒有檐嚣;
  • 旋轉(zhuǎn)為20次助泽,通過循環(huán)控制,可以設(shè)置成無限
  • 注意嚎京,Gox制作的圖形界面程序嗡贺,如果Windows上不想出現(xiàn)CMD的黑框,可以下載Goxg版本鞍帝,或者在自行編譯時诫睬,加上ldflags="-H windowsgui"參數(shù)。

注意:

  • Gox語言是脫胎于Go語言(Golang)的開源腳本語言帕涌,解釋執(zhí)行摄凡,但相比Go語言更貼近高級語言续徽,語法硬性限制也少一些;是一門偏向快速應(yīng)用的語言架谎,也可以說是一個集成工具;

  • Gox語言主要優(yōu)勢有三點:

    • 第一辟躏,Gox語言本身只有一個可執(zhí)行文件谷扣,綠色免配置,下載即可使用捎琐,無需安裝Go語言環(huán)境会涎,無需編譯,非常適合快速制作原型以及云服務(wù)器上的遠程開發(fā)瑞凑;
    • 第二末秃,Gox中可以直接使用絕大多數(shù)Go語言標準庫中的對象和方法函數(shù),也內(nèi)置了很多常用籽御、優(yōu)秀的第三方庫练慕,充分發(fā)揮Go語言多年積累的資源優(yōu)勢;
    • 第三技掏,與很多其他主流語言不同铃将,Gox語言著力解決了GUI圖形界面編程的問題,內(nèi)置了基于Giu(imgui)哑梳、LCL劲阎、Sciter的三套圖形界面編程庫,直接可以進行快捷高效的圖形界面開發(fā)(LCL鸠真、Sciter只需分別下載一個動態(tài)鏈接庫文件悯仙,執(zhí)行和分發(fā)時附帶上即可),特別適合編寫演示原型系統(tǒng)吠卷。

作為腳本語言锡垄,Gox語言性能肯定不如Go語言這樣的編譯型語言快,但由于Gox語言與Go語言的緊密聯(lián)系祭隔,Gox語言編寫的腳本可以很容易的改寫成Go語言代碼偎捎,編譯執(zhí)行后就可以發(fā)揮Go語言的速度優(yōu)勢了。因此序攘,Gox語言也比較適合做初期的Go語言調(diào)試茴她,還有一個更直接的方式是使用Gotx(在Gox官網(wǎng)上也有下載),這是使用完全和Go語言一樣語法的解釋器程奠,可以理解成集成了Go語言標準庫和不少第三方庫的解釋執(zhí)行的Go語言丈牢,一樣也不需要搭建Go語言環(huán)境。Gotx與Gox的區(qū)別在于瞄沙,Gotx仍然遵循Go語言的文法己沛,代碼相對復(fù)雜一些慌核,限制也多一些,但改寫回Go語言準備編譯執(zhí)行時申尼,基本上沒有成本垮卓。

Gox的官網(wǎng)在這里,也可以在瀏覽器搜索引擎中直接搜索“gox語言”师幕,Github頁面在這里粟按,在這里可以看到很多Gox語言的學(xué)習(xí)指南和實際應(yīng)用實例。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霹粥,一起剝皮案震驚了整個濱河市灭将,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌后控,老刑警劉巖庙曙,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浩淘,居然都是意外死亡捌朴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門张抄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來男旗,“玉大人,你說我怎么就攤上這事欣鳖〔旎剩” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵泽台,是天一觀的道長什荣。 經(jīng)常有香客問我,道長怀酷,這世上最難降的妖魔是什么稻爬? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮蜕依,結(jié)果婚禮上桅锄,老公的妹妹穿的比我還像新娘。我一直安慰自己样眠,他們只是感情好友瘤,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著檐束,像睡著了一般辫秧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上被丧,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天盟戏,我揣著相機與錄音绪妹,去河邊找鬼。 笑死柿究,一個胖子當(dāng)著我的面吹牛邮旷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蝇摸,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼婶肩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了探入?” 一聲冷哼從身側(cè)響起狡孔,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤懂诗,失蹤者是張志新(化名)和其女友劉穎蜂嗽,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殃恒,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡植旧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了离唐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片病附。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亥鬓,靈堂內(nèi)的尸體忽然破棺而出完沪,到底是詐尸還是另有隱情,我是刑警寧澤嵌戈,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布覆积,位于F島的核電站,受9級特大地震影響熟呛,放射性物質(zhì)發(fā)生泄漏宽档。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一庵朝、第九天 我趴在偏房一處隱蔽的房頂上張望吗冤。 院中可真熱鬧,春花似錦九府、人聲如沸椎瘟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽降传。三九已至,卻和暖如春勾怒,著一層夾襖步出監(jiān)牢的瞬間婆排,已是汗流浹背声旺。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留段只,地道東北人腮猖。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像赞枕,于是被迫代替她去往敵國和親澈缺。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359