forked from x/ContextOS
vps add html5.md
This commit is contained in:
parent
07165a1957
commit
b64b9e0d6a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,5 @@
|
|||||||
tmp/
|
|
||||||
var/
|
var/
|
||||||
pkg/
|
pkg/
|
||||||
bin/
|
|
||||||
*.swp
|
*.swp
|
||||||
# Binaries for programs and plugins
|
# Binaries for programs and plugins
|
||||||
*.exe
|
*.exe
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
source etc/local_exit.shy
|
source etc/local_exit.shy
|
||||||
~file1
|
~file1
|
||||||
history save etc/history.txt
|
history save var/history.txt
|
||||||
~aaa
|
~aaa
|
||||||
login save etc/login.txt
|
login save var/login.txt
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
login root root
|
login root root
|
||||||
~aaa
|
~aaa
|
||||||
login load etc/login.txt
|
login load var/login.txt
|
||||||
~file1
|
~file1
|
||||||
history load etc/history.txt
|
history load var/history.txt
|
||||||
|
|
||||||
source etc/local.shy
|
source etc/local.shy
|
||||||
|
|
||||||
|
@ -2,7 +2,12 @@ package aaa // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
import ( // {{{
|
import ( // {{{
|
||||||
"contexts"
|
"contexts"
|
||||||
|
"crypto/sha1"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"net/http"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
@ -147,8 +152,38 @@ var Pulse *ctx.Message
|
|||||||
var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
||||||
Caches: map[string]*ctx.Cache{
|
Caches: map[string]*ctx.Cache{
|
||||||
"nuser": &ctx.Cache{Name: "nuser", Value: "0", Help: "用户数量"},
|
"nuser": &ctx.Cache{Name: "nuser", Value: "0", Help: "用户数量"},
|
||||||
|
|
||||||
|
"access_expire": &ctx.Cache{Name: "会话超时", Value: "0", Help: "会话超时"},
|
||||||
|
"access_token": &ctx.Cache{Name: "会话令牌", Value: "0", Help: "会话令牌", Hand: func(m *ctx.Message, x *ctx.Cache, arg ...string) string {
|
||||||
|
if len(arg) > 0 { // {{{
|
||||||
|
return arg[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Capi("access_expire") < int(time.Now().Unix()) {
|
||||||
|
var data struct {
|
||||||
|
Errcode int64
|
||||||
|
Errmsg string
|
||||||
|
Access_token string
|
||||||
|
Expires_in int64
|
||||||
|
}
|
||||||
|
res, e := http.Get(fmt.Sprintf(m.Conf("wx_api")+m.Conf("access_route"), m.Conf("appid"), m.Conf("appmm")))
|
||||||
|
m.Assert(e)
|
||||||
|
m.Assert(json.NewDecoder(res.Body).Decode(&data))
|
||||||
|
m.Cap("access_expire", fmt.Sprintf("%d", time.Now().Unix()+data.Expires_in))
|
||||||
|
x.Value = data.Access_token
|
||||||
|
m.Log("info", "access_token: %s(%s)", m.Cap("access_token"), m.Cap("access_expire"))
|
||||||
|
m.Cap("stream", m.Conf("appid"))
|
||||||
|
}
|
||||||
|
return x.Value // }}}
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{
|
||||||
|
"wx_api": &ctx.Config{Name: "微信接口", Value: "https://api.weixin.qq.com/cgi-bin/", Help: "微信登录"},
|
||||||
|
"access_route": &ctx.Config{Name: "微信登录", Value: "token?grant_type=client_credential&appid=%s&secret=%s", Help: "微信登录"},
|
||||||
|
"appid": &ctx.Config{Name: "微信帐号", Value: "", Help: "微信帐号"},
|
||||||
|
"appmm": &ctx.Config{Name: "微信密码", Value: "", Help: "微信密码"},
|
||||||
|
"token": &ctx.Config{Name: "微信令牌", Value: "", Help: "微信密码"},
|
||||||
|
|
||||||
"rootname": &ctx.Config{Name: "rootname", Value: "root", Help: "根用户名"},
|
"rootname": &ctx.Config{Name: "rootname", Value: "root", Help: "根用户名"},
|
||||||
"expire": &ctx.Config{Name: "expire(s)", Value: "7200", Help: "会话超时"},
|
"expire": &ctx.Config{Name: "expire(s)", Value: "7200", Help: "会话超时"},
|
||||||
"pub": &ctx.Config{Name: "pub", Value: "etc/pub.pem", Help: "公钥文件"},
|
"pub": &ctx.Config{Name: "pub", Value: "etc/pub.pem", Help: "公钥文件"},
|
||||||
@ -171,9 +206,24 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
if aaa, ok := c.Server.(*AAA); m.Assert(ok) { // {{{
|
if aaa, ok := c.Server.(*AAA); m.Assert(ok) { // {{{
|
||||||
stream := ""
|
stream := ""
|
||||||
|
method := ""
|
||||||
|
username := ""
|
||||||
|
m.Log("fuck", "%s %s", method, username)
|
||||||
|
if len(arg) > 0 {
|
||||||
|
switch arg[0] {
|
||||||
|
case "openid":
|
||||||
|
method = arg[0]
|
||||||
|
username = arg[1]
|
||||||
|
stream = arg[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if m.Has("ip") {
|
if m.Has("ip") {
|
||||||
stream = m.Option("ip")
|
stream = m.Option("ip")
|
||||||
}
|
}
|
||||||
|
if m.Has("openid") {
|
||||||
|
stream = m.Option("openid")
|
||||||
|
}
|
||||||
if m.Has("pub") {
|
if m.Has("pub") {
|
||||||
stream = m.Option("pub")
|
stream = m.Option("pub")
|
||||||
buf, e := ioutil.ReadFile(m.Option("pub"))
|
buf, e := ioutil.ReadFile(m.Option("pub"))
|
||||||
@ -249,7 +299,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
word := strings.SplitN(bio.Text(), ":", 3)
|
word := strings.SplitN(bio.Text(), ":", 3)
|
||||||
msg := m.Spawn()
|
msg := m.Spawn()
|
||||||
msg.Start(word[0], "用户", word[0], word[1], word[2])
|
msg.Start(word[0], "用户", word[0], word[1], word[2])
|
||||||
msg.Spawn().Cmd("config", "load", fmt.Sprintf("etc/%s.json", word[0]), "lark")
|
msg.Spawn().Cmd("config", "load", fmt.Sprintf("var/%s.json", word[0]), "lark")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "save":
|
case "save":
|
||||||
@ -257,7 +307,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
m.Travel(func(m *ctx.Message, i int) bool {
|
m.Travel(func(m *ctx.Message, i int) bool {
|
||||||
if i > 0 && m.Cap("username") != "root" {
|
if i > 0 && m.Cap("username") != "root" {
|
||||||
f.WriteString(fmt.Sprintf("%s:%s:%s\n", m.Cap("username"), m.Cap("password"), m.Cap("sessid")))
|
f.WriteString(fmt.Sprintf("%s:%s:%s\n", m.Cap("username"), m.Cap("password"), m.Cap("sessid")))
|
||||||
m.Spawn().Cmd("config", "save", fmt.Sprintf("etc/%s.json", m.Cap("username")), "lark")
|
m.Spawn().Cmd("config", "save", fmt.Sprintf("var/%s.json", m.Cap("username")), "lark")
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@ -701,6 +751,15 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心",
|
|||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
"wx": &ctx.Command{Name: "wx check signature", Help: "微信", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
list := []string{m.Option("nonce"), m.Option("timestamp"), m.Conf("token")}
|
||||||
|
sort.Strings(list)
|
||||||
|
b := sha1.Sum([]byte(strings.Join(list, "")))
|
||||||
|
|
||||||
|
if m.Option("signature") == hex.EncodeToString(b[:]) {
|
||||||
|
m.Echo("ok")
|
||||||
|
}
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3466,6 +3466,7 @@ func Start(args ...string) {
|
|||||||
Pulse.Sess("cli", "cli")
|
Pulse.Sess("cli", "cli")
|
||||||
|
|
||||||
Pulse.Sess("aaa", "aaa")
|
Pulse.Sess("aaa", "aaa")
|
||||||
|
Pulse.Sess("web", "web")
|
||||||
Pulse.Sess("log", "log")
|
Pulse.Sess("log", "log")
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
|
@ -8,6 +8,7 @@ import ( // {{{
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"encoding/xml"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -106,6 +107,8 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C
|
|||||||
hand(msg, msg.Target(), msg.Option("path"))
|
hand(msg, msg.Target(), msg.Option("path"))
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case msg.Has("directory"):
|
||||||
|
http.ServeFile(w, r, msg.Append("directory"))
|
||||||
case msg.Has("redirect"):
|
case msg.Has("redirect"):
|
||||||
http.Redirect(w, r, msg.Append("redirect"), http.StatusFound)
|
http.Redirect(w, r, msg.Append("redirect"), http.StatusFound)
|
||||||
case msg.Has("template"):
|
case msg.Has("template"):
|
||||||
@ -139,7 +142,7 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.URL.Path == "/" && m.Confs("root_index") {
|
if r.URL.Path == "/" && m.Confs("root_index") {
|
||||||
http.Redirect(w, r, "/index/", http.StatusFound)
|
http.Redirect(w, r, m.Conf("root_index"), http.StatusFound)
|
||||||
} else {
|
} else {
|
||||||
web.ServeMux.ServeHTTP(w, r)
|
web.ServeMux.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
@ -254,6 +257,7 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
yac.Cmd("train", "code", "struct", "typedef", "struct", "key", "key", ";")
|
yac.Cmd("train", "code", "struct", "typedef", "struct", "key", "key", ";")
|
||||||
yac.Cmd("train", "code", "function", "key", "\\*", "key", "(", "other")
|
yac.Cmd("train", "code", "function", "key", "\\*", "key", "(", "other")
|
||||||
yac.Cmd("train", "code", "function", "key", "key", "(", "other")
|
yac.Cmd("train", "code", "function", "key", "key", "(", "other")
|
||||||
|
yac.Cmd("train", "code", "variable", "struct", "key", "key", "other")
|
||||||
yac.Cmd("train", "code", "define", "#define", "key", "other")
|
yac.Cmd("train", "code", "define", "#define", "key", "other")
|
||||||
|
|
||||||
if m.Cap("protocol") == "https" {
|
if m.Cap("protocol") == "https" {
|
||||||
@ -291,16 +295,19 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
"cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "路由数量"},
|
"cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "路由数量"},
|
||||||
"key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "路由数量"},
|
"key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "路由数量"},
|
||||||
"wiki_dir": &ctx.Config{Name: "wiki_dir", Value: "usr/wiki", Help: "路由数量"},
|
"wiki_dir": &ctx.Config{Name: "wiki_dir", Value: "usr/wiki", Help: "路由数量"},
|
||||||
|
"wiki_list_show": &ctx.Config{Name: "wiki_list_show", Value: map[string]interface{}{
|
||||||
|
"md": true,
|
||||||
|
}, Help: "路由数量"},
|
||||||
"which": &ctx.Config{Name: "which", Value: "redis.note", Help: "路由数量"},
|
"which": &ctx.Config{Name: "which", Value: "redis.note", Help: "路由数量"},
|
||||||
"root_index": &ctx.Config{Name: "root_index(true/false)", Value: "true", Help: "路由数量"},
|
"root_index": &ctx.Config{Name: "root_index", Value: "/wiki/", Help: "路由数量"},
|
||||||
"auto_create": &ctx.Config{Name: "auto_create(true/false)", Value: "true", Help: "路由数量"},
|
"auto_create": &ctx.Config{Name: "auto_create(true/false)", Value: "true", Help: "路由数量"},
|
||||||
"refresh_time": &ctx.Config{Name: "refresh_time(ms)", Value: "1000", Help: "路由数量"},
|
"refresh_time": &ctx.Config{Name: "refresh_time(ms)", Value: "1000", Help: "路由数量"},
|
||||||
"define": &ctx.Config{Name: "define", Value: map[string]interface{}{
|
"define": &ctx.Config{Name: "define", Value: map[string]interface{}{
|
||||||
"ngx_command_t": map[string]interface{}{
|
"ngx_command_t": map[string]interface{}{
|
||||||
"position": map[string]interface{}{
|
"position": []interface{}{map[string]interface{}{
|
||||||
"file": "nginx-1.15.2/src/core/ngx_core.h",
|
"file": "nginx-1.15.2/src/core/ngx_core.h",
|
||||||
"line": "22",
|
"line": "22",
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
"ngx_command_s": map[string]interface{}{
|
"ngx_command_s": map[string]interface{}{
|
||||||
"position": map[string]interface{}{
|
"position": map[string]interface{}{
|
||||||
@ -562,6 +569,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
|
if m.Option("type") == "json" {
|
||||||
|
contenttype = "application/json"
|
||||||
|
body = file
|
||||||
|
break
|
||||||
|
}
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
writer := multipart.NewWriter(buf)
|
writer := multipart.NewWriter(buf)
|
||||||
|
|
||||||
@ -1193,7 +1205,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
case "pyc", "o", "gz", "tar":
|
case "pyc", "o", "gz", "tar":
|
||||||
continue
|
continue
|
||||||
case "c":
|
case "c":
|
||||||
m.Log("fuck", "parse %s", name)
|
|
||||||
case "h":
|
case "h":
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
@ -1202,8 +1213,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
f, e := os.Open(name)
|
f, e := os.Open(name)
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
m.Log("fuck", "%d/%d %s", i, len(msg.Meta["filename"]), v)
|
||||||
m.Log("fuck", "parse %d/%d %s", i, len(msg.Meta["filename"]), name)
|
|
||||||
|
|
||||||
bio := bufio.NewScanner(f)
|
bio := bufio.NewScanner(f)
|
||||||
for line := 1; bio.Scan(); line++ {
|
for line := 1; bio.Scan(); line++ {
|
||||||
@ -1228,11 +1238,16 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
default:
|
default:
|
||||||
key = l.Result(3)
|
key = l.Result(3)
|
||||||
}
|
}
|
||||||
|
case "variable":
|
||||||
|
switch l.Result(2) {
|
||||||
|
case "struct":
|
||||||
|
key = l.Result(4)
|
||||||
|
}
|
||||||
case "define":
|
case "define":
|
||||||
key = l.Result(3)
|
key = l.Result(3)
|
||||||
}
|
}
|
||||||
if key != "" {
|
if key != "" {
|
||||||
m.Confv("define", strings.Join([]string{key, "position"}, "."), map[string]interface{}{
|
m.Confv("define", strings.Join([]string{key, "position", "-2"}, "."), map[string]interface{}{
|
||||||
"file": strings.TrimPrefix(name, m.Confx("wiki_dir")),
|
"file": strings.TrimPrefix(name, m.Confx("wiki_dir")),
|
||||||
"line": line,
|
"line": line,
|
||||||
"type": l.Result(1),
|
"type": l.Result(1),
|
||||||
@ -1271,10 +1286,11 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
|
|
||||||
if m.Options("query") {
|
if m.Options("query") {
|
||||||
if v, ok := m.Confv("define", m.Option("query")).(map[string]interface{}); ok {
|
if v, ok := m.Confv("define", m.Option("query")).(map[string]interface{}); ok {
|
||||||
if val, ok := v["position"].(map[string]interface{}); ok {
|
for _, val := range v["position"].([]interface{}) {
|
||||||
m.Add("append", "name", fmt.Sprintf("%v#hash_%v", val["file"], val["line"]))
|
value := val.(map[string]interface{})
|
||||||
return
|
m.Add("append", "name", fmt.Sprintf("%v#hash_%v", value["file"], value["line"]))
|
||||||
}
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), m.Option("dir")), "dir_name", "path")
|
msg := m.Sess("nfs").Cmd("dir", path.Join(m.Conf("wiki_dir"), m.Option("dir")), "dir_name", "path")
|
||||||
for _, v := range msg.Meta["filename"] {
|
for _, v := range msg.Meta["filename"] {
|
||||||
@ -1309,21 +1325,155 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
|||||||
if l.Name()[0] == '.' {
|
if l.Name()[0] == '.' {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if !l.IsDir() {
|
||||||
es := strings.Split(l.Name(), ".")
|
es := strings.Split(l.Name(), ".")
|
||||||
if len(es) > 0 {
|
if len(es) > 0 {
|
||||||
switch es[len(es)-1] {
|
if show, ok := m.Confv("wiki_list_show", es[len(es)-1]).(bool); !ok || !show {
|
||||||
case "pyc", "o", "gz", "tar":
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m.Add("append", "name", l.Name())
|
m.Add("append", "name", l.Name())
|
||||||
|
m.Add("append", "time", l.ModTime().Format("2006-01-02 15:04:05"))
|
||||||
|
if l.IsDir() {
|
||||||
|
m.Add("append", "pend", "/")
|
||||||
|
} else {
|
||||||
|
m.Add("append", "pend", "")
|
||||||
|
}
|
||||||
|
m.Option("time_layout", "2006-01-02 15:04:05")
|
||||||
|
m.Sort("time", "time_r")
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
"/wiki/": &ctx.Command{Name: "/wiki", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
"/wiki/": &ctx.Command{Name: "/wiki", Help: "维基", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
m.Option("which", strings.TrimPrefix(key, "/wiki/"))
|
m.Option("which", strings.TrimPrefix(key, "/wiki/"))
|
||||||
|
if f, e := os.Stat(path.Join(m.Conf("wiki_dir"), m.Option("which"))); e == nil && !f.IsDir() && (strings.HasSuffix(m.Option("which"), ".json") || strings.HasSuffix(m.Option("which"), ".js") || strings.HasSuffix(m.Option("which"), ".css")) {
|
||||||
|
m.Append("directory", path.Join(m.Conf("wiki_dir"), m.Option("which")))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
m.Append("template", "wiki")
|
m.Append("template", "wiki")
|
||||||
}},
|
}},
|
||||||
|
"/wx/": &ctx.Command{Name: "/wx/", Help: "微信", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
if !m.Sess("aaa").Cmd("wx").Results(0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if m.Has("echostr") {
|
||||||
|
m.Echo(m.Option("echostr"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r := m.Optionv("request").(*http.Request)
|
||||||
|
|
||||||
|
switch r.Header.Get("Content-Type") {
|
||||||
|
case "text/xml":
|
||||||
|
type Article struct {
|
||||||
|
XMLName xml.Name `xml:"item"`
|
||||||
|
PicUrl string
|
||||||
|
Title string
|
||||||
|
Description string
|
||||||
|
Url string
|
||||||
|
}
|
||||||
|
type WXMsg struct {
|
||||||
|
XMLName xml.Name `xml:"xml"`
|
||||||
|
ToUserName string
|
||||||
|
FromUserName string
|
||||||
|
CreateTime int32
|
||||||
|
MsgId int64
|
||||||
|
MsgType string
|
||||||
|
|
||||||
|
Event string
|
||||||
|
EventKey string
|
||||||
|
|
||||||
|
Content string
|
||||||
|
|
||||||
|
Format string
|
||||||
|
Recognition string
|
||||||
|
|
||||||
|
PicUrl string
|
||||||
|
MediaId string
|
||||||
|
|
||||||
|
Location_X float64
|
||||||
|
Location_Y float64
|
||||||
|
Scale int64
|
||||||
|
Label string
|
||||||
|
|
||||||
|
ArticleCount int
|
||||||
|
Articles struct {
|
||||||
|
XMLName xml.Name `xml:"Articles"`
|
||||||
|
Articles []*Article
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var data WXMsg
|
||||||
|
|
||||||
|
b, e := ioutil.ReadAll(r.Body)
|
||||||
|
m.Log("fuck", "b: %v", string(b))
|
||||||
|
e = xml.Unmarshal(b, &data)
|
||||||
|
m.Log("fuck", "b: %#v", data)
|
||||||
|
|
||||||
|
// de := xml.NewDecoder(r.Body)
|
||||||
|
// e := de.Decode(&data)
|
||||||
|
m.Assert(e)
|
||||||
|
|
||||||
|
var echo WXMsg
|
||||||
|
echo.FromUserName = data.ToUserName
|
||||||
|
echo.ToUserName = data.FromUserName
|
||||||
|
echo.CreateTime = data.CreateTime
|
||||||
|
|
||||||
|
fs, e := ioutil.ReadDir("usr/wiki")
|
||||||
|
m.Assert(e)
|
||||||
|
msg := m.Spawn()
|
||||||
|
for _, f := range fs {
|
||||||
|
if !strings.HasSuffix(f.Name(), ".md") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
msg.Add("append", "name", f.Name())
|
||||||
|
msg.Add("append", "title", strings.TrimSuffix(f.Name(), ".md")+"源码解析")
|
||||||
|
msg.Add("append", "time", f.ModTime().Format("01/02 15:03"))
|
||||||
|
}
|
||||||
|
msg.Option("time_layout", "01/02 15:03")
|
||||||
|
msg.Sort("time", "time_r")
|
||||||
|
|
||||||
|
articles := []*Article{}
|
||||||
|
articles = append(articles, &Article{PicUrl: "http://mmbiz.qpic.cn/mmbiz_jpg/sCJZHmp0V0doWEFBe6gS2HjgB0abiaK7H5WjkXGTvAI0CkCFrVJDEBBbJX8Kz0VegZ54ZoCo4We0sKJUOTuf1Tw/0",
|
||||||
|
Title: "wiki首页", Description: "技术文章", Url: "https://shylinux.com/wiki/"})
|
||||||
|
for i, v := range msg.Meta["title"] {
|
||||||
|
if i > 6 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
articles = append(articles, &Article{PicUrl: "http://mmbiz.qpic.cn/mmbiz_jpg/sCJZHmp0V0doWEFBe6gS2HjgB0abiaK7H5WjkXGTvAI0CkCFrVJDEBBbJX8Kz0VegZ54ZoCo4We0sKJUOTuf1Tw/0",
|
||||||
|
Title: msg.Meta["time"][i] + " " + v, Description: "技术文章", Url: "https://shylinux.com/wiki/" + msg.Meta["name"][i]})
|
||||||
|
}
|
||||||
|
|
||||||
|
switch data.MsgType {
|
||||||
|
case "event":
|
||||||
|
echo.MsgType = "news"
|
||||||
|
echo.Articles.Articles = articles
|
||||||
|
echo.ArticleCount = len(echo.Articles.Articles)
|
||||||
|
case "text":
|
||||||
|
echo.MsgType = "news"
|
||||||
|
echo.Articles.Articles = articles
|
||||||
|
echo.ArticleCount = len(echo.Articles.Articles)
|
||||||
|
case "voice":
|
||||||
|
echo.MsgType = "text"
|
||||||
|
echo.Content = "你好"
|
||||||
|
case "image":
|
||||||
|
echo.MsgType = "text"
|
||||||
|
echo.Content = "你好"
|
||||||
|
case "location":
|
||||||
|
echo.MsgType = "text"
|
||||||
|
echo.Content = "你好"
|
||||||
|
}
|
||||||
|
|
||||||
|
b, e = xml.Marshal(echo)
|
||||||
|
m.Echo(string(b))
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
"user": &ctx.Command{Name: "user", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
|
aaa := m.Sess("aaa")
|
||||||
|
m.Spawn().Cmd("get", fmt.Sprintf("%suser/get", aaa.Conf("wx_api")), "access_token", aaa.Cap("access_token"))
|
||||||
|
}},
|
||||||
"temp": &ctx.Command{Name: "temp", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
"temp": &ctx.Command{Name: "temp", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) {
|
||||||
msg := m.Spawn(m.Target())
|
msg := m.Spawn(m.Target())
|
||||||
question := []string{}
|
question := []string{}
|
||||||
|
@ -41,6 +41,52 @@ ctx = {
|
|||||||
}
|
}
|
||||||
location.search = arg.join("&");
|
location.search = arg.join("&");
|
||||||
},//}}}
|
},//}}}
|
||||||
|
GET: function(url, form, cb) {//{{{
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
switch (xhr.readyState) {
|
||||||
|
case 4:
|
||||||
|
switch (xhr.status) {
|
||||||
|
case 200:
|
||||||
|
try {
|
||||||
|
var msg = JSON.parse(xhr.responseText||'{"result":[]}');
|
||||||
|
} catch (e) {
|
||||||
|
msg = {"result": [xhr.responseText]}
|
||||||
|
}
|
||||||
|
|
||||||
|
msg && console.log(msg)
|
||||||
|
msg.result && console.log(msg.result.join(""));
|
||||||
|
typeof cb == "function" && cb(msg)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form = form || {}
|
||||||
|
form["dir"] = form["dir"] || this.Search("dir") || undefined
|
||||||
|
form["module"] = form["module"] || this.Search("module") || undefined
|
||||||
|
form["domain"] = form["domain"] || this.Search("domain") || undefined
|
||||||
|
|
||||||
|
var args = [];
|
||||||
|
for (k in form) {
|
||||||
|
if (form[k] instanceof Array) {
|
||||||
|
for (i in form[k]) {
|
||||||
|
args.push(k+"="+encodeURIComponent(form[k][i]));
|
||||||
|
}
|
||||||
|
} else if (form[k] != undefined) {
|
||||||
|
args.push(k+"="+encodeURIComponent(form[k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var arg = args.join("&");
|
||||||
|
if (arg) {
|
||||||
|
url += "?"+arg
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.open("GET", url);
|
||||||
|
console.log("GET: "+url+"?"+arg);
|
||||||
|
xhr.send();
|
||||||
|
},//}}}
|
||||||
POST: function(url, form, cb) {//{{{
|
POST: function(url, form, cb) {//{{{
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{{define "head"}}
|
{{define "head"}}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{{option .Meta "page_title"}}</title>
|
<title>{{option .Meta "page_title"}}</title>
|
||||||
<style>
|
<style>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
overflow:scroll;
|
overflow:scroll;
|
||||||
}
|
}
|
||||||
code {
|
code {
|
||||||
font-size:14px;
|
font-size:13px;
|
||||||
}
|
}
|
||||||
.command {
|
.command {
|
||||||
font-size:14px;
|
font-size:14px;
|
||||||
|
@ -14,6 +14,9 @@ function jumpto(url) {
|
|||||||
}
|
}
|
||||||
function keyup(event) {
|
function keyup(event) {
|
||||||
console.log(event);
|
console.log(event);
|
||||||
|
if (typeof window.control == "function") {
|
||||||
|
control(event);
|
||||||
|
}
|
||||||
if (event.key == "z") {
|
if (event.key == "z") {
|
||||||
var input = document.getElementsByClassName("query_input")[0];
|
var input = document.getElementsByClassName("query_input")[0];
|
||||||
if (!window.query_show) {
|
if (!window.query_show) {
|
||||||
@ -156,18 +159,27 @@ function query(event) {
|
|||||||
input.style.width = "0px";
|
input.style.width = "0px";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var tags_list = {
|
var tags_list = {};
|
||||||
{{range $key, $val := conf . "define"}}
|
ctx.GET("/wiki/define.json", undefined, function(msg){
|
||||||
"{{$key}}": true,
|
tags_list = msg["define"];
|
||||||
{{end}}
|
})
|
||||||
};
|
|
||||||
function tags(event) {
|
function tags(event) {
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
|
if (event.srcElement.tagName == "CODE") {
|
||||||
var tag = document.getSelection().toString();
|
var tag = document.getSelection().toString();
|
||||||
console.log(tag);
|
console.log(tag);
|
||||||
if (tag && tag.length > 0 && tags_list[tag]) {
|
if (tag && tag.length > 0 && tags_list[tag]) {
|
||||||
|
var position = tags_list[tag].position;
|
||||||
|
if (position.length == 1) {
|
||||||
|
jumpto("/wiki"+position[0].file+"#hash_"+position[0].line);
|
||||||
|
} else {
|
||||||
jumpto("/wiki/?query="+encodeURIComponent(tag));
|
jumpto("/wiki/?query="+encodeURIComponent(tag));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
document.onmouseup = tags;
|
||||||
toggle();
|
toggle();
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
@ -192,36 +204,51 @@ toggle();
|
|||||||
font-size:18px;
|
font-size:18px;
|
||||||
}
|
}
|
||||||
.number {
|
.number {
|
||||||
font-size:12px;
|
|
||||||
float:left;
|
float:left;
|
||||||
position:relative;
|
position:relative;
|
||||||
left:-6px;
|
left:-6px;
|
||||||
top:22px;
|
top:18px;
|
||||||
text-align:right;
|
text-align:right;
|
||||||
}
|
}
|
||||||
|
.number div {
|
||||||
|
margin:0px;
|
||||||
|
padding:0px;
|
||||||
|
height:16px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="toggle" title="点击,显示或隐藏目录" onclick="toggle()"></div>
|
<div class="toggle" title="点击,显示或隐藏目录" onclick="toggle()"></div>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<div class="number">
|
<div class="number">
|
||||||
{{range option . "nline"|meta|list}}
|
{{range option . "nline"|meta|list}}
|
||||||
<div id="hash_{{.}}"><code>{{.}}</code></div>
|
<div id="hash_{{.}}" style="margin-top:-1px"><code>{{.}}</code></div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{$msg := .}}
|
{{$msg := .}}
|
||||||
{{if append . "name"}}
|
{{if append . "name"}}
|
||||||
|
{{$l := append . "name"|len}}
|
||||||
|
{{if eq $l 1}}
|
||||||
|
<script>
|
||||||
|
location.replace("/wiki/{{option $msg "dir"|meta|unscaped}}/{{append . "name"|meta|unscaped}}");
|
||||||
|
</script>
|
||||||
|
{{else}}
|
||||||
<ul>
|
<ul>
|
||||||
{{range append . "name"}}
|
{{range $i, $v := append . "name"}}
|
||||||
<li class="link">
|
<li class="link">
|
||||||
<div><a href="/wiki/{{option $msg "dir"|meta}}/{{.}}">{{.}}</a></div>
|
<div>
|
||||||
|
<code>{{option $msg "time" $i}} </code>
|
||||||
|
<a href="/wiki/{{option $msg "dir"|meta}}/{{$v}}{{option $msg "pend" $i}}">{{$v}}{{option $msg "pend" $i}}</a>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
<ul>
|
<ul>
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<p>{{append . "body"|meta|unscaped}}</p>
|
<p>{{append . "body"|meta|unscaped}}</p>
|
||||||
<p><pre><code onmouseup="return tags(event)">{{append . "code"|meta}}</code></pre><p>
|
<p><pre><code>{{append . "code"|meta}}</code></pre><p>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
8
usr/wiki/html5.css
Normal file
8
usr/wiki/html5.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
canvas {
|
||||||
|
border: solid 1px green;
|
||||||
|
}
|
||||||
|
.demo {
|
||||||
|
float:left;
|
||||||
|
margin-right:10px;
|
||||||
|
border: solid 1px green;
|
||||||
|
}
|
519
usr/wiki/html5.js
Normal file
519
usr/wiki/html5.js
Normal file
@ -0,0 +1,519 @@
|
|||||||
|
var canvas = document.getElementById("heart");
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
var main_angle = 30;
|
||||||
|
function refreshHeart() {
|
||||||
|
ctx.clearRect(0,0,400,400)
|
||||||
|
drawHeart(ctx,200,200,60,main_angle);
|
||||||
|
main_angle += 10;
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
var x = Math.random() * 400;
|
||||||
|
var y = Math.random() * 400;
|
||||||
|
var scale = Math.random() * 20+10;
|
||||||
|
var angle = Math.random() * 360;
|
||||||
|
drawHeart(ctx,x,y,scale,angle);
|
||||||
|
}
|
||||||
|
setTimeout(refreshHeart, 200);
|
||||||
|
}
|
||||||
|
setTimeout(refreshHeart, 200);
|
||||||
|
|
||||||
|
function drawHeart(ctx,x,y,scale,angle, style, stroke) {//{{{
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(x,y);
|
||||||
|
ctx.rotate(angle/180*Math.PI);
|
||||||
|
ctx.scale(scale, scale);
|
||||||
|
heartPath(ctx);
|
||||||
|
ctx.shadowColor = "gray";
|
||||||
|
ctx.shadowOffsetX = 5;
|
||||||
|
ctx.shadowOffsetY = 5;
|
||||||
|
ctx.shadowBlur = 5;
|
||||||
|
if (stroke == "stroke") {
|
||||||
|
ctx.strokeStyle = style||"red";
|
||||||
|
ctx.stroke();
|
||||||
|
} else {
|
||||||
|
ctx.fillStyle = style||"red";
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function heartPath(ctx) {//{{{
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(-1,0,1,Math.PI,0,false);
|
||||||
|
ctx.arc(1,0,1,Math.PI,0,false);
|
||||||
|
ctx.bezierCurveTo(1.9, 1.2, 0.6, 1.6, 0, 3.0);
|
||||||
|
ctx.bezierCurveTo( -0.6, 1.6,-1.9, 1.2,-2,0);
|
||||||
|
ctx.closePath();
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
var ctx0 = document.getElementById("demo0").getContext("2d");
|
||||||
|
ctx0.fillStyle = "green";
|
||||||
|
ctx0.fillRect(10,10,100,100);
|
||||||
|
|
||||||
|
var ctx2 = document.getElementById("demo2").getContext("2d");
|
||||||
|
ctx2.beginPath();
|
||||||
|
ctx2.moveTo(60,10);
|
||||||
|
ctx2.lineTo(10,110);
|
||||||
|
ctx2.lineTo(110,110);
|
||||||
|
ctx2.fill();
|
||||||
|
|
||||||
|
|
||||||
|
function draw3() {
|
||||||
|
for (var i = 0; i < 120; i+=20) {
|
||||||
|
for (var j = 0; j < 120; j+=20) {
|
||||||
|
r = Math.random()*255;
|
||||||
|
g = Math.random()*255;
|
||||||
|
b = Math.random()*255;
|
||||||
|
ctx3.fillStyle = "rgb("+r+","+g+","+b+")";
|
||||||
|
ctx3.fillRect(i, j, 20, 20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var demo3 = document.getElementById("demo3");
|
||||||
|
var ctx3 = demo3.getContext("2d");
|
||||||
|
demo3.onclick = draw3;
|
||||||
|
draw3()
|
||||||
|
|
||||||
|
var select_pan = document.getElementById("select_pan");
|
||||||
|
var his = document.getElementById("draw_history");
|
||||||
|
var show = document.getElementById("show");
|
||||||
|
var item = document.getElementById("draw");
|
||||||
|
var draw = item.getContext("2d");
|
||||||
|
|
||||||
|
var control_map = {//{{{
|
||||||
|
s: "stroke",
|
||||||
|
f: "fill",
|
||||||
|
|
||||||
|
e: "heart",
|
||||||
|
c: "cycle",
|
||||||
|
r: "rect",
|
||||||
|
v: "line",
|
||||||
|
t: "text",
|
||||||
|
|
||||||
|
d: "delete",
|
||||||
|
|
||||||
|
b: "big",
|
||||||
|
m: "small",
|
||||||
|
a: "play",
|
||||||
|
|
||||||
|
Escape: "escape",
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function control(event) {//{{{
|
||||||
|
if (event.type == "keyup") {
|
||||||
|
action(event, control_map[event.key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
var current_ctx = {//{{{
|
||||||
|
hide: 0,
|
||||||
|
scale: 1,
|
||||||
|
index_point: false,
|
||||||
|
shape: 'cycle',
|
||||||
|
stroke: 'stroke',
|
||||||
|
color: 'red',
|
||||||
|
font: '32px sans-serif',
|
||||||
|
big_scale: 1.25,
|
||||||
|
small_scale: 0.8,
|
||||||
|
begin_point: null,
|
||||||
|
end_point: null,
|
||||||
|
list: {
|
||||||
|
style: ["red", "green", "yellow", "blue"],
|
||||||
|
stroke: ["fill", "stroke"],
|
||||||
|
shape: ["heart", "cycle", "rect", "line"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function display(which, group) {//{{{
|
||||||
|
var cs = document.getElementsByClassName(group);
|
||||||
|
for (var i = 0; i < cs.length; i++) {
|
||||||
|
cs[i].style.backgroundColor = "white";
|
||||||
|
}
|
||||||
|
|
||||||
|
var cs = document.getElementsByClassName(group+" "+which);
|
||||||
|
for (var i = 0; i < cs.length; i++) {
|
||||||
|
cs[i].style.backgroundColor = "lightblue";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function action(event, s) {//{{{
|
||||||
|
console.log(event);
|
||||||
|
switch (s) {
|
||||||
|
case "escape":
|
||||||
|
current_ctx.begin_point = null;
|
||||||
|
current_ctx.end_point = null;
|
||||||
|
refresh();
|
||||||
|
break
|
||||||
|
case "big":
|
||||||
|
current_ctx.scale *= current_ctx.big_scale;
|
||||||
|
draw.scale(current_ctx.big_scale, current_ctx.big_scale);
|
||||||
|
refresh();
|
||||||
|
break
|
||||||
|
case "small":
|
||||||
|
current_ctx.scale *= current_ctx.small_scale;
|
||||||
|
draw.scale(current_ctx.small_scale, current_ctx.small_scale);
|
||||||
|
refresh();
|
||||||
|
break
|
||||||
|
case "clear":
|
||||||
|
if (confirm("clear all?")) {
|
||||||
|
action(event, "clear");
|
||||||
|
his.innerHTML = "";
|
||||||
|
draw_history = [];
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case "hide":
|
||||||
|
current_ctx.hide = draw_history.length;
|
||||||
|
refresh();
|
||||||
|
break
|
||||||
|
case "delete":
|
||||||
|
draw_history.pop();
|
||||||
|
refresh();
|
||||||
|
break
|
||||||
|
case "draw":
|
||||||
|
current_ctx.hide = 0;
|
||||||
|
refresh();
|
||||||
|
break
|
||||||
|
|
||||||
|
case "fill":
|
||||||
|
current_ctx.stroke = "fill";
|
||||||
|
select_pan.selectedIndex=1;
|
||||||
|
break
|
||||||
|
case "stroke":
|
||||||
|
current_ctx.stroke = "stroke";
|
||||||
|
select_pan.selectedIndex=0;
|
||||||
|
break
|
||||||
|
|
||||||
|
case "heart":
|
||||||
|
current_ctx.shape = s;
|
||||||
|
current_ctx.stroke = "fill";
|
||||||
|
display("e", "control");
|
||||||
|
select_pan.selectedIndex=1;
|
||||||
|
break
|
||||||
|
case "cycle":
|
||||||
|
current_ctx.shape = s;
|
||||||
|
display("c", "control");
|
||||||
|
break
|
||||||
|
case "rect":
|
||||||
|
current_ctx.shape = s;
|
||||||
|
display("r", "control");
|
||||||
|
break
|
||||||
|
case "line":
|
||||||
|
current_ctx.shape = s;
|
||||||
|
current_ctx.stroke = "stroke";
|
||||||
|
select_pan.selectedIndex=0;
|
||||||
|
display("v", "control");
|
||||||
|
break
|
||||||
|
case "text":
|
||||||
|
current_ctx.shape = s;
|
||||||
|
current_ctx.stroke = "fill";
|
||||||
|
select_pan.selectedIndex=0;
|
||||||
|
display("t", "control");
|
||||||
|
break
|
||||||
|
|
||||||
|
case "play":
|
||||||
|
current_ctx.hide = 0;
|
||||||
|
refresh(500, 0);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function select(event, config, val) {//{{{
|
||||||
|
var target = event.target;
|
||||||
|
var value = target[target.selectedIndex].value;
|
||||||
|
switch (config) {
|
||||||
|
case "color":
|
||||||
|
current_ctx.color = value;
|
||||||
|
break
|
||||||
|
case "stroke":
|
||||||
|
current_ctx.stroke = value;
|
||||||
|
break
|
||||||
|
case "shape":
|
||||||
|
display("r", "control");
|
||||||
|
switch (value) {
|
||||||
|
case "heart":
|
||||||
|
current_ctx.stroke = "fill";
|
||||||
|
display("h", "control");
|
||||||
|
break
|
||||||
|
case "cycle":
|
||||||
|
display("c", "control");
|
||||||
|
break
|
||||||
|
case "rect":
|
||||||
|
display("r", "control");
|
||||||
|
break
|
||||||
|
case "line":
|
||||||
|
current_ctx.stroke = "stroke";
|
||||||
|
display("v", "control");
|
||||||
|
break
|
||||||
|
}
|
||||||
|
current_ctx.shape = value;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
var draw_history = [];
|
||||||
|
function modify(event, row, col) {//{{{
|
||||||
|
if (event.key != "Enter") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log("modify");
|
||||||
|
console.log(event);
|
||||||
|
console.log();
|
||||||
|
var data = event.target.dataset;
|
||||||
|
var row = draw_history[data.row];
|
||||||
|
var value = event.target.value;
|
||||||
|
switch (data.col) {
|
||||||
|
case "x1":
|
||||||
|
row.begin_point.x = value;
|
||||||
|
break
|
||||||
|
case "y1":
|
||||||
|
row.begin_point.y = value;
|
||||||
|
break
|
||||||
|
case "x2":
|
||||||
|
row.end_point.x = value;
|
||||||
|
break
|
||||||
|
case "y2":
|
||||||
|
row.end_point.y = value;
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
row[data.col] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function refresh(time, i) {//{{{
|
||||||
|
if (time) {
|
||||||
|
if (0 == i) {
|
||||||
|
draw.clearRect(0, 0,400/current_ctx.scale, 400/current_ctx.scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_ctx.hide <= i && i < draw_history.length) {
|
||||||
|
var h = draw_history[i];
|
||||||
|
draws(draw, h.style, h.stroke, h.shape, h.begin_point, h.end_point);
|
||||||
|
i++;
|
||||||
|
setTimeout(function(){
|
||||||
|
refresh(time, i);
|
||||||
|
}, time);
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.clearRect(0, 0,400/current_ctx.scale, 400/current_ctx.scale);
|
||||||
|
|
||||||
|
for (var i in draw_history) {
|
||||||
|
if (i <current_ctx.hide) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var h = draw_history[i];
|
||||||
|
draws(draw, h.style, h.stroke, h.shape, h.begin_point, h.end_point, h.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function draws(draw, style, stroke, shape, begin_point, end_point, text) {//{{{
|
||||||
|
draw.save();
|
||||||
|
begin_x = begin_point.x;
|
||||||
|
begin_y = begin_point.y;
|
||||||
|
end_x = end_point.x;
|
||||||
|
end_y = end_point.y;
|
||||||
|
|
||||||
|
if (current_ctx.index_point) {
|
||||||
|
draw.beginPath();
|
||||||
|
draw.arc(begin_x, begin_y, 5, 0, 2*Math.PI)
|
||||||
|
draw.fill()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_ctx.index_point) {
|
||||||
|
draw.beginPath();
|
||||||
|
draw.arc(end_x, end_y, 5, 0, 2*Math.PI)
|
||||||
|
draw.fill()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (shape) {
|
||||||
|
case 'heart':
|
||||||
|
r = Math.sqrt(Math.pow(begin_x-end_x, 2)+Math.pow(begin_y-end_y,2));
|
||||||
|
a = Math.atan((end_y-begin_y)/(end_x-begin_x))/Math.PI*180;
|
||||||
|
drawHeart(draw, begin_x, begin_y, r, a, style, stroke)
|
||||||
|
break
|
||||||
|
case 'cycle':
|
||||||
|
draw.beginPath();
|
||||||
|
r = Math.sqrt(Math.pow(begin_x-end_x, 2)+Math.pow(begin_y-end_y,2));
|
||||||
|
draw.arc(begin_x, begin_y, r, 0, 2*Math.PI)
|
||||||
|
if (stroke == "stroke") {
|
||||||
|
if (style) {
|
||||||
|
draw.strokeStyle = style;
|
||||||
|
}
|
||||||
|
draw.stroke()
|
||||||
|
} else {
|
||||||
|
if (style) {
|
||||||
|
draw.fillStyle = style;
|
||||||
|
}
|
||||||
|
draw.fill()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'line':
|
||||||
|
draw.beginPath();
|
||||||
|
draw.moveTo(begin_x, begin_y);
|
||||||
|
draw.lineTo(end_x, end_y);
|
||||||
|
if (stroke == "stroke") {
|
||||||
|
if (style) {
|
||||||
|
draw.strokeStyle = style;
|
||||||
|
}
|
||||||
|
draw.stroke()
|
||||||
|
} else {
|
||||||
|
if (style) {
|
||||||
|
draw.fillStyle = style;
|
||||||
|
}
|
||||||
|
draw.fill()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'rect':
|
||||||
|
if (stroke == "stroke") {
|
||||||
|
if (style) {
|
||||||
|
draw.strokeStyle = style;
|
||||||
|
}
|
||||||
|
draw.strokeRect(begin_x, begin_y, end_x-begin_x, end_y-begin_y);
|
||||||
|
} else {
|
||||||
|
if (style) {
|
||||||
|
draw.fillStyle = style;
|
||||||
|
}
|
||||||
|
draw.fillRect(begin_x, begin_y, end_x-begin_x, end_y-begin_y);
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'text':
|
||||||
|
if (stroke == "stroke") {
|
||||||
|
if (style) {
|
||||||
|
draw.strokeStyle = style;
|
||||||
|
}
|
||||||
|
draw.font = current_ctx.font;
|
||||||
|
draw.strokeText(text, begin_x, begin_y, end_x-begin_x);
|
||||||
|
} else {
|
||||||
|
if (style) {
|
||||||
|
draw.fillStyle = style;
|
||||||
|
}
|
||||||
|
draw.font = current_ctx.font;
|
||||||
|
draw.fillText(text, begin_x, begin_y, end_x-begin_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw.restore();
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function show_debug(log, clear) {//{{{
|
||||||
|
var fuck = document.getElementById("fuck");
|
||||||
|
if (clear) {
|
||||||
|
fuck.innerHTML = "";
|
||||||
|
}
|
||||||
|
var div = fuck.appendChild(document.createElement("div"));
|
||||||
|
div.appendChild(document.createTextNode(log));
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
|
||||||
|
function trans(point) {//{{{
|
||||||
|
point.x /= current_ctx.scale;
|
||||||
|
point.y /= current_ctx.scale;
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function draw_point(event) {//{{{
|
||||||
|
console.log("point");
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
|
var point = trans({x:event.offsetX, y:event.offsetY});
|
||||||
|
|
||||||
|
if (current_ctx.index_point) {
|
||||||
|
draw.beginPath();
|
||||||
|
draw.arc(point.x, point.y, 5, 0, 2*Math.PI);
|
||||||
|
draw.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!current_ctx.begin_point) {
|
||||||
|
current_ctx.begin_point = point;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
current_ctx.end_point = point;
|
||||||
|
console.log(current_ctx.end_point);
|
||||||
|
var text = "";
|
||||||
|
if (current_ctx.shape == "text") {
|
||||||
|
text = prompt("请入文字", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
draws(draw, current_ctx.color, current_ctx.stroke, current_ctx.shape, current_ctx.begin_point, current_ctx.end_point, text);
|
||||||
|
draw_history.push({style:current_ctx.color, stroke:current_ctx.stroke, shape:current_ctx.shape, begin_point:current_ctx.begin_point, end_point:current_ctx.end_point, text:text})
|
||||||
|
|
||||||
|
var headers = ["style", "stroke", "shape", "x1", "y1", "x2", "y2", "text"]
|
||||||
|
if (his.rows.length == 0) {
|
||||||
|
var tr = his.insertRow(-1);
|
||||||
|
for (var i in headers) {
|
||||||
|
var th = tr.appendChild(document.createElement("th"));
|
||||||
|
th.appendChild(document.createTextNode(headers[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var tr = his.insertRow(-1);
|
||||||
|
var fields = [current_ctx.color, current_ctx.stroke, current_ctx.shape,
|
||||||
|
parseInt(current_ctx.begin_point.x), parseInt(current_ctx.begin_point.y),
|
||||||
|
parseInt(current_ctx.end_point.x), parseInt(current_ctx.end_point.y), text]
|
||||||
|
|
||||||
|
for (var i in fields) {
|
||||||
|
var td = tr.appendChild(document.createElement("td"));
|
||||||
|
switch (headers[i]) {
|
||||||
|
case "shape":
|
||||||
|
case "style":
|
||||||
|
case "stroke":
|
||||||
|
var select = td.appendChild(document.createElement("select"));
|
||||||
|
(function() {
|
||||||
|
var index = [headers[i]];
|
||||||
|
select.onchange = function(event) {
|
||||||
|
draw_history[tr.rowIndex-1][index] = event.target[event.target.selectedIndex].text;
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
var shapes = current_ctx.list[headers[i]];
|
||||||
|
for (var j in shapes) {
|
||||||
|
var option = select.appendChild(document.createElement("option"));
|
||||||
|
option.text = shapes[j];
|
||||||
|
if (option.text == fields[i]) {
|
||||||
|
select.selectedIndex = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
var input = td.appendChild(document.createElement("input"));
|
||||||
|
input.value = fields[i];
|
||||||
|
input.style.width="40px";
|
||||||
|
input.dataset.row = tr.rowIndex-1
|
||||||
|
input.dataset.col = headers[i]
|
||||||
|
input.onkeyup = modify
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
current_ctx.begin_point = null;
|
||||||
|
current_ctx.end_point = null;
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
function draw_move(event) {//{{{
|
||||||
|
var point = trans({x:event.offsetX, y:event.offsetY});
|
||||||
|
show_debug("", true)
|
||||||
|
show.innerText="坐标: "+parseInt(point.x)+","+parseInt(point.y);
|
||||||
|
|
||||||
|
if (current_ctx.shape == "move") {
|
||||||
|
if (current_ctx.index_point) {
|
||||||
|
draw.beginPath();
|
||||||
|
draw.arc(point.x, point.y, 5, 0, 2*Math.PI);
|
||||||
|
draw.fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_ctx.begin_point) {
|
||||||
|
refresh();
|
||||||
|
draws(draw, current_ctx.color, current_ctx.stroke, current_ctx.shape, current_ctx.begin_point, point, "");
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
//}}}
|
||||||
|
|
159
usr/wiki/html5.md
Normal file
159
usr/wiki/html5.md
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
<canvas id="heart" width="400" height="400"></canvas>
|
||||||
|
|
||||||
|
## 简介
|
||||||
|
|
||||||
|
- 文档: <https://developer.mozilla.org/en-US/docs/Learn>
|
||||||
|
- 文档: <https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/>
|
||||||
|
|
||||||
|
### miniCAD在线绘图
|
||||||
|
<label>颜色: </label>
|
||||||
|
<select onchange="select(event, 'color')">
|
||||||
|
<option>red</option>
|
||||||
|
<option>green</option>
|
||||||
|
<option>yellow</option>
|
||||||
|
<option>blue</option>
|
||||||
|
<option>black</option>
|
||||||
|
<option>white</option>
|
||||||
|
<option>purple</option>
|
||||||
|
</select>
|
||||||
|
<label>画笔: </label>
|
||||||
|
<select id="select_pan" onchange="select(event, 'stroke')">
|
||||||
|
<option>stroke</option>
|
||||||
|
<option>fill</option>
|
||||||
|
</select>
|
||||||
|
<label>图形: </label>
|
||||||
|
<select id="select_pan" onchange="select(event, 'shape')">
|
||||||
|
<option>heart</option>
|
||||||
|
<option>cycle</option>
|
||||||
|
<option>rect</option>
|
||||||
|
<option>line</option>
|
||||||
|
</select>
|
||||||
|
<label id="show">坐标: 0,0</label>
|
||||||
|
<br/>
|
||||||
|
<button class="control e" onclick="action(event, 'heart')">画心(e)</button>
|
||||||
|
<button class="control c" onclick="action(event, 'cycle')">画圆\(c\)</button>
|
||||||
|
<button class="control r" onclick="action(event, 'rect')">矩形\(r\)</button>
|
||||||
|
<button class="control v" onclick="action(event, 'line')">直线(v)</button>
|
||||||
|
<button class="control t" onclick="action(event, 'text')">文字(t)</button>
|
||||||
|
<button class="control a" onclick="action(event, 'play')">播放\(a\)</button>
|
||||||
|
<br/>
|
||||||
|
<canvas id="draw" width="400" height="400"
|
||||||
|
onmousemove="draw_move(event)"
|
||||||
|
onmouseup="draw_point(event)"
|
||||||
|
></canvas>
|
||||||
|
<br/>
|
||||||
|
<button class="control" onclick="action(event, 'move')">追踪</button>
|
||||||
|
<button class="control b" onclick="action(event, 'big')">放大(b)</button>
|
||||||
|
<button class="control m" onclick="action(event, 'small')">缩小(m)</button>
|
||||||
|
<button class="control" onclick="action(event, 'hide')">隐藏</button>
|
||||||
|
<button class="control" onclick="action(event, 'draw')">恢复</button>
|
||||||
|
<button class="control d" onclick="action(event, 'delete')">删除\(d\)</button>
|
||||||
|
<button class="control" onclick="action(event, 'clear')">清空\(q\)</button>
|
||||||
|
<br/>
|
||||||
|
<div id="fuck">
|
||||||
|
</div>
|
||||||
|
<div style="clear:both">
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
<div><table id="draw_history"></table></div>
|
||||||
|
|
||||||
|
### canvas绘图
|
||||||
|
<canvas id="demo0" class="demo" width="120" height="120"></canvas>
|
||||||
|
```
|
||||||
|
<canvas id="canvas"></canvas>
|
||||||
|
<script>
|
||||||
|
var canvas = document.getElementById("canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.fillStyle = "green";
|
||||||
|
ctx.fillRect(10,10,100,100);
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 画矩形
|
||||||
|
|
||||||
|
```
|
||||||
|
fillRect(x, y, width, height)
|
||||||
|
strokeRect(x, y, width, height)
|
||||||
|
clearRect(x, y, width, height)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 画路径
|
||||||
|
<canvas id="demo2" class="demo" width="120" height="120"></canvas>
|
||||||
|
```
|
||||||
|
<canvas id="demo2" width="120" height="120"></canvas>
|
||||||
|
<script>
|
||||||
|
var ctx2 = document.getElementById("demo2").getContext("2d");
|
||||||
|
ctx2.beginPath();
|
||||||
|
ctx2.moveTo(60,10);
|
||||||
|
ctx2.lineTo(10,110);
|
||||||
|
ctx2.lineTo(110,110);
|
||||||
|
ctx2.fill();
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
beginPath()
|
||||||
|
moveTo(x, y)
|
||||||
|
LineTo(x, y)
|
||||||
|
closePath()
|
||||||
|
stroke()
|
||||||
|
fill()
|
||||||
|
|
||||||
|
arc(x, y, radius, startAngle, endAngle, anticlockwise)
|
||||||
|
arcTo(x1, y1, x2, y2, radius)
|
||||||
|
quadraticCurveTo(cp1x, cp1y, x, y)
|
||||||
|
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
|
||||||
|
new Path2D()
|
||||||
|
```
|
||||||
|
### 设置样式
|
||||||
|
<canvas id="demo3" class="demo" width="120" height="120"></canvas>
|
||||||
|
```
|
||||||
|
fillStyle = "red"
|
||||||
|
fillStyle = "#FF0000"
|
||||||
|
fillStyle = "rgb(255,0,0)"
|
||||||
|
fillStyle = "rgb(255,0,0,1)"
|
||||||
|
strokeStyle =
|
||||||
|
|
||||||
|
var img = new Image();
|
||||||
|
img.src = "img.png";
|
||||||
|
img.onLoad = function() {}
|
||||||
|
createPattern(img, style)
|
||||||
|
|
||||||
|
createLinearGradient(x1, y1, x2, y2)
|
||||||
|
createRadialGradient(x1, y1, r1, x2, y2, r2)
|
||||||
|
addColorStop(position, color)
|
||||||
|
|
||||||
|
shadowOffsetX
|
||||||
|
shadowOffsetY
|
||||||
|
shadowBlur
|
||||||
|
shadowColor
|
||||||
|
|
||||||
|
lineWidth
|
||||||
|
lineCap
|
||||||
|
lineJoin
|
||||||
|
```
|
||||||
|
### 输出文字
|
||||||
|
```
|
||||||
|
font
|
||||||
|
textAlign
|
||||||
|
textBaseline
|
||||||
|
direction
|
||||||
|
measureText()
|
||||||
|
fillText(text, x, y[, maxWidth])
|
||||||
|
strokeText(text, x, y[, maxWidth])
|
||||||
|
```
|
||||||
|
|
||||||
|
### 坐标变换
|
||||||
|
```
|
||||||
|
save()
|
||||||
|
restore()
|
||||||
|
translate(x,y)
|
||||||
|
rotate(angle)
|
||||||
|
scale(x, y)
|
||||||
|
transform(a,b,c,d,e,f)
|
||||||
|
setTransform(a,b,c,d,e,f)
|
||||||
|
resetTransform()
|
||||||
|
```
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/wiki/html5.css" type="text/css"></link>
|
||||||
|
<script src="/wiki/html5.js"></script>
|
Loading…
x
Reference in New Issue
Block a user