1、点击官方链接即可开始创建工作空间

2、查看已创建好的工作空间

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.")
- }
1、参考 Element 官方文档
2、页面功能:用户在输入框填写文本,选择效果(方向,字体)后,点击 Run 按钮,返回用户预期效果图片
- html>
- <html>
-
- <head>
- <meta charset="UTF-8">
- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js">script>
-
- <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">字体1el-radio>
- <el-radio v-model="font" label="font2">字体2el-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>
- <script src="https://unpkg.com/vue@2/dist/vue.js">script>
- <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
- }
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、重新打开页面时,脚本自动执行,自动开启前后端


1、编码流畅度:目前使用来说很流畅,偶尔会有字符输入延时,也有出现整个IDE卡死、没有提示语法的情况
2、开发环境:云端自带的开发环境能满足大部分的需求,也可以自行安装插件,我使用的是Go环境也能自动识别,这点可以节省一大部分搭建环境的时间(下载-安装-配置),提高开发效率。
3、灵活度:不局限与本地机器,只要有网络,随时随地都可以使用云IDE。