An Interest In:
Web News this Week
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
- March 26, 2024
- March 25, 2024
- March 24, 2024
July 6, 2019 12:48 pm GMT
Original Link: https://dev.to/sayanarijit/create-dev-s-offline-page-with-python-pyodide-and-webassembly-241h
Create Dev's offline page with Python (Pyodide) and WebAssembly
Inspired by this post:
Create Dev's offline page with (Tiny)GO and WebAssembly
Sendil Kumar N Jul 6 4 min read
#go #webassembly #showdev
I have decided to give it a try using Python.
This is the first time I am writing WebAssembly which I wanted to do for a long time. So for this, I am using Pyodide.
Let's get started
First download Pyodide, extract it and copy the pyodide.js
file in your current directory.
Now Let's write the server in server.py
.
from http.server import BaseHTTPRequestHandler, HTTPServerclass HTTPRequestHandler(BaseHTTPRequestHandler): """Request handler class""" def do_GET(self): """Handler for GET requests.""" # Send response status code self.send_response(200) # Send headers self.send_header("Cache-Control", "no-cache") if self.path.endswith(".wasm"): # Header to serve .wasm file self.send_header("Content-Type", "application/wasm") else: self.send_header("Content-Type", "text/html") self.end_headers() # Serve the file contents urlpath = self.path if urlpath == "/": urlpath = "/index.html" with open(f".{urlpath}", "rb") as f: content = f.read() self.wfile.write(content)def main(): print("starting server...") # Server settings server_address = ("localhost", 8080) httpd = HTTPServer(server_address, HTTPRequestHandler) print("running server...") httpd.serve_forever()if __name__ == "__main__": main()
So we have pyodide.js
, server.py
.
Let's write the index.html
<!doctype html><html> <head> <meta charset="utf-8"> <title>Python wasm</title> </head> <body> <script src="pyodide.js"></script> <div id="status">Initializing Python...</div> <canvas id="draw-here"></canvas> <style> .color { display: inline-block; width: 50px; height: 50px; border-radius: 50%; cursor: pointer; margin: 10px; } </style> <div id="colors" style="text-align:center"></div> <script> window.languagePluginUrl = "/pyodide.js"; languagePluginLoader.then(() => { pyodide.runPython(` ! Python code goes here ! `) }) </script> </body></html>
Now let's write the Python code for canvas.
from js import document as doc# Make the "Initializing Python" status disappeardoc.getElementById("status").innerHTML = ""canvas = doc.getElementById("draw-here")canvas.setAttribute("width", doc.body.clientWidth)canvas.setAttribute("height", 300)ctx = canvas.getContext("2d")ctx.strokeStyle = "#F4908E"ctx.lineJoin = "round"ctx.lineWidth = 5# Global variablespen = FalselastPoint = (0, 0)def onmousemove(e): global lastPoint if pen: newPoint = (e.offsetX, e.offsetY) ctx.beginPath() ctx.moveTo(lastPoint[0], lastPoint[1]) ctx.lineTo(newPoint[0], newPoint[1]) ctx.closePath() ctx.stroke() lastPoint = newPointdef onmousedown(e): global pen, lastPoint pen = True lastPoint = (e.offsetX, e.offsetY)def onmouseup(e): global pen pen = Falsecanvas.addEventListener("mousemove", onmousemove)canvas.addEventListener("mousedown", onmousedown)canvas.addEventListener("mouseup", onmouseup)# Colorsdiv = doc.getElementById("colors")colors = ["#F4908E", "#F2F097", "#88B0DC", "#F7B5D1", "#53C4AF", "#FDE38C"]for c in colors: node = doc.createElement("div") node.setAttribute("class", "color") node.setAttribute("id", c) node.setAttribute("style", f"background-color: {c}") def setColor(e): ctx.strokeStyle = e.target.id node.addEventListener("click", setColor) div.appendChild(node)
Now we can fetch this code as text via AJAX and execute with pyodide.runPython(code)
.
But for simplicity, we will directly paste the code in index.html
.
So the final version looks like this:
<!doctype html><html> <head> <meta charset="utf-8"> <title>Python wasm</title> </head> <body> <script src="pyodide.js"></script> <div id="status">Initializing Python...</div> <canvas id="draw-here"></canvas> <style> .color { display: inline-block; width: 50px; height: 50px; border-radius: 50%; cursor: pointer; margin: 10px; } </style> <div id="colors" style="text-align:center"></div> <script> window.languagePluginUrl = "/pyodide.js"; languagePluginLoader.then(() => { pyodide.runPython(`from js import document as doc# Make the "Initializing Python" status disappeardoc.getElementById("status").innerHTML = ""canvas = doc.getElementById("draw-here")canvas.setAttribute("width", doc.body.clientWidth)canvas.setAttribute("height", 300)ctx = canvas.getContext("2d")ctx.strokeStyle = "#F4908E"ctx.lineJoin = "round"ctx.lineWidth = 5# Global variablespen = FalselastPoint = (0, 0)def onmousemove(e): global lastPoint if pen: newPoint = (e.offsetX, e.offsetY) ctx.beginPath() ctx.moveTo(lastPoint[0], lastPoint[1]) ctx.lineTo(newPoint[0], newPoint[1]) ctx.closePath() ctx.stroke() lastPoint = newPointdef onmousedown(e): global pen, lastPoint pen = True lastPoint = (e.offsetX, e.offsetY)def onmouseup(e): global pen pen = Falsecanvas.addEventListener("mousemove", onmousemove)canvas.addEventListener("mousedown", onmousedown)canvas.addEventListener("mouseup", onmouseup)# Colorsdiv = doc.getElementById("colors")colors = ["#F4908E", "#F2F097", "#88B0DC", "#F7B5D1", "#53C4AF", "#FDE38C"]for c in colors: node = doc.createElement("div") node.setAttribute("class", "color") node.setAttribute("id", c) node.setAttribute("style", f"background-color: {c}") def setColor(e): ctx.strokeStyle = e.target.id node.addEventListener("click", setColor) div.appendChild(node) `) }) </script> </body></html>
Now we only need to run the webserver with python server.py
and open http://localhost:8080
If you are having trouble, here is the full project.
Original Link: https://dev.to/sayanarijit/create-dev-s-offline-page-with-python-pyodide-and-webassembly-241h
Share this article:
Tweet
View Full Article
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To