一、云空间创建
1、点击官方链接即可开始创建工作空间
2、查看已创建好的工作空间
二、云IDE使用
1、在 git 地址钱加入 ide 回车即可访问云IDE
2、可以看到 云IDE 的界面跟本地的 VSCODE IDE 界面是相同的
图-云IDE
图-本地 IDE
3、云IDE 优点
云端预制了常见的开发环境,无需下载安装,一键创建项目,灵活配置代码仓和云主机。同时支持在线安装 VSCode 插件来增强使用体验,支持从基础组件快速构建高阶组件,无需重新编写组件,提高研发效率。随时随地开发编码,拥有媲美本地IDE 的流畅编码体验。
三、封装工具
1、该工具用于生成指定春联,指定:words 内容,horV 方向,font 字体
2、原理是在图片上渲染字体像素
package util
import (
"flag"
"github.com/golang/freetype"
"image"
"image/color"
"image/png"
"io/ioutil"
"log"
. "mock/lib/font/config"
"os"
)
// charset 中文文字
// horV - H-横排,V-竖排
// out 输出文件名
// font 字体
func Generator(charset []string, outPath string, horV string, textFont TextFont) {
// 打开背景图
bgFile, err := os.OpenFile("../img/bg.png", os.O_RDONLY, 6)
if err != nil {
log.Fatal(err)
}
defer bgFile.Close()
// 解码
i, err := png.Decode(bgFile)
if err != nil {
log.Fatal(err)
}
// 图片的宽度
srcWidth := 640
// 图片的高度
srcHeight := 640
if horV == "H" {
srcWidth = 640 * len(charset)
}
if horV == "V" {
srcHeight = 640 * len(charset)
}
imgFile, _ := os.Create(outPath)
defer imgFile.Close()
img := image.NewRGBA(image.Rect(0, 0, srcWidth, srcHeight))
if horV == "H" {
log.Println("横向生成,渲染背景...")
// 根据字符长度创建背景
for index := 0; index < len(charset); index++ {
// 复制背景图
for y := 0; y < srcHeight; y++ {
for x := index * 640; x < srcWidth; x++ {
if x < 640 {
img.Set(x, y, i.At(x, y))
} else {
img.Set(x, y, i.At(x-index*640, y))
}
}
}
}
}
if horV == "V" {
log.Println("竖向生成,渲染背景...")
// 根据字符长度创建背景
for index := 0; index < len(charset); index++ {
// 复制背景图
for y := index * 640; y < srcHeight; y++ {
for x := 0; x < srcWidth; x++ {
if y < 640 {
img.Set(x, y, i.At(x, y))
} else {
img.Set(x, y, i.At(x, y-index*640))
}
}
}
}
}
// 读取字体数据
fontFileName := "../lib/font/" + textFont.FontName
fontBytes, err := ioutil.ReadFile(fontFileName)
log.Printf("加载字体:%s...", textFont.FontName)
if err != nil {
log.Fatal(err)
}
// 载入字体数据
font, err := freetype.ParseFont(fontBytes)
if err != nil {
log.Println("载入字体失败!", err)
}
f := freetype.NewContext()
// 设置分辨率
f.SetDPI(100)
// 设置字体
f.SetFont(font)
// 设置尺寸
f.SetFontSize(textFont.FontSize)
f.SetClip(img.Bounds())
// 设置输出的图片
f.SetDst(img)
// 设置字体颜色(黑色)
f.SetSrc(image.NewUniform(color.Black))
if horV == "H" {
log.Println("开始绘制对联...")
// 绘制字符
for index := 0; index < len(charset); index++ {
// 设置字体的位置
pt := freetype.Pt(textFont.X+index*640, textFont.Y)
_, err = f.DrawString(charset[index], pt)
if err != nil {
log.Fatal(err)
}
}
}
if horV == "V" {
// 绘制字符
for index := 0; index < len(charset); index++ {
// 设置字体的位置
pt := freetype.Pt(textFont.X, textFont.Y+index*640)
_, err = f.DrawString(charset[index], pt)
if err != nil {
log.Fatal(err)
}
}
}
// 以png 格式写入文件作为输出
err = png.Encode(imgFile, img)
if err != nil {
log.Fatal(err)
}
log.Println("Done.")
}
四、Template 引用 Element UI
1、参考 Element 官方文档
2、页面功能:用户在输入框填写文本,选择效果(方向,字体)后,点击 Run 按钮,返回用户预期效果图片
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
<div class="demo-image__lazy" style="margin-top:30px;">
<el-image src="../res/3f8b879b-fa29-4dda-8e08-1f82cbd2d895.png"></el-image>
</div>
<el-input placeholder="请输入内容" v-model="input" clearable>
</el-input>
<el-radio v-model="horV" label="H">水平方向</el-radio>
<el-radio v-model="horV" label="V">垂直方向</el-radio>
<el-radio v-model="font" label="font1">字体1</el-radio>
<el-radio v-model="font" label="font2">字体2</el-radio>
<el-button style="margin-left: 10px;margin-top:30px;" size="small" type="success" @click="submitUpload"
v-loading.fullscreen.lock="fullscreenLoading" element-loading-text="拼命加载中">Run
</el-button>
<div class="demo-image__lazy" style="margin-top:30px;">
<el-image v-for="url in urls" :key="url" :src="url" lazy></el-image>
</div>
</div>
</body>
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue@2/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
horV: 'H',
font: 'font1',
input: '',
urls: [],
fullscreenLoading: false
};
},
methods: {
// 提交表单
submitUpload() {
if (this.input.length > 0) {
console.log(this.input, this.horV, this.font);
let formdata = {
words: this.input,
horV: this.horV,
font: this.font,
};
this.fullscreenLoading = true;
var that = this;
axios({
url: '/api/GetImg',
method: 'post',
data: formdata,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(function (response) {
console.log('success');
console.log(response);
that.urls = response.data.urls;
that.fullscreenLoading = false;
})
.catch(function (error) {
console.log('error');
console.log(error);
});
}
}
}
})
</script>
</html>
五、定义控制器
1、Index 用于返回定义好的 Index.tmpl 模板
2、GetImg 用于响应页面请求
package controller
import (
"net/http"
"github.com/gin-gonic/gin"
"mock/lib/font/config"
. "mock/util"
uuid "github.com/satori/go.uuid"
)
// 首页
func Index(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", nil)
}
// 参数 worlds,horV,font => 春联内容,方向,字体
func GetImg(c *gin.Context) {
// ================== 参数处理
words := c.PostForm("words")
// 处理字符
var charset []string
if len(words) > 0 {
for _, v := range words {
charset = append(charset, string(v))
}
} else {
charset = []string{"你", "好", "世", "界"}
}
// 处理方向
horV := c.PostForm("horV")
if len(horV) > 0 {
if horV != "H" && horV != "V" {
horV = "H"
}
} else {
horV = "H"
}
// 输出路径
outPath := "../res/" + uuid.NewV4().String() + ".png"
// 处理字体
font := config.Font_1
ft := c.PostForm("font")
if len(ft) > 0 {
if ft != "font1" && ft != "font2" {
font = config.Font_1
}
} else {
font = config.Font_1
}
// 生成对联
Generator(charset, outPath, horV, font)
// 返回数组
urls := []string{outPath}
c.JSON(http.StatusOK, gin.H{
"status": "success",
"urls": urls,
})
}
六、跨域中间件
1、如果不做跨域配置,axios 请求可能会被拦截
package middleware
import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"time"
)
// 跨域请求
func Cors() gin.HandlerFunc {
handlerFunc := cors.New(cors.Config{
AllowMethods: []string{"*"},
AllowHeaders: []string{"content-type", "token", "fileType", "size", "digest"}, //此处设置非默认之外的请求头(自定义请求头),否则会出现跨域问题
AllowAllOrigins: true,
AllowCredentials: true,
MaxAge: 24 * time.Hour,
ExposeHeaders: []string{"*"},
})
return handlerFunc
}
// gin 上下文配置 cors
func CORSMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, PUT, HEAD, OPTIONS")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
}
}
//nginx 跨域
//server {
//#以上省略
//add_header 'Access-Control-Allow-Origin' '*';
//add_header 'Access-Control-Allow-Headers' 'X-Pagination-Current-Page,Content-Type';
//add_header 'Access-Control-Allow-Methods' 'PUT,GET,POST,HEAD,DELETE';
//add_header 'Access-Control-Expose-Headers' 'X-Pagination-Current-Page,Content-Type';
//#以下省略
//}
//Allow-Headers "Accept","Accept-Encoding","Host","Origin","Referer","User-Agent",
七、定义路由
1、放行静态路径和页面模板
2、放行业务接口
package router
import (
. "mock/controller"
"mock/middleware"
"net/http"
"github.com/gin-gonic/gin"
)
/*
InitRouter 路由初始化
*/
func InitRouter() *gin.Engine {
router := gin.Default()
// 加载 templates 文件夹下所有的 tmpl
router.LoadHTMLGlob("../templates/*")
router.StaticFS("/res", http.Dir("../res"))
router.GET("/", Index)
v1 := router.Group("/api")
v1.Use(middleware.CORSMiddleware())
{
v1.Any("/GetImg", GetImg)
}
return router
}
八、main入口
1、以 8080 端口启动服务,默认为 localhost
package main
import (
"mock/router"
)
func main() {
r := router.InitRouter()
r.Run(":8080")
}
九、自动化脚本
1、先执行 go build 生成可执行文件 cmd 后,编写自动执行脚本
autoOpen: true
apps:
- port: 8080
command: go env -w GOPROXY=https://goproxy.cn,direct & cd cmd && ./cmd
root: ./
name: demo
description: demo
autoOpen: true
十、运行效果
1、重新打开页面时,脚本自动执行,自动开启前后端
十一、云IDE测评总结
1、编码流畅度:目前使用来说很流畅,偶尔会有字符输入延时,也有出现整个IDE卡死、没有提示语法的情况
2、开发环境:云端自带的开发环境能满足大部分的需求,也可以自行安装插件,我使用的是Go环境也能自动识别,这点可以节省一大部分搭建环境的时间(下载-安装-配置),提高开发效率。
3、灵活度:不局限与本地机器,只要有网络,随时随地都可以使用云IDE。