Skip to content

Instantly share code, notes, and snippets.

@mdecourse
Last active January 13, 2022 16:04
Show Gist options
  • Save mdecourse/2f56974a40da7a218dbaef376a5b4ca4 to your computer and use it in GitHub Desktop.
Save mdecourse/2f56974a40da7a218dbaef376a5b4ca4 to your computer and use it in GitHub Desktop.
cp2021 W11
# 從 browser 導入 document
from browser import document
# 使用者可以透過 window 當作介面使用其他 Javascript 功能
from browser import html, window, ajax
# https://www.brython.info/static_doc/en/ajax.html
brython_div = document["brython_div"]
output = html.DIV("output")
output.id = "output"
brython_div <= output
# 插入輸入表單
form = html.FORM()
A = html.INPUT(type="text", id="A", size="5", name="a", value="2")
B = html.INPUT(type="text", id="B", size="5", name="b", value="3")
button = html.BUTTON("calculate", id="calculate")
form <= "a: " + A + html.BR()
form <= "b: " + B + html.BR()
brython_div <= form + button + html.BR()
def log(*args):
output = document["output"]
output.html += ', '.join(str(arg) for arg in args)
def show(req):
document["output"].clear()
log(req.text)
def on_complete(req):
document["output"].clear()
if req.status==200 or req.status==0:
document["output"] <= req.text
else:
document["output"] <= "error " + req.text
def post(ev):
# a 為 id="A" 輸入欄位中所輸入的值
a = document['A'].value
# b 為 id="B" 輸入欄位中所輸入的值
b = document['B'].value
url = "http://localhost:9448/add_numbers"
ajax.post(url,
oncomplete=show,
data={"a": a, "b":b})
# req 從 ajax 模組中的 ajax 類別建立案例, 為一個 ajax 物件
'''
req = ajax.Ajax()
# ajax 物件中的 bind 方法, 第一個輸入變數為 evt, 'complete' 表示 ajax 從伺服器取值完成後, 執行 on_complete 函式
req.bind('complete', on_complete)
req.open('POST', url, True)
req.set_header('content-type','application/x-www-form-urlencoded')
req.send({"a": a, "b":b})
'''
# 使用者按下 id="calculate" 按鈕, 將會執行上述 get("/add_numbers") 函式
document['calculate'].bind('click', post)
from flask import Flask, render_template, request, jsonify
# 必須導入 CORS
from flask_cors import CORS
# Initialize the Flask application
app = Flask(__name__)
CORS(app, support_credentials=False)
@app.route('/')
def index():
#return render_template('index.html')
return "index"
@app.route('/add_numbers', methods=['POST'])
def add_numbers():
a = request.form.get('a', 0, type=int)
b = request.form.get('b', 0, type=int)
#return jsonify(result = a+b)
# 必須傳回字串?
return str(a+b)
if __name__ == '__main__':
app.run(debug=True, port=9448) #, ssl_context="adhoc")
# 這個程式用於 demo 綠色方塊往隨機產生的紅色方塊位置移動
# 此程式並未計算各紅色方塊與綠色方塊的距離, 僅按照隨機排序移動
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 用於定時執行特定函式
import browser.timer
# 導入亂數模組
from random import random, randint
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c default 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
# 從兩個座標點求中心點座標
def center(lx, ly, rx, ry):
# lx is x coord of the left up corner
# rx is the x coord of th right down corner
x = (lx + rx)/2
y = (ly + ry)/2
return x, y
# 畫出填色方塊
def draw_rect(gx, gy, gw, gh, color="lime"):
# gx is the grid coord at x direction
# gy is the grid coord at y direction
# gw is the width of the green rect
# gh is the height of the green rect
lx = origx + (gx-1)*w
ly = origy + (gy-1)*h
rx = origx + gx*w
ry = origy + gy*h
cx, cy = center(lx, ly, rx, ry)
# glx is the x coord of the left corner
# gly is the y coord of the left corner
glx = cx - gw/2
gly = cy - gh/2
# 利用設定的顏色值畫出 rectangle
ctx.fillStyle = color
ctx.fillRect(glx, gly, gw, gh)
# 以白色覆蓋位於 (nowx, nowy)
# 且比目標方塊長寬各大於 1 pixel的方塊
def wipe():
draw_rect(nowx, nowy, 30+1, 30+1, color="white")
# 畫出位於 (nowx, nowy) 的綠色方塊
def draw():
draw_rect(nowx, nowy, 30, 30, color="lime")
# 以隨機方式在格點座標中畫出紅色方塊
def draw_red(x, y):
draw_rect(x, y, wrect_size, hrect_size, color="red")
# 綠色方塊往紅色方塊位置移動, 抵達目標位置後停止移動
def walk():
global stepx, stepy
if nowx > redx:
stepx = -1
stepy = 0
if nowx < redx:
stepx = 1
stepy = 0
if nowy > redy:
stepx = 0
stepy = -1
if nowy < redy:
stepx = 0
stepy = 1
if nowx == redx and nowy == redy:
stepx = 0
stepy = 0
# 每隔短暫時間即呼叫執行一次的函式
def game():
# 因 nowx, nowy, redx, redy 在函式外宣告
# 且在函式內改變對應值, 因此需宣告為 global
global nowx, nowy, redx, redy
# 當綠色方塊移動至紅色方塊座標後, 逐一取出另一個紅色目標座標值
if nowx == redx and nowy == redy:
# 利用 pop() 逐一取出 coord 中的座標值 pos
# coord 取至最後一個數列後, 即跳至 pass
try:
pos = coord.pop()
# 索引 0 為 x 座標, 1 為 y 座標
redx = pos[0]
redy = pos[1]
wText(int((redx-0.5)*w), int((redy-0.5)*h), "O")
except:
# 以隨機方產生 5 個座標值
for i in range(5):
# wnum 為 width 方向的格子數
# hnum 為 height 方向的格子數
x = randint(1, wnum)
y = randint(1, hnum)
# 逐一在座標位置畫出紅色方塊
draw_red(x, y)
# 將座標值以數列方式放入 coord 數列
coord.append([x, y])
walk()
wipe()
nowx += stepx
nowy += stepy
draw()
# 綠色方塊起點座標與 x 及 y 方向的座標增量
nowx = 1
nowy = 1
stepx = 0
stepy = 0
go = True
# 設定格數
# width 方向格子數
wnum = 15
# height 方向格子數
hnum = 15
# 紅色方塊座標起始座標位於右下角
redx = wnum-1
redy = hnum-1
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/wnum) - pixel
# 設定 h 高度
h = int(canvas.height/hnum) - pixel
# 設定紅色方塊寬度與高度, 分別設為格子大小的 70%
wrect_size = int(w*0.7)
hrect_size = int(h*0.7)
# 設定繪圖座標點起點位置
origx = 1
origy = 1
# 利用 grid 函式畫出格線
grid(origx, origy, w, h, wnum, hnum, pixel=1, color="black")
# 宣告 coord 為數列
coord = []
# 以隨機方產生 5 個座標值
for i in range(5):
# wnum 為 width 方向的格子數
# hnum 為 height 方向的格子數
x = randint(1, wnum)
y = randint(1, hnum)
# 逐一在座標位置畫出紅色方塊
draw_red(x, y)
# 將座標值以數列方式放入 coord 數列
coord.append([x, y])
browser.timer.set_interval(game, 100)
# source: https://www.geeksforgeeks.org/combinations-in-python-without-using-itertools/
# Function to create combinations
# without itertools
def n_length_combo(lst, n):
if n == 0:
return [[]]
l =[]
for i in range(0, len(lst)):
m = lst[i]
remLst = lst[i + 1:]
for p in n_length_combo(remLst, n-1):
l.append([m]+p)
return l
# Driver code
if __name__=="__main__":
arr ="abc"
print(n_length_combo([x for x in arr], 2))
class_name = "1a"
class_course = "cp2021_final"
data_url = "https://mde.tw/" + class_course+ "/downloads/" + class_name + "_grouping.txt"
data = open(data_url).read().splitlines()
data = list(filter(None, data))
#print(data)
grp_count = 0
grp_title = []
grp_mem = []
grp_big = []
for i in data:
if class_name in i:
mem_count = 0
grp_count += 1
grp = i
# 納入各組組序標題
grp_title.append(i)
# 若 grp_mem 有值, 表示已經讀完各組學員名單
# 就可以將該組全員名單納入 grp_big 數列中
# 然後 grp_mem 重新設為空數列, 準備納入下一組員名單
if len(grp_mem) > 1:
grp_big.append(grp_mem)
grp_mem = []
#print("組別:", grp_count, grp)
else:
# 讀完各組組序標題後, 將逐一將組員名單納入 grp_mem 數列中
grp_mem.append(i)
mem_count += 1
student_id = i
#print("學員:", mem_count, student_id)
# 離開組序標題後, 必須納入最後一組學員名單
grp_big.append(grp_mem)
# 查驗是否正確讀入各班組員名單
#print(grp_title, grp_big)
for i in range(len(grp_title)):
# 分別讀出各組組序與排序後的組員學號
print(grp_title[i], sorted(grp_big[i]))
# 這個程式用於 demo 以 canvas 畫線以及寫字
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c defaul 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
# 設定格數
num = 15
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/num) - pixel
# 設定 h 高度
h = int(canvas.height/num) - pixel
# 設定繪圖座標點起點位置
x = 1
y = 1
# 利用 grid 函式畫出格線
grid(x, y, w, h, num, num, pixel=1, color="black")
# 這個程式用於 demo 以 canvas 畫線以及寫字
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 用於定時執行特定函式
import browser.timer
# 導入亂數模組
from random import random, randint
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c defaul 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
def center(lx, ly, rx, ry):
# lx is x coord of the left up corner
# rx is the x coord of th right down corner
x = (lx + rx)/2
y = (ly + ry)/2
return x, y
def draw_rect(gx, gy, gw, gh, color="lime"):
# gx is the grid coord at x direction
# gy is the grid coord at y direction
# gw is the with of the green rect
# gh is the height of the green rect
lx = origx + (gx-1)*w
ly = origy + (gy-1)*h
rx = origx + gx*w
ry = origy + gy*h
cx, cy = center(lx, ly, rx, ry)
# glx is the x coord of the left corner
# gly is the y coord of the left corner
glx = cx - gw/2
gly = cy - gh/2
# 利用設定的顏色值畫出 rectangle
ctx.fillStyle = color
ctx.fillRect(glx, gly, gw, gh)
# 設定格數
# width 方向格子數
wnum = 15
# height 方向格子數
hnum = 15
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/wnum) - pixel
# 設定 h 高度
h = int(canvas.height/hnum) - pixel
# 設定繪圖座標點起點位置
origx = 1
origy = 1
# 利用 grid 函式畫出格線
grid(origx, origy, w, h, wnum, hnum, pixel=1, color="black")
# 利用 draw_rect 以 grid 座標畫出正方形, 內建為 lime
draw_rect(3, 3, 30, 30)
# 利用隨機亂數產生五個紅色方塊
# wnum 與 hnum 為 x 與 y 方向的格子個數
# w 與 h 方向上的方塊 pixel 數
wrect_size = 30
hrect_size = 30
# 利用 for 迴圈產生五個紅色方塊
for i in range(5):
xcoord = randint(1, wnum)
ycoord = randint(1, hnum)
draw_rect(xcoord, ycoord, wrect_size, hrect_size, color="red")
# make canvas 600x400
from browser import document as doc
from browser import window
from browser import timer
from browser import html
import math
# 建立 fourbar canvas
canvas = html.CANVAS(width = 600, height = 400)
canvas.id = "fourbar"
brython_div = doc["brython_div"]
brython_div <= canvas
# 準備繪圖畫布
canvas = doc["fourbar"]
# 建立 buttons
brython_div <= html.BUTTON("啟動", id="power")
brython_div <= html.BUTTON("反向", id="reverse")
# 利用 window 擷取 PrairieDraw 程式庫變數物件, 然後以 JSConstructor 函式轉為 Brython 變數
pdraw = window.PrairieDraw.new
# 利用 window 擷取 PrairieDrawAnim 程式庫變數物件, 然後以 JSConstructor 函式轉為 Brython 變數
PrairieDrawAnim = window.PrairieDrawAnim.new
# 利用 window 擷取 sylvester 程式庫變數物件 Vector, 並將其 create 方法直接轉為 Brython 變數
# 在 sylvester 中的 $V 簡化變數無法直接在 Brython 程式中引用
vector = window.Vector.create.new
# 在 "fourbar" 畫布中建立 panim 動態模擬案例
panim = PrairieDrawAnim("fourbar")
# 平面連桿繪圖以 t = 0 起始
t = 0
# 控制轉動方向變數
direction = True
# 繪製不同 t 時間下的平面連桿
def draw():
global t, direction, fast
# 設定模擬繪圖範圍
panim.setUnits(6, 6)
# 設定箭頭線寬
panim.setProp("arrowLineWidthPx",2)
# 起始變數設定
omega = 1
length_bar1 = 1
length_bar2 = 26/18
length_bar3 = 2
length_base = 40/18
time = 0
# 畫出地面直線
G = vector([0, -0.5])
panim.ground(G, vector([0, 1]), 10)
# 連桿長度與角度計算
A = t*omega # "theta"
AD = length_bar1 #length of left bar
AB = length_base #distance between two stationary pivots
BC = length_bar3 #length of right bar
CD = length_bar2 #length of middle bar
BD = math.sqrt(AD*AD + AB*AB - 2*AD*AB*math.cos(A))
C = math.acos((BC*BC + CD*CD - BD*BD)/(2*BC*CD))
ABD = math.asin(CD * math.sin(C) / BD)
DBC = math.asin(AD * math.sin(A) / BD)
B = ABD + DBC
D = math.pi - B - C
# draw pivot
pivot_left = vector([AB/-2, 0])
pivot_right = vector([AB/2, 0])
panim.pivot(vector([pivot_left.e(1), -0.5]), pivot_left, 0.5)
panim.pivot(vector([pivot_right.e(1), -0.5]), pivot_right, 0.5)
# 儲存轉換矩陣
panim.save()
#FIRST BAR
panim.translate(pivot_left)
panim.rotate(A)
panim.rod(vector([0,0]), vector([AD,0]), 0.25)
panim.point(vector([0,0]))
#SECOND BAR
panim.translate(vector([AD,0]))
panim.rotate(A*-1) #"undo" the original A rotation
panim.rotate(D) #rotate by D only
panim.rod(vector([0,0]), vector([CD,0]), 0.25)
panim.point(vector([0,0]))
#THIRD BAR
panim.translate(vector([CD,0]))
panim.rotate(math.pi+C)
panim.rod(vector([0,0]), vector([BC,0]), 0.25)
panim.point(vector([0,0]))
# 回復原先的轉換矩陣
panim.restore()
panim.point(vector([pivot_right.e(1), 0]))
# 時間增量
if direction == True:
t += 0.08
else:
t += -0.08
# 先畫出 t = 0 的連桿機構
draw()
# 將 anim 設為 None
anim = None
def launchAnimation(ev):
global anim
# 初始啟動, anim 為 None
if anim is None:
# 每 0.08 秒執行一次 draw 函式繪圖
anim = timer.set_interval(draw, 80)
# 初始啟動後, 按鈕文字轉為"暫停"
doc['power'].text = '暫停'
elif anim == 'hold':
# 當 anim 為 'hold' 表示曾經暫停後的啟動, 因此持續以 set_interval() 持續旋轉, 且將 power 文字轉為"暫停"
anim = timer.set_interval(draw, 80)
doc['power'].text = '暫停'
else:
# 初始啟動後, 使用者再按 power, 此時 anim 非 None 也不是 'hold', 因此會執行 clear_interval() 暫停
# 且將 anim 變數設為 'hold', 且 power 文字轉為"繼續"
timer.clear_interval(anim)
anim = 'hold'
doc['power'].text = '繼續'
def reverse(ev):
global anim, direction
# 當 anim 為 hold 時, 按鈕無效
if anim != "hold":
if direction == True:
direction = False
else:
direction = True
doc["power"].bind("click", launchAnimation)
doc["reverse"].bind("click", reverse)
# import point-line-triangle module
import plt
import math
from browser import document as doc
from browser import timer
from browser import html
midpt = plt.Point(0, 0)
tippt = plt.Point(0, 0)
contour = []
# 執行繪圖流程, 注意 x, y 為 global variables
def draw():
global theta, midpt, oldpt
context.clearRect(0, 0, canvas.width, canvas.height)
line1.drawMe(context)
line2.drawMe(context)
line3.drawMe(context)
line4.drawMe(context)
#triangle1.drawMe(context)
#triangle2.drawMe(context)
theta += dx
#PLAP
p2.x = p1.x + line1.length*math.cos(theta*degree)
p2.y = p1.y - line1.length*math.sin(theta*degree)
#PLLP
p3.x, p3.y = triangle2.setPPSS(p2,p4,line2.length,line3.length)
# 計算垂直單位向量
a = plt.Coord(p3.x, p3.y)
b = plt.Coord(p2.x, p2.y)
normal = plt.perpendicular(plt.normalize(a-b))
midpt.x = (p2.x + p3.x)/2
midpt.y = (p2.y + p3.y)/2
tippt.x = midpt.x + 150*normal.x
tippt.y = midpt.y + 150*normal.y
if theta < 360:
contour.append((tippt.x, tippt.y))
context.beginPath()
context.moveTo(midpt.x, midpt.y)
context.lineTo(tippt.x, tippt.y)
# 利用 fillRect 繪製一個長寬各 1 單位的正方形
for i in range(len(contour)):
context.fillRect(contour[i][0], contour[i][1], 1, 1)
context.stroke()
#p1.tag(context)
# 以上為相關函式物件的定義區
# 全域變數
# 幾何位置輸入變數
x=10
y=10
r=10
# 畫布與繪圖內容
# 其他輸入變數
theta = 0
degree = math.pi/180.0
dx = 2
dy = 4
#set p1.p2.p3.p4 position
lift = 10
# 各起始座標點必須精確
p1 = plt.Point(150,100+lift)
p2 = plt.Point(150,200+lift)
p3 = plt.Point(300,300+lift)
p4 = plt.Point(350,100+lift)
#共有五條線
line1 = plt.Link(p1,p2)
line2 = plt.Link(p2,p3)
line3 = plt.Link(p3,p4)
line4 = plt.Link(p1,p4)
line5 = plt.Link(p2,p4)
#link2_len = p2.distance(p3)
#link3_len = p3.distance(p4)
#link2_len = line1.getR()
#link3_len = line3.getR()
#alert(str(link2_len)+','+str(link3_len))
triangle1 = plt.Triangle(p1,p2,p4)
triangle2 = plt.Triangle(p2,p3,p4)
# 視窗載入時執行內容
# 繪圖畫布設定
canvas = html.CANVAS(width = 500, height = 500)
canvas.id = "game-board"
brython_div = doc["brython_div"]
brython_div <= canvas
#canvas = document["plotarea2"]
context = canvas.getContext("2d")
# 座標轉換, 移動 canvas.height 並且 y 座標變號, 也就是將原點座標移到畫面左下角
context.translate(0,canvas.height)
context.scale(1,-1)
#以間隔 20 micro seconds 重複呼叫 draw()
timer.set_interval(draw,20)
a = 0.2 + 2.3 -9.7 +11.2
# b = 4.2 ......
print(a)
# source: https://stackoverflow.com/questions/33312532/generate-all-permutations-of-a-string-in-python-without-using-itertools
def permutations_with_repetition(s):
base = len(s)
for n in range(base**base):
yield "".join(s[n // base**(base-d-1) % base] for d in range(base))
for p in permutations_with_repetition("abc"):
print(p)
# pont, line and triangle scripts
import math
class Coord(object):
def __init__(self,x,y):
self.x = x
self.y = y
def __sub__(self,other):
# This allows you to substract vectors
return Coord(self.x-other.x,self.y-other.y)
def __repr__(self):
# Used to get human readable coordinates when printing
return "Coord(%f,%f)"%(self.x,self.y)
def length(self):
# Returns the length of the vector
return math.sqrt(self.x**2 + self.y**2)
def angle(self):
# Returns the vector's angle
return math.atan2(self.y,self.x)
def normalize(coord):
return Coord(
coord.x/coord.length(),
coord.y/coord.length()
)
def perpendicular(coord):
# Shifts the angle by pi/2 and calculate the coordinates
# using the original vector length
return Coord(
coord.length()*math.cos(coord.angle()+math.pi/2),
coord.length()*math.sin(coord.angle()+math.pi/2)
)
# 點類別
class Point(object):
# 起始方法
def __init__(self, x, y):
self.x = x
self.y = y
# 繪製方法
def drawMe(self, g, r):
self.g = g
self.r = r
self.g.save()
self.g.moveTo(self.x,self.y)
self.g.beginPath()
# 根據 r 半徑繪製一個圓代表點的所在位置
self.g.arc(self.x, self.y, self.r, 0, 2*math.pi, True)
self.g.moveTo(self.x,self.y)
self.g.lineTo(self.x+self.r, self.y)
self.g.moveTo(self.x, self.y)
self.g.lineTo(self.x-self.r, self.y)
self.g.moveTo(self.x, self.y)
self.g.lineTo(self.x, self.y+self.r)
self.g.moveTo(self.x, self.y)
self.g.lineTo(self.x, self.y-self.r)
self.g.restore()
self.g.stroke()
# 加入 Eq 方法
def Eq(self, pt):
self.x = pt.x
self.y = pt.y
# 加入 setPoint 方法
def setPoint(self, px, py):
self.x = px
self.y = py
# 加上 distance(pt) 方法, 計算點到 pt 的距離
def distance(self, pt):
self.pt = pt
x = self.x - self.pt.x
y = self.y - self.pt.y
return math.sqrt(x * x + y * y)
# 利用文字標示點的座標位置
def tag(self, g):
self.g = g
self.g.beginPath()
self.g.fillText("%d, %d"%(self.x, self.y),self.x, self.y)
self.g.stroke()
# Line 類別物件
class Line(object):
# 起始方法
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
# 直線的第一點, 設為線尾
self.Tail = self.p1
# 直線組成的第二點, 設為線頭
self.Head = self.p2
# 直線的長度屬性
self.length = math.sqrt(math.pow(self.p2.x-self.p1.x, 2)+math.pow(self.p2.y-self.p1.y,2))
# setPP 以指定頭尾座標點來定義直線
def setPP(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.Tail = self.p1
self.Head = self.p2
self.length = math.sqrt(math.pow(self.p2.x-self.p1.x, 2)+math.pow(self.p2.y-self.p1.y,2))
# setRT 方法 for Line, 應該已經確定 Tail 點, 然後以 r, t 作為設定 Head 的參考
def setRT(self, r, t):
self.r = r
self.t = t
x = self.r * math.cos(self.t)
y = self.r * math.sin(self.t)
self.Tail.Eq(self.p1)
self.Head.setPoint(self.Tail.x + x,self.Tail.y + y)
# getR 方法 for Line
def getR(self):
# x 分量與 y 分量
x = self.p1.x - self.p2.x
y = self.p1.y - self.p2.y
return math.sqrt(x * x + y * y)
# 根據定義 atan2(y,x), 表示 (x,y) 與 正 x 軸之間的夾角, 介於 pi 與 -pi 間
def getT(self):
x = self.p2.x - self.p1.x
y = self.p2.y - self.p1.y
if (math.fabs(x) < math.pow(10,-100)):
if(y < 0.0):
return (-math.pi/2)
else:
return (math.pi/2)
else:
return math.atan2(y, x)
# setTail 方法 for Line
def setTail(self, pt):
self.pt = pt
self.Tail.Eq(pt)
self.Head.setPoint(self.pt.x + self.x, self.pt.y + self.y)
# getHead 方法 for Line
def getHead(self):
return self.Head
def getTail(self):
return self.Tail
def drawMe(self, g):
self.g = g
self.g.beginPath()
self.g.moveTo(self.p1.x,self.p1.y)
self.g.lineTo(self.p2.x,self.p2.y)
self.g.stroke()
def test(self):
return ("this is pure test to Inherit")
class Link(Line):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
self.length = math.sqrt(math.pow((self.p2.x - self.p1.x), 2) + math.pow((self.p2.y - self.p1.y), 2))
#g context
def drawMe(self, g):
self.g = g
hole = 5
radius = 10
length = self.getR()
# alert(length)
# 儲存先前的繪圖狀態
self.g.save()
self.g.translate(self.p1.x,self.p1.y)
#alert(str(self.p1.x)+","+str(self.p1.y))
#self.g.rotate(-((math.pi/2)-self.getT()))
self.g.rotate(-math.pi*0.5 + self.getT())
#alert(str(self.getT()))
#self.g.rotate(10*math.pi/180)
#this.g.rotate(-(Math.PI/2-this.getT()));
# 必須配合畫在 y 軸上的 Link, 進行座標轉換, 也可以改為畫在 x 軸上...
self.g.beginPath()
self.g.moveTo(0,0)
self.g.arc(0, 0, hole, 0, 2*math.pi, True)
self.g.stroke()
self.g.moveTo(0,length)
self.g.beginPath()
self.g.arc(0,length, hole, 0, 2*math.pi, True)
self.g.stroke()
self.g.moveTo(0,0)
self.g.beginPath()
self.g.arc(0,0, radius, 0, math.pi, True)
self.g.moveTo(0+radius,0)
self.g.lineTo(0+radius,0+length)
self.g.stroke()
self.g.moveTo(0,0+length)
self.g.beginPath()
self.g.arc(0, 0+length, radius, math.pi, 0, True)
self.g.moveTo(0-radius,0+length)
self.g.lineTo(0-radius,0)
self.g.stroke()
self.g.restore()
'''
self.g.beginPath()
self.g.fillStyle = "red"
self.g.font = "bold 18px sans-serif"
self.g.fillText("%d, %d"%(self.p2.x, self.p2.y),self.p2.x, self.p2.y)
self.g.stroke()
'''
class Triangle(object):
def __init__(self, p1, p2, p3):
self.p1 = p1
self.p2 = p2
self.p3 = p3
def getLenp3(self):
p1 = self.p1
ret = p1.distance(self.p2)
return ret
def getLenp1(self):
p2 = self.p2
ret = p2.distance(self.p3)
return ret
def getLenp2(self):
p1 = self.p1
ret = p1.distance(self.p3)
return ret
# 角度
def getAp1(self):
ret = math.acos(((self.getLenp2() * self.getLenp2() + self.getLenp3() * self.getLenp3()) - self.getLenp1() * self.getLenp1()) / (2* self.getLenp2() * self.getLenp3()))
return ret
#
def getAp2(self):
ret =math.acos(((self.getLenp1() * self.getLenp1() + self.getLenp3() * self.getLenp3()) - self.getLenp2() * self.getLenp2()) / (2* self.getLenp1() * self.getLenp3()))
return ret
def getAp3(self):
ret = math.acos(((self.getLenp1() * self.getLenp1() + self.getLenp2() * self.getLenp2()) - self.getLenp3() * self.getLenp3()) / (2* self.getLenp1() * self.getLenp2()))
return ret
def drawMe(self, g):
self.g = g
r = 5
# 繪出三個頂點
self.p1.drawMe(self.g,r)
self.p2.drawMe(self.g,r)
self.p3.drawMe(self.g,r)
line1 = Line(self.p1,self.p2)
line2 = Line(self.p1,self.p3)
line3 = Line(self.p2,self.p3)
# 繪出三邊線
line1.drawMe(self.g)
line2.drawMe(self.g)
line3.drawMe(self.g)
# ends Triangle def
# 透過三個邊長定義三角形
def setSSS(self, lenp3, lenp1, lenp2):
self.lenp3 = lenp3
self.lenp1 = lenp1
self.lenp2 = lenp2
self.ap1 = math.acos(((self.lenp2 * self.lenp2 + self.lenp3 * self.lenp3) - self.lenp1 * self.lenp1) / (2* self.lenp2 * self.lenp3))
self.ap2 = math.acos(((self.lenp1 * self.lenp1 + self.lenp3 * self.lenp3) - self.lenp2 * self.lenp2) / (2* self.lenp1 * self.lenp3))
self.ap3 = math.acos(((self.lenp1 * self.lenp1 + self.lenp2 * self.lenp2) - self.lenp3 * self.lenp3) / (2* self.lenp1 * self.lenp2))
# 透過兩個邊長與夾角定義三角形
def setSAS(self, lenp3, ap2, lenp1):
self.lenp3 = lenp3
self.ap2 = ap2
self.lenp1 = lenp1
self.lenp2 = math.sqrt((self.lenp3 * self.lenp3 + self.lenp1 * self.lenp1) - 2* self.lenp3 * self.lenp1 * math.cos(self.ap2))
#等於 SSS(AB, BC, CA)
def setSaSS(self, lenp2, lenp3, lenp1):
self.lenp2 = lenp2
self.lenp3 = lenp3
self.lenp1 = lenp1
if(self.lenp1 > (self.lenp2 + self.lenp3)):
#<CAB 夾角為 180 度, 三點共線且 A 介於 BC 之間
ret = math.pi
else :
# <CAB 夾角為 0, 三點共線且 A 不在 BC 之間
if((self.lenp1 < (self.lenp2 - self.lenp3)) or (self.lenp1 < (self.lenp3 - self.lenp2))):
ret = 0.0
else :
# 透過餘絃定理求出夾角 <CAB
ret = math.acos(((self.lenp2 * self.lenp2 + self.lenp3 * self.lenp3) - self.lenp1 * self.lenp1) / (2 * self.lenp2 * self.lenp3))
return ret
# 取得三角形的三個邊長值
def getSSS(self):
temp = []
temp.append( self.getLenp1() )
temp.append( self.getLenp2() )
temp.append( self.getLenp3() )
return temp
# 取得三角形的三個角度值
def getAAA(self):
temp = []
temp.append( self.getAp1() )
temp.append( self.getAp2() )
temp.append( self.getAp3() )
return temp
# 取得三角形的三個角度與三個邊長
def getASASAS(self):
temp = []
temp.append(self.getAp1())
temp.append(self.getLenp1())
temp.append(self.getAp2())
temp.append(self.getLenp2())
temp.append(self.getAp3())
temp.append(self.getLenp3())
return temp
#2P 2L return mid P
def setPPSS(self, p1, p3, lenp1, lenp3):
temp = []
self.p1 = p1
self.p3 = p3
self.lenp1 = lenp1
self.lenp3 = lenp3
#bp3 is the angle beside p3 point, cp3 is the angle for line23, p2 is the output
line31 = Line(p3, p1)
self.lenp2 = line31.getR()
#self.lenp2 = self.p3.distance(self.p1)
#這裡是求角3
ap3 = math.acos(((self.lenp1 * self.lenp1 + self.lenp2 * self.lenp2) - self.lenp3 * self.lenp3) / (2 * self.lenp1 * self.lenp2))
#ap3 = math.acos(((self.lenp1 * self.lenp1 + self.lenp3 * self.lenp3) - self.lenp2 * self.lenp2) / (2 * self.lenp1 * self.lenp3))
bp3 = line31.getT()
cp3 = bp3 - ap3
temp.append(p3.x + self.lenp1*math.cos(cp3))#p2.x
temp.append(p3.y + self.lenp1*math.sin(cp3))#p2.y
return temp
# 畫中華人民共和國國旗
# 根據 https://en.wikipedia.org/wiki/Flag_of_China 規格繪圖
# 導入 doc
from browser import document as doc
# 以下將利用 html 產生所需的繪圖畫布
from browser import html
# 利用 math 函式庫執行三角函數運算
import math
canvas = html.CANVAS(width = 600, height = 400)
#canvas.style = {"width": "100%"}
canvas.id = "taiwan_flag"
# 將圖畫至 id 為 brython_div 的 cnavas 標註
brython_div = doc["brython_div"]
brython_div <= canvas
# 準備繪圖畫布
canvas = doc["taiwan_flag"]
ctx = canvas.getContext("2d")
# 進行座標轉換, x 軸不變, y 軸反向且移動 canvas.height 單位光點
# ctx.setTransform(1, 0, 0, -1, 0, canvas.height)
# 以下採用 canvas 原始座標繪圖
flag_w = canvas.width
flag_h = canvas.height
# 先畫滿地紅
ctx.fillStyle='rgb(255, 0, 0)'
ctx.fillRect(0,0,flag_w,flag_h)
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 測試畫直線函式功能
#draw_line(10, 10, 100, 100)
# 定義角度轉換為徑度變數
deg = math.pi/180.
# 建立五星繪圖函式
#x, y 為中心, r 為半徑, angle 旋轉角, solid 空心或實心, color 顏色
def star(x, y, r, angle=0, solid=False, color="#ff0000"):
#以 x, y 為圓心, 計算五個外點
# 圓心到水平線距離
a = r*math.cos(72*deg)
# a 頂點向右到內點距離
b = (r*math.cos(72*deg)/math.cos(36*deg))*math.sin(36*deg)
# 利用畢氏定理求內點半徑
rin = math.sqrt(a*a + b*b)
# 查驗 a, b 與 rin
#print(a, b, rin)
if solid:
ctx.beginPath()
# angle 角度先轉 360/10, 讓五星對正
angle = angle + 360/10
for i in range(5):
xout = (x + r*math.sin((360/5)*deg*i+angle*deg))
yout = (y + r*math.cos((360/5)*deg*i+angle*deg))
# 外點增量 + 1
xout2 = x + r*math.sin((360/5)*deg*(i+1)+angle*deg)
yout2 = y + r*math.cos((360/5)*deg*(i+1)+angle*deg)
xin = x + rin*math.sin((360/5)*deg*i+36*deg+angle*deg)
yin = y + rin*math.cos((360/5)*deg*i+36*deg+angle*deg)
# 查驗外點與內點座標
#print(xout, yout, xin, yin)
if solid:
# 填色
if i==0:
ctx.moveTo(xout, yout)
ctx.lineTo(xin, yin)
ctx.lineTo(xout2, yout2)
else:
ctx.lineTo(xin, yin)
ctx.lineTo(xout2, yout2)
else:
# 空心
draw_line(xout, yout, xin, yin, color)
# 畫空心五芒星, 無關畫線次序, 若實心則與畫線次序有關
draw_line(xout2, yout2, xin, yin, color)
if solid:
ctx.fillStyle = color
ctx.fill()
yellow = "#FFFF00"
# 大五星位於 (5x20, 5x20) 半徑為 3x20
star(100, 100, 60, solid=True, color=yellow)
unit = int(canvas.width/30)
# 計算各小五星座標與轉角
x1 = 10*unit
y1 = 2*unit
x2 = 12*unit
y2 = 4*unit
x3 = 12*unit
y3 = 7*unit
x4 = 10*unit
y4 = 9*unit
angle1 = 90 + math.atan(3/5)/deg
angle2 = 90 + math.atan(1/7)/deg
angle3 = 90 - math.atan(2/7)/deg
angle4 = 90 - math.atan(4/5)/deg
radius = 20
star(x1, y1, radius , angle=angle1, solid=True, color=yellow)
star(x2, y2, radius, angle=angle2, solid=True, color=yellow)
star(x3, y3, radius, angle=angle3, solid=True, color=yellow)
star(x4, y4, radius, angle=angle4, solid=True, color=yellow)
# 這個程式用於 demo 綠色方塊沿著網格 ㄇ形路徑行走
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 用於定時執行特定函式
import browser.timer
# 導入亂數模組
from random import random, randint
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c defaul 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
# 從兩個座標點求中心點座標
def center(lx, ly, rx, ry):
# lx is x coord of the left up corner
# rx is the x coord of th right down corner
x = (lx + rx)/2
y = (ly + ry)/2
return x, y
# 畫出填色方塊
def draw_rect(gx, gy, gw, gh, color="lime"):
# gx is the grid coord at x direction
# gy is the grid coord at y direction
# gw is the with of the green rect
# gh is the height of the green rect
lx = origx + (gx-1)*w
ly = origy + (gy-1)*h
rx = origx + gx*w
ry = origy + gy*h
cx, cy = center(lx, ly, rx, ry)
# glx is the x coord of the left corner
# gly is the y coord of the left corner
glx = cx - gw/2
gly = cy - gh/2
# 利用設定的顏色值畫出 rectangle
ctx.fillStyle = color
ctx.fillRect(glx, gly, gw, gh)
# 以白色覆蓋位於 (nowx, nowy)
# 且比目標方塊長寬各大於 1 pixel的方塊
def wipe():
draw_rect(nowx, nowy, 30+1, 30+1, color="white")
# 畫出位於 (nowx, nowy) 的綠色方塊
def draw():
draw_rect(nowx, nowy, 30, 30, color="lime")
# 繞著外圍行走
def walk():
global stepx, stepy, go
# 去程
if go == True:
# 向上
if nowy == hnum and nowx == 1:
stepx = 0
stepy = -1
# 向右
elif nowx < wnum and nowy == 1:
stepx = 1
stepy = 0
# 向下
elif nowy == 1 and nowx == wnum:
stepx = 0
stepy = 1
elif nowx == wnum and nowy == hnum:
go = False
# 回程
if go == False:
# 向上
if nowx == wnum and nowy == hnum:
stepx = 0
stepy = -1
# 向左
elif nowy == 1 and nowx > 1:
stepx = -1
stepy = 0
# 向下
elif nowx == 1 and nowy == 1:
stepx = 0
stepy = 1
elif nowx ==1 and nowy == hnum:
stepx = 0
stepy = -1
go = True
# 每隔短暫時間即呼叫執行一次的函式
def game():
# 因 nowx 與 nowy 在函式外宣告
# 且在函式內改變對應值, 因此需宣告為 global
global nowx, nowy
walk()
wipe()
nowx += stepx
nowy += stepy
draw()
# 綠色方塊起點座標與 x 及 y 方向的座標增量
nowx = 1
nowy = 15
stepx = 0
stepy = 0
go = True
# 設定格數
# width 方向格子數
wnum = 15
# height 方向格子數
hnum = 15
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/wnum) - pixel
# 設定 h 高度
h = int(canvas.height/hnum) - pixel
# 設定繪圖座標點起點位置
origx = 1
origy = 1
# 利用 grid 函式畫出格線
grid(origx, origy, w, h, wnum, hnum, pixel=1, color="black")
'''
# 利用 draw_rect 以 grid 座標畫出正方形, 內建為 lime
draw_rect(3, 3, 30, 30)
# 利用隨機亂數產生五個紅色方塊
# wnum 與 hnum 為 x 與 y 方向的格子個數
# w 與 h 方向上的方塊 pixel 數
wrect_size = 30
hrect_size = 30
# 利用 for 迴圈產生五個紅色方塊
for i in range(5):
xcoord = randint(1, wnum)
ycoord = randint(1, hnum)
draw_rect(xcoord, ycoord, wrect_size, hrect_size, color="red")
'''
browser.timer.set_interval(game, 100)
# 這個程式用於 demo 綠色方塊沿著網格 U 形路徑行走
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 用於定時執行特定函式
import browser.timer
# 導入亂數模組
from random import random, randint
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c defaul 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
# 從兩個座標點求中心點座標
def center(lx, ly, rx, ry):
# lx is x coord of the left up corner
# rx is the x coord of th right down corner
x = (lx + rx)/2
y = (ly + ry)/2
return x, y
# 畫出填色方塊
def draw_rect(gx, gy, gw, gh, color="lime"):
# gx is the grid coord at x direction
# gy is the grid coord at y direction
# gw is the with of the green rect
# gh is the height of the green rect
lx = origx + (gx-1)*w
ly = origy + (gy-1)*h
rx = origx + gx*w
ry = origy + gy*h
cx, cy = center(lx, ly, rx, ry)
# glx is the x coord of the left corner
# gly is the y coord of the left corner
glx = cx - gw/2
gly = cy - gh/2
# 利用設定的顏色值畫出 rectangle
ctx.fillStyle = color
ctx.fillRect(glx, gly, gw, gh)
# 以白色覆蓋位於 (nowx, nowy)
# 且比目標方塊長寬各大於 1 pixel的方塊
def wipe():
draw_rect(nowx, nowy, 30+1, 30+1, color="white")
# 畫出位於 (nowx, nowy) 的綠色方塊
def draw():
draw_rect(nowx, nowy, 30, 30, color="lime")
# 繞著外圍行走
def walk():
global stepx, stepy, go
# 去程
if go == True:
# 向下
if nowy < hnum and nowx == 1:
stepx = 0
stepy = 1
# 向右
elif nowx < wnum and nowy == hnum:
stepx = 1
stepy = 0
# 向上
elif nowy == hnum and nowx == wnum:
stepx = 0
stepy = -1
elif nowx == wnum and nowy == 1:
go = False
# 回程
if go == False:
# 向下
if nowx == wnum and nowy == 1:
stepx = 0
stepy = 1
# 向左
elif nowy == hnum and nowx > 1:
stepx = -1
stepy = 0
# 向上
elif nowx == 1 and nowy == hnum:
stepx = 0
stepy = -1
elif nowx ==1 and nowy == 1:
stepx = 0
stepy = 1
go = True
# 每隔短暫時間即呼叫執行一次的函式
def game():
# 因 nowx 與 nowy 在函式外宣告
# 且在函式內改變對應值, 因此需宣告為 global
global nowx, nowy
walk()
wipe()
nowx += stepx
nowy += stepy
draw()
# 綠色方塊起點座標與 x 及 y 方向的座標增量
nowx = 1
nowy = 1
stepx = 0
stepy = 0
go = True
# 設定格數
# width 方向格子數
wnum = 15
# height 方向格子數
hnum = 15
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/wnum) - pixel
# 設定 h 高度
h = int(canvas.height/hnum) - pixel
# 設定繪圖座標點起點位置
origx = 1
origy = 1
# 利用 grid 函式畫出格線
grid(origx, origy, w, h, wnum, hnum, pixel=1, color="black")
'''
# 利用 draw_rect 以 grid 座標畫出正方形, 內建為 lime
draw_rect(3, 3, 30, 30)
# 利用隨機亂數產生五個紅色方塊
# wnum 與 hnum 為 x 與 y 方向的格子個數
# w 與 h 方向上的方塊 pixel 數
wrect_size = 30
hrect_size = 30
# 利用 for 迴圈產生五個紅色方塊
for i in range(5):
xcoord = randint(1, wnum)
ycoord = randint(1, hnum)
draw_rect(xcoord, ycoord, wrect_size, hrect_size, color="red")
'''
browser.timer.set_interval(game, 100)
# 這個程式用於 demo 綠色方塊沿著特定網格路徑行走
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 用於定時執行特定函式
import browser.timer
# 導入亂數模組
from random import random, randint
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c defaul 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
# 從兩個座標點求中心點座標
def center(lx, ly, rx, ry):
# lx is x coord of the left up corner
# rx is the x coord of th right down corner
x = (lx + rx)/2
y = (ly + ry)/2
return x, y
# 畫出填色方塊
def draw_rect(gx, gy, gw, gh, color="lime"):
# gx is the grid coord at x direction
# gy is the grid coord at y direction
# gw is the with of the green rect
# gh is the height of the green rect
lx = origx + (gx-1)*w
ly = origy + (gy-1)*h
rx = origx + gx*w
ry = origy + gy*h
cx, cy = center(lx, ly, rx, ry)
# glx is the x coord of the left corner
# gly is the y coord of the left corner
glx = cx - gw/2
gly = cy - gh/2
# 利用設定的顏色值畫出 rectangle
ctx.fillStyle = color
ctx.fillRect(glx, gly, gw, gh)
# 以白色覆蓋位於 (nowx, nowy)
# 且比目標方塊長寬各大於 1 pixel的方塊
def wipe():
draw_rect(nowx, nowy, 30+1, 30+1, color="white")
# 畫出位於 (nowx, nowy) 的綠色方塊
def draw():
draw_rect(nowx, nowy, 30, 30, color="lime")
# 繞著外圍行走
def walk():
global stepx, stepy
# 向下
if nowy < hnum and nowx == 1:
stepx = 0
stepy = 1
# 向右
elif nowx < wnum and nowy == hnum:
stepx = 1
stepy = 0
# 向上
elif nowy == hnum and nowx == wnum:
stepx = 0
stepy = -1
# 向左
elif nowx == wnum and nowy == 1:
stepx = -1
stepy = 0
# 每隔短暫時間即呼叫執行一次的函式
def game():
# 因 nowx 與 nowy 在函式外宣告
# 且在函式內改變對應值, 因此需宣告為 global
global nowx, nowy
walk()
wipe()
nowx += stepx
nowy += stepy
draw()
# 綠色方塊起點座標與 x 及 y 方向的座標增量
nowx = 1
nowy = 1
stepx = 0
stepy = 0
# 設定格數
# width 方向格子數
wnum = 15
# height 方向格子數
hnum = 15
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/wnum) - pixel
# 設定 h 高度
h = int(canvas.height/hnum) - pixel
# 設定繪圖座標點起點位置
origx = 1
origy = 1
# 利用 grid 函式畫出格線
grid(origx, origy, w, h, wnum, hnum, pixel=1, color="black")
'''
# 利用 draw_rect 以 grid 座標畫出正方形, 內建為 lime
draw_rect(3, 3, 30, 30)
# 利用隨機亂數產生五個紅色方塊
# wnum 與 hnum 為 x 與 y 方向的格子個數
# w 與 h 方向上的方塊 pixel 數
wrect_size = 30
hrect_size = 30
# 利用 for 迴圈產生五個紅色方塊
for i in range(5):
xcoord = randint(1, wnum)
ycoord = randint(1, hnum)
draw_rect(xcoord, ycoord, wrect_size, hrect_size, color="red")
'''
browser.timer.set_interval(game, 100)
# 畫中華民國國旗
# 導入 doc
from browser import document as doc
# 以下將利用 html 產生所需的繪圖畫布
from browser import html
# 利用 math 函式庫執行三角函數運算
import math
canvas = html.CANVAS(width = 600, height = 400)
#canvas.style = {"width": "100%"}
canvas.id = "taiwan_flag"
# 將圖畫至 id 為 brython_div 的 cnavas 標註
brython_div = doc["brython_div"]
brython_div <= canvas
# 準備繪圖畫布
canvas = doc["taiwan_flag"]
ctx = canvas.getContext("2d")
# 進行座標轉換, x 軸不變, y 軸反向且移動 canvas.height 單位光點
# ctx.setTransform(1, 0, 0, -1, 0, canvas.height)
# 以下採用 canvas 原始座標繪圖
flag_w = canvas.width
flag_h = canvas.height
circle_x = flag_w/4
circle_y = flag_h/4
# 先畫滿地紅
ctx.fillStyle='rgb(255, 0, 0)'
ctx.fillRect(0,0,flag_w,flag_h)
# 再畫青天
ctx.fillStyle='rgb(0, 0, 150)'
ctx.fillRect(0,0,flag_w/2,flag_h/2)
# 畫十二道光芒白日
ctx.beginPath()
star_radius = flag_w/8
angle = 0
for i in range(24):
angle += 5*math.pi*2/12
toX = circle_x + math.cos(angle)*star_radius
toY = circle_y + math.sin(angle)*star_radius
# 只有 i 為 0 時移動到 toX, toY, 其餘都進行 lineTo
if (i):
ctx.lineTo(toX, toY)
else:
ctx.moveTo(toX, toY)
ctx.closePath()
# 將填色設為白色
ctx.fillStyle = '#fff'
ctx.fill()
# 白日:藍圈
ctx.beginPath()
ctx.arc(circle_x, circle_y, flag_w*17/240, 0, math.pi*2, True)
ctx.closePath()
# 填色設為藍色
ctx.fillStyle = 'rgb(0, 0, 149)'
ctx.fill()
# 白日:白心
ctx.beginPath()
ctx.arc(circle_x, circle_y, flag_w/16, 0, math.pi*2, True)
ctx.closePath()
# 填色設為白色
ctx.fillStyle = '#fff'
ctx.fill()
# 這個程式用於 demo 綠色方塊往隨機產生的紅色方塊位置移動
# 從 Brython 程式庫中的 browser 模組導入 document 類別, 並以簡寫設定為 doc
from browser import document as doc
# 從 browser 模組導入 html 類別, 主要用於建立 CANVAS 標註物件, 並插入頁面中
from browser import html
# 用於定時執行特定函式
import browser.timer
# 導入亂數模組
from random import random, randint
# 利用 html 建立一個 CANVAS 標註物件, 與變數 canvas 對應
canvas = html.CANVAS(width = 600, height = 600)
# 將 canvas 標註的 id 設為 "canvas"
canvas.id = "canvas"
# 將 document 中 id 為 "brython_div" 的標註
# 設為與 brython_div 變數對應
brython_div = doc["brython_div"]
# 將 canvas 標註放入 brython_div 所在位置
# 頁面中原本就已經放入 <div id="brython_div"></div> 標註
brython_div <= canvas
# 將頁面中 id 為 canvas 的 CANVAS 設為與 canvas 變數對應
canvas = doc["canvas"]
# 將 canvas 的 2d 繪圖 context 命名為 ctx
ctx = canvas.getContext("2d")
# 建立一個 dRect() 函式
# s default 為 1, c default 為紅色
def dRect(lux, luy, w, h, s=1, c='#ff0000'):
ctx.lineWidth = s
ctx.strokeStyle = c
ctx.beginPath();
ctx.rect(lux, luy, w, h)
ctx.stroke();
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 建立 write Text 函式
def wText(x, y, t, s=14, c='#0000ff'):
ctx.font = str(s) + "px Arial";
ctx.fillText(t, x, y)
# 定義畫格線的函式
def grid(startx, starty, w, h, wnum, hnum, pixel=1, color="#ff0000"):
# 利用迴圈與座標增量繪圖
# 因為輸入 wnum 與 hnum 為格子數, 畫格線數則需加上 1
for i in range(wnum+1):
for j in range(hnum+1):
# 畫上下直線
yend = starty + h*(hnum)
xend = startx + w*(wnum)
x = startx + i*w
draw_line(x, starty, x, yend, color)
# 畫左右直線
y = starty + j*h
draw_line(startx, y, xend, y, color)
#wText(w/2-10, y-w/2, str(j))
# 從兩個座標點求中心點座標
def center(lx, ly, rx, ry):
# lx is x coord of the left up corner
# rx is the x coord of th right down corner
x = (lx + rx)/2
y = (ly + ry)/2
return x, y
# 畫出填色方塊
def draw_rect(gx, gy, gw, gh, color="lime"):
# gx is the grid coord at x direction
# gy is the grid coord at y direction
# gw is the width of the green rect
# gh is the height of the green rect
lx = origx + (gx-1)*w
ly = origy + (gy-1)*h
rx = origx + gx*w
ry = origy + gy*h
cx, cy = center(lx, ly, rx, ry)
# glx is the x coord of the left corner
# gly is the y coord of the left corner
glx = cx - gw/2
gly = cy - gh/2
# 利用設定的顏色值畫出 rectangle
ctx.fillStyle = color
ctx.fillRect(glx, gly, gw, gh)
# 以白色覆蓋位於 (nowx, nowy)
# 且比目標方塊長寬各大於 1 pixel的方塊
def wipe():
draw_rect(nowx, nowy, 30+1, 30+1, color="white")
# 畫出位於 (nowx, nowy) 的綠色方塊
def draw():
draw_rect(nowx, nowy, 30, 30, color="lime")
# 以隨機方式在格點座標中畫出紅色方塊
def draw_red():
draw_rect(redx, redy, wrect_size, hrect_size, color="red")
# 綠色方塊往紅色方塊位置移動, 抵達目標位置後停止移動
def walk():
global stepx, stepy
if nowx > redx:
stepx = -1
stepy = 0
if nowx < redx:
stepx = 1
stepy = 0
if nowy > redy:
stepx = 0
stepy = -1
if nowy < redy:
stepx = 0
stepy = 1
if nowx == redx and nowy == redy:
stepx = 0
stepy = 0
# 每隔短暫時間即呼叫執行一次的函式
def game():
# 因 nowx, nowy, redx, redy 在函式外宣告
# 且在函式內改變對應值, 因此需宣告為 global
global nowx, nowy, redx, redy
# 當綠色方塊移動至紅色方塊座標後, 產生另一個紅色目標座標值
if nowx == redx and nowy == redy:
# wnum 為 width 方向的格子數
# hnum 為 height 方向的格子數
redx = randint(1, wnum)
redy = randint(1, hnum)
draw_red()
walk()
wipe()
nowx += stepx
nowy += stepy
draw()
# 綠色方塊起點座標與 x 及 y 方向的座標增量
nowx = 1
nowy = 1
stepx = 0
stepy = 0
go = True
# 設定格數
# width 方向格子數
wnum = 15
# height 方向格子數
hnum = 15
# 紅色方塊座標起始座標位於右下角
redx = wnum-1
redy = hnum-1
# 設定線寬
pixel = 1
# 設定 w 寬度
w = int(canvas.width/wnum) - pixel
# 設定 h 高度
h = int(canvas.height/hnum) - pixel
# 設定紅色方塊寬度與高度, 分別設為格子大小的 70%
wrect_size = int(w*0.7)
hrect_size = int(h*0.7)
# 設定繪圖座標點起點位置
origx = 1
origy = 1
# 利用 grid 函式畫出格線
grid(origx, origy, w, h, wnum, hnum, pixel=1, color="black")
browser.timer.set_interval(game, 100)
# 畫美國國旗
# 根據 https://en.wikipedia.org/wiki/Flag_of_the_United_States#Specifications 規格繪圖
# 導入 doc
from browser import document as doc
# 以下將利用 html 產生所需的繪圖畫布
from browser import html
# 利用 math 函式庫執行三角函數運算
import math
# height = 1, width = 1.9
width = 600
height = int(600/1.9)
canvas = html.CANVAS(width = width, height = height)
#canvas.style = {"width": "100%"}
canvas.id = "taiwan_flag"
# 將圖畫至 id 為 brython_div 的 cnavas 標註
brython_div = doc["brython_div"]
brython_div <= canvas
# 準備繪圖畫布
canvas = doc["taiwan_flag"]
ctx = canvas.getContext("2d")
# 進行座標轉換, x 軸不變, y 軸反向且移動 canvas.height 單位光點
# ctx.setTransform(1, 0, 0, -1, 0, canvas.height)
# 以下採用 canvas 原始座標繪圖
flag_w = canvas.width
flag_h = canvas.height
# 先畫滿地紅
ctx.fillStyle='#B31942'
ctx.fillRect(0,0,flag_w,flag_h)
# 6 條白色長方形
# 每條高度 height/13
ctx.fillStyle ='#FFFFFF'
white_height = int(height/13)
whitex = 0
whitey = white_height
white_width = width
for i in range(6):
ctx.fillRect(whitex, whitey+i*2*white_height, white_width, white_height)
# 藍色區域
blue_height = int(height*7/13)
blue_width = int(width*2/5)
bluex = 0
bluey = 0
ctx.fillStyle ='#0A3161'
ctx.fillRect(bluex, bluey, blue_width, blue_height)
# 建立畫直線函式
def draw_line(x1, y1, x2, y2, color="#ff0000"):
ctx.beginPath()
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.strokeStyle = color
ctx.stroke()
# 測試畫直線函式功能
#draw_line(10, 10, 100, 100)
# 定義角度轉換為徑度變數
deg = math.pi/180.
# 建立五星繪圖函式
#x, y 為中心, r 為半徑, angle 旋轉角, solid 空心或實心, color 顏色
def star(x, y, r, angle=0, solid=False, color="#ff0000"):
#以 x, y 為圓心, 計算五個外點
# 圓心到水平線距離
a = r*math.cos(72*deg)
# a 頂點向右到內點距離
b = (r*math.cos(72*deg)/math.cos(36*deg))*math.sin(36*deg)
# 利用畢氏定理求內點半徑
rin = math.sqrt(a*a + b*b)
# 查驗 a, b 與 rin
#print(a, b, rin)
if solid:
ctx.beginPath()
# angle 角度先轉 360/10, 讓五星對正
angle = angle + 360/10
for i in range(5):
xout = (x + r*math.sin((360/5)*deg*i+angle*deg))
yout = (y + r*math.cos((360/5)*deg*i+angle*deg))
# 外點增量 + 1
xout2 = x + r*math.sin((360/5)*deg*(i+1)+angle*deg)
yout2 = y + r*math.cos((360/5)*deg*(i+1)+angle*deg)
xin = x + rin*math.sin((360/5)*deg*i+36*deg+angle*deg)
yin = y + rin*math.cos((360/5)*deg*i+36*deg+angle*deg)
# 查驗外點與內點座標
#print(xout, yout, xin, yin)
if solid:
# 填色
if i==0:
ctx.moveTo(xout, yout)
ctx.lineTo(xin, yin)
ctx.lineTo(xout2, yout2)
else:
ctx.lineTo(xin, yin)
ctx.lineTo(xout2, yout2)
else:
# 空心
draw_line(xout, yout, xin, yin, color)
# 畫空心五芒星, 無關畫線次序, 若實心則與畫線次序有關
draw_line(xout2, yout2, xin, yin, color)
if solid:
ctx.fillStyle = color
ctx.fill()
# 白色五星
white = "#FFFFFF"
# 單數排白色五星
star1x = int(blue_width/12)
star1y = int(blue_height/10)
star_radius = int(white_height*4/5/2)
# 沿 x 方向有 6 顆白色五星
# 沿 y 方向有 5 顆白色五星
inc1x = int(2*blue_width/12)
inc1y = int(2*blue_height/10)
for i in range(6):
for j in range(5):
star(star1x+i*inc1x, star1y+j*inc1y, star_radius, solid=True, color=white)
# 雙數排白色五星
star2x = int(blue_width/12 + blue_width/12)
star2y = int(blue_height/10 + blue_height/10)
# 沿 x 方向有 5 顆白色五星
# 沿 y 方向有 4 顆白色五星
for i in range(5):
for j in range(4):
star(star2x+i*inc1x, star2y+j*inc1y, star_radius, solid=True, color=white)
c = [1, 2, 3, 4]
for i in c:
print(i)
# 第一排隨機列出的序號為 3.
import random
cnum = ["一", "二", "三", "四", "五", "六", "七", "八", "九"]
n = 6
for i in range(1, n+1):
num = random.randint(1, 9)
#print("第 " + str(i) + " 排隨機列出的序號為 " + str(num))
print("第 " + cnum[i-1] + " 排隨機列出的序號為 " + str(num))
# 參考: https://usefulangle.com/post/352/javascript-capture-image-from-camera
# 參考: https://usefulangle.com/post/353/javascript-canvas-image-upload
from browser import html, document, window
# 建立 video tag, 並且插入既有的 brython_div 標註中
# autoplay=True for phone camera, 480X640 for iphone
videotag = html.VIDEO(autoplay=True,id='video', width='480', height='640')
# 建立 canvas tag
canvas = html.CANVAS(width = 480, height = 640, id="canvas")
# 建立 button tag
button = html.BUTTON("Save Image", id="save")
# 分別將上列 tags 插入 id="brython_div" 之位置
brython_div = document['brython_div']
brython_div <= videotag + html.BR()
brython_div <= button + html.BR()
brython_div <= canvas
ctx = canvas.getContext("2d")
# 定義 OnSuccess 函式在 video 標註中播放 Webcam 串流影像
def OnSuccess(stream):
video = document['video']
video.srcObject = stream
video.play()
# 透過瀏覽器取得使用者同意後傳送 Webcam 串流資料
# 'facingMode': 'environment' for rear camera
window.navigator.mediaDevices.getUserMedia(
{"video": {"facingMode": 'environment'}, "audio": False}
).then(OnSuccess)
# 建立儲存串流影像至圖檔函式
def save_image(e):
#print(canvas.width)
video = document['video']
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
image_data_url = canvas.toDataURL('image/jpeg')
print(image_data_url)
# click id="save" 按鈕後, 執行 save_image
# 此 image_data_url 可以用於將影像檔案送到 server
document["save"].bind("click", save_image)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment