【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)

Web服务器系列相关文章编写如下:

  1. 【Web开发】Node.js实现Web服务器(http模块)
  2. 【Web开发】Node.js实现Web服务器(express模块)
  3. 【Web开发】Python实现Web服务器(Flask入门)
  4. 【Web开发】Python实现Web服务器(Flask测试)
  5. 【Web开发】Python实现Web服务器(Tornado入门)
  6. 【Web开发】Python实现Web服务器(Tornado+flask+nginx)
  7. 【Web开发】Python实现Web服务器(FastAPI)
  8. 【Web开发】Android手机上基于Termux实现Web服务器(Python、node.js)

文章目录

  • 1、前言
  • 2、Flask测试网页(GIS地图)
    • 2.1 基于model-viewer的太阳系查看的网页
    • 2.2 基于openlayers的在线地图叠加geojson的网页
    • 2.3 基于openlayers的离线地图瓦片的网页
    • 2.4 基于leaflet的在线地图叠加mbtiles的网页
    • 2.5 基于cesium.js的三维地球显示的网页
  • 3、Flask测试网页(三维显示)
    • 3.1 基于three.js的三维场景显示的网页
    • 3.2 基于babylon.js的三维场景显示的网页
    • 3.3 基于A-Frame的三维场景显示的网页
  • 4、Flask测试网页(统计图表)
    • 4.1 基于echarts的统计图的网页
    • 4.2 基于Highcharts.js的统计图的网页
  • 5、Flask测试网页(后台框架模板)
    • 5.1 基于layui的后台框架模板的网页
    • 5.2 基于layuimini的后台框架模板的网页
    • 5.3 基于Pear Admin Layui的后台框架模板的网页
  • 6、Flask测试网页(其他)
    • 6.1 基于vue的考试题目列表的网页
  • 结语

【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第1张图片

1、前言

提示:Flask是一个用python语言基于Werkzeug工具箱编写的轻量级web开发框架,它主要面向需求简单,项目周期短的小应用。

Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。Flask使用 BSD 授权。
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第2张图片

Flask也被称为 “microframework” ,因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。

【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第3张图片
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第4张图片
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第5张图片
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第6张图片

2、Flask测试网页(GIS地图)

2.1 基于model-viewer的太阳系查看的网页

该例子的具体介绍请见作者的另一篇文章,网址如下:
【小沐科普】小沐带您遨游太阳系(model-viewer,trimesh,Python)

这里通过编写python代码,搭建flask的web服务器环境,运行这个网页例子。

  • test_solarsystem.py:
#***************************************************************
#   Purpose:   基于model-viewer的太阳系查看的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-8
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************

from flask import Flask, redirect, url_for, request, render_template, Response
from io import FileIO

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('solar_system.html')

@app.route("/images/")
def get_image(filename):
    with open("static/images/{}".format(filename), 'rb') as f:
      image = f.read()
    resp = Response(image, mimetype="image/jpg")
    return resp

@app.route("/glb/")
def get_binary(filename):
    data = FileIO("static/glb/{}".format(filename))
    resp = Response(data, mimetype="application/zip")
    return resp

if __name__ == '__main__':
   app.run(debug = True)

【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第7张图片【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第8张图片
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第9张图片
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第10张图片

2.2 基于openlayers的在线地图叠加geojson的网页

该例子的具体介绍请见作者的另一篇文章,网址如下:
【GIS开发】OpenLayers入门学习(JavaScript库)

  • test_openlayers.py:
#***************************************************************
#   Purpose:   基于openlayers的在线地图叠加geojson的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-8
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************

from flask import Flask, Response, request
from flask import render_template, make_response, jsonify, send_from_directory,redirect, url_for
from io import FileIO
import os
import mimetypes
from flask_cors import CORS, cross_origin

app = Flask(__name__)
cors = CORS(app)
# CORS(app, supports_credentials=True)
# CORS(app, resources=r'/*')
# CORS(app, resources={r'/*': {'origins': '*'}})
# cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('test_openlayers.html')
    # return render_template('test_openlayers2_offlinemap.html')

def get_localfile(directory, path):
    response = make_response(send_from_directory(directory, path.encode('utf-8').decode('utf-8'), as_attachment=False))
    mime_type = mimetypes.guess_type(path)[0]
    if path.endswith(".js") :
       mime_type = "application/javascript"
    response.headers['Content-Type'] = mime_type
    print(directory, path, mime_type)
    return response

@app.route("/")
def get_staticfile(path):
    directory = os.getcwd() + "/static/"
    return get_localfile(directory, path)

@app.route("/tile/")
def get_tilefile(path):
    directory = "D:/test/maps/"
    return get_localfile(directory, path)

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
   app.run(debug = True)
  • test_openlayers.html:
doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.13.0/css/ol.css" type="text/css">
    <style>
        .map {
            height: 45rem;
            width: 100%;
        }
    style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.13.0/build/ol.js">script>
    <title>OpenLayers exampletitle>
head>

<body>
    <h2>爱看书的小沐的地图h2>
    <div id="map" class="map">div>
    <script type="text/javascript">

        var pointGeoJsonLayer = new ol.layer.Vector({
            title: 'points',
            source: new ol.source.Vector({
                projection: 'EPSG:4326',
                url: 'json/china.json',
                format: new ol.format.GeoJSON()
            })
        });

        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                pointGeoJsonLayer
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([104.1, 21.6]),
                zoom: 3
            })
        });
    script>
body>

html>

运行结果如下:

2.3 基于openlayers的离线地图瓦片的网页

test_openlayers.py: 和2.2 基于openlayers的在线地图叠加geojson的网页相同。

  • test_openlayers.html:
DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>本地瓦片数据测试title>
    <link rel="stylesheet" href="/openlayers/v6.13.0-dist/ol.css" />
    <style>
        body, html {
            width: 100%;
            height: 100%;
        }
        #map, #info {
            width: 100%;
            height: 100%;
        }
    style>
    <script src="/openlayers/v6.13.0-dist/ol.js">script>
head>

<body>
    <div id="map">div>
    <script type="text/javascript">
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: "http://127.0.0.1:5000/tile/{z}/{x}/{y}.png",
                        attributions: "test"
                    })
                })
            ],
            view: new ol.View({
                center: ol.proj.fromLonLat([37.41, 8.82]),
                zoom: 4
            }),
            controls: ol.control.defaults().extend([
                new ol.control.FullScreen(),
                new ol.control.MousePosition(),
                new ol.control.OverviewMap(),
                new ol.control.ScaleLine(),
                new ol.control.ZoomSlider(),
                new ol.control.ZoomToExtent()
            ]),
        });
    script>
body>
html>

运行结果如下:

2.4 基于leaflet的在线地图叠加mbtiles的网页

该例子的具体介绍请见作者的另一篇文章,网址如下:
【GIS开发】Leaflet入门学习(Javascript库)

  • test_leaflet.py:
#***************************************************************
#   Purpose:   基于leaflet的在线地图叠加mbtiles的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-8
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************

from flask import Flask, redirect, url_for, request, render_template, Response
from io import FileIO

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('test_leaflet.html')

@app.route("/json/")
def get_binary(filename):
    data = FileIO("static/json/{}".format(filename))
    resp = Response(data, mimetype="application/json")
    return resp

@app.route("/js/")
def get_js(filename):
    data = FileIO("static/js/{}".format(filename))
    resp = Response(data, mimetype="application/html")
    return resp

if __name__ == '__main__':
   app.run(debug = True)
  • test_leaflet.html:
DOCTYPE html>
<html>

<head>
    <title>Leaflet sampletitle>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
        integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
        crossorigin="" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"
        integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
        crossorigin="" >script>

    >
    <script src="js/Leaflet.TileLayer.MBTiles.js">script>
    <script src="https://unpkg.com/[email protected]/js/sql.js">script>
head>

<body>
    <div id="map" style="width: 900px; height: 380px">div>
    <script>
        var map = new L.Map('map').fitWorld();
 
        var mb = L.tileLayer.mbTiles('json/world_countries.mbtiles').addTo(map);
        mb.on('databaseloaded', function(ev) {
            console.info('MBTiles DB loaded', ev);
        });
        mb.on('databaseerror', function(ev) {
            console.info('MBTiles DB error', ev);
        });
    script>
body>

html>

运行结果如下:

2.5 基于cesium.js的三维地球显示的网页

Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示。它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以及多平台,易用性上都有高质量的保证。

test_cesiumjs.py:

from flask import Flask, Response
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os
import mimetypes

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('test_cesium3.html')

@app.route("/Cesium-1.93/Build/Cesium/")
def get_cesiumfile(path):
    directory = os.getcwd() + "/static/Cesium-1.93/Build/Cesium/"
    response = make_response(send_from_directory(directory, path.encode('utf-8').decode('utf-8'), as_attachment=False))
    mime_type = mimetypes.guess_type(path)[0]
    if path.endswith(".js") :
       mime_type = "application/javascript"
    response.headers['Content-Type'] = mime_type
    print(directory, path, mime_type)
    return response

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
   app.run(debug = True)
  • test_cesiumjs.html:
DOCTYPE html>
<html lang="en">
<head>
  <title>cesium.js exampletitle>
  <meta charset="utf-8">
  
  <script src="Cesium-1.93/Build/Cesium/Cesium.js">script>
  <link href="Cesium-1.93/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
head>
<body>
  <div id="cesiumContainer">div>
  <script>
    // Your access token can be found at: https://cesium.com/ion/tokens.
    // This is the default access token from your ion account

    Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZGQ4ZTc1Yy0xZjY1LTQzYzUtYjhiZi1iYTliZWFkZTVhMjYiLCJpZCI6ODc4MjQsImlhdCI6MTY0ODcyMTAyNH0.hL34d0emYTYCqDlmTq8lpL4UyA_p6W4BOATX9JqDHQs';

    // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
    const viewer = new Cesium.Viewer('cesiumContainer', {
      terrainProvider: Cesium.createWorldTerrain()
    });    
    // Add Cesium OSM Buildings, a global 3D buildings layer.
    const buildingTileset = viewer.scene.primitives.add(Cesium.createOsmBuildings());   
    // Fly the camera to San Francisco at the given longitude, latitude, and height.
    viewer.camera.flyTo({
      destination : Cesium.Cartesian3.fromDegrees(-122.4175, 37.655, 400),
      orientation : {
        heading : Cesium.Math.toRadians(0.0),
        pitch : Cesium.Math.toRadians(-15.0),
      }
    });
  script>
 div>
body>
html>
  • 运行结果:

3、Flask测试网页(三维显示)

3.1 基于three.js的三维场景显示的网页

  • test_threejs.py:
#***************************************************************
#   Purpose:   基于three.js的三维场景显示的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-8
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
from flask import Flask, render_template, Response
from io import FileIO

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('test_threejs.html')

@app.route("/js/")
def get_js(path):
    data = FileIO("static/js/{}".format(path))
    resp = Response(data, mimetype="application/javascript")
    return resp

@app.route("/glb/")
def get_binary(filename):
    data = FileIO("static/glb/{}".format(filename))
    resp = Response(data, mimetype="application/zip")
    return resp
    
if __name__ == '__main__':
   app.run(debug = True)
  • test_threejs.html:
DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>My first three.js apptitle>
    <style>
        body {margin: 0;}
    style>
head>

<body>
    <script src="js/three.js">script>
    <script src="js/loaders/GLTFLoader.js">script>
    <script src="js/controls/OrbitControls.js">script>
    <script>
        /* add scene */ 
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(1, 1, 5);
        camera.lookAt(new THREE.Vector3(0, 0, 0));

        /* add light */ 
        scene.add(new THREE.AmbientLight(0x999999)); // 环境光
        let light = new THREE.DirectionalLight(0xdfebff, 0.45);
        light.position.set(100, 600, 400);
        light.position.multiplyScalar(0.3);
        light.shadow.camera.near = 20; // 产生阴影的最近距离
        light.shadow.camera.far = 20000; // 产生阴影的最远距离
        light.shadow.camera.left = -500; // 产生阴影距离位置的最左边位置
        light.shadow.camera.right = 500; // 最右边
        light.shadow.camera.top = 500; // 最上边
        light.shadow.camera.bottom = -500; // 最下面
        light.castShadow = true;
        light.shadow.mapSize = new THREE.Vector2(1024, 1024);
        scene.add(light);
        //var helper = new THREE.DirectionalLightHelper(light, 5);
        //scene.add(helper);
        
        /* add renderer */ 
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        /* add orbit control */ 
        let controls = new THREE.OrbitControls(camera, renderer.domElement)
        controls.target.set(0, 0, 0)
        controls.minDistance = 1
        controls.maxDistance = 1000
        //controls.maxPolarAngle = Math.PI / 3
        //controls.minPolarAngle=controls.maxPolarAngle=1.57079
        //controls.minAzimuthAngle = Math.PI;
        //controls.maxAzimuthAngle = Math.PI;
        controls.enableDamping = true;
        controls.update()

        /* add a box model */ 
        const geometry = new THREE.BoxGeometry();
        const material = new THREE.MeshBasicMaterial({
            color: 0xffff00
        });
        const cube = new THREE.Mesh(geometry, material);
        cube.position.x = 2;
        scene.add(cube);

        /* add a gltf model */ 
        gltfmodel = null;
        const loader = new THREE.GLTFLoader();
        loader.load('glb/Avocado2.glb', function (gltf) {
            gltfmodel = gltf.scene;
            gltfmodel.position.x = 0;
            gltfmodel.position.y = 0;
            gltfmodel.position.z = 0;
            gltfmodel.scale.set(40, 40, 40);

            gltfmodel.traverse((object) => {
                if (object.isMesh) {
                    console.log(object)
                    object.castShadow = true
                    object.receiveShadow = true
                }
            })
            gltfmodel.receiveShadow = true
            scene.add(gltfmodel)
        }, undefined,
        function (error) {
            console.error(error);
        });

        /* add floor */ 
        const floorGeometry = new THREE.PlaneGeometry(1000, 1000, 100, 100)
        const floorMaterial = new THREE.MeshPhongMaterial({
            color: 0x808080,
            shininess: 0,
            wireframe: true
        })
        const floor = new THREE.Mesh(floorGeometry, floorMaterial)
        floor.rotation.x = -0.5 * Math.PI
        floor.position.z = -1;
        // 地板接受阴影开启
        floor.receiveShadow = true
        scene.add(floor)

        /* add animation */
        function animate() {
            requestAnimationFrame(animate);
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;
            renderer.render(scene, camera);
            update();
        };

        /* 更新 */
        function update() {
            controls.update();
        }

        /* 窗口变动触发的方法 */
        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }

        animate();
        window.addEventListener('resize', onWindowResize, false);
    script>
body>
html>

运行结果如下:

3.2 基于babylon.js的三维场景显示的网页

  • test_babylon.py:
#***************************************************************
#   Purpose:   基于babylon.js的三维场景显示的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-8
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
from flask import Flask, render_template, Response
from io import FileIO

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('test_babylon.html')

@app.route("/js/babylon/")
def get_js(path):
    data = FileIO("static/js/babylon/{}".format(path))
    resp = Response(data, mimetype="application/javascript")
    return resp

@app.route("/glb/")
def get_binary(filename):
    data = FileIO("static/glb/{}".format(filename))
    resp = Response(data, mimetype="application/zip")
    return resp
    
if __name__ == '__main__':
   app.run(debug = True)
  • test_threejs.html:
doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <style>
        html,
        body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%;
            -ms-touch-action: none;
            touch-action: none;
        }
    style>
    <title>Babylon exampletitle>
head>

<body>
<canvas>canvas>
<script src="https://cdn.babylonjs.com/babylon.js">script>
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js">script>

<script>
    var canvas = document.querySelector("canvas");
    var engine = new BABYLON.Engine(canvas, true);

    var scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(0.2, 0.2, 0.2);

    var camera = new BABYLON.FreeCamera("mainCamera", new BABYLON.Vector3(0, 5, -10), scene);
    camera.setTarget(BABYLON.Vector3.Zero());
    camera.attachControl(canvas, false);

    var light = new BABYLON.SpotLight("light", new BABYLON.Vector3(0, 14, -1), new BABYLON.Vector3(0, -1, 0), 1, 16,
        scene);
    light.intensity = 0.9;

    var sphereMaterial = new BABYLON.StandardMaterial("sphereMaterial", scene);
    sphereMaterial.diffuseColor = new BABYLON.Color3(0.6, 0.2, 0.2);
    sphereMaterial.specularPower = 128;

    var sphere = BABYLON.Mesh.CreateSphere("sphere", 16, 2, scene);
    sphere.position.y = 1;
    sphere.material = sphereMaterial;

    var groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
    groundMaterial.diffuseColor = new BABYLON.Color3(0.1, 0.3, 0.1);

    var ground = BABYLON.Mesh.CreateGround("ground", 10, 10, 2, scene);
    ground.material = groundMaterial;
    ground.receiveShadows = true;

    var shadowGenerator = new BABYLON.ShadowGenerator(1024, light);
    shadowGenerator.setDarkness(0.4);
    shadowGenerator.getShadowMap().renderList.push(sphere);
    shadowGenerator.useBlurVarianceShadowMap = true;
    shadowGenerator.blurScale = 2;
    shadowGenerator.bias = 0.01;

    BABYLON.SceneLoader.AppendAsync("glb/", "CesiumMan.glb", scene).then(function (scene) {
        scene.meshes[3].scaling.x = 3;
        scene.meshes[3].scaling.y = 3;
        scene.meshes[3].scaling.z = 3;

        scene.createDefaultCameraOrLight(true, true, true);
        scene.activeCamera.alpha += Math.PI;
    });
    
    BABYLON.SceneLoader.AppendAsync("glb/", "CesiumMan.glb", scene).then(function (scene) {
        scene.meshes[4].scaling.x = 3;
        scene.meshes[4].scaling.y = 3;
        scene.meshes[4].scaling.z = 3;
        scene.meshes[4].position.x = 3;
    });

    engine.runRenderLoop(function () {
        scene.render();
    });

    window.addEventListener("resize", function () {
        engine.resize();
    })
script>
body>
html>

运行结果如下:

3.3 基于A-Frame的三维场景显示的网页

https://aframe.io/
https://codepen.io/AndraConnect/pen/YNogdG?editors=1000

A-Frame 可以从纯 HTML 文件开发,而无需安装任何东西。尝试 A-Frame 的一个好方法是在 Glitch
上重新混合启动示例,这是一个可以立即免费托管和部署的在线代码编辑器。

A-Frame 支持大多数 VR 耳机,例如 Vive、Rift、Windows Mixed Reality、Daydream、GearVR、Cardboard、Oculus Go,甚至可以用于增强现实。尽管 A-Frame 支持整个频谱,但 A-Frame 旨在定义超越基本 360° 内容的完全沉浸式交互式 VR 体验,充分利用位置跟踪和控制器。

组件:使用 A-Frame 的核心组件(例如几何、材质、灯光、动画、模型、光线投射器、阴影、位置音频、文本和大多数主要耳机的控件)开始运行。进一步了解数百个社区组件,包括环境、状态、粒子系统、物理、多用户、海洋、传送、超级手和 增强现实。

  • test_A-Frame.py:
#***************************************************************
#   Purpose:   基于A-Frame.js的三维场景显示的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-18
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************

from flask import Flask, Response
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('test_A-Frame.html')

@app.route("/js/")
def get_js(path):
    data = FileIO("static/js/aframe/{}".format(path))
    resp = Response(data, mimetype="application/javascript")
    return resp

@app.route("/glb2/")
def get_binary(filename):
    data = FileIO("static/glb2/{}".format(filename))
    resp = Response(data, mimetype="application/zip")
    return resp
    
@app.route("/images/")
def get_image(filename):
    with open("static/images/{}".format(filename), 'rb') as f:
      image = f.read()
    resp = Response(image, mimetype="image/jpg")
    return resp

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
   app.run(debug = True)
  • test_A-Frame.html:
<html>
<head>
  <script src="js/aframe-v1.3.0.min.js">script>
head>

<body>
  <a-scene background="color: #333" stats>
    <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9">a-box>
    <a-sphere position="0 1.25 -5" radius="0.25" color="#EF2D5E">a-sphere>
    <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D">a-cylinder>
    <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4">a-plane>

    <a-assets>
      <a-asset-item id="XD40" src="glb2/XD40.glb">a-asset-item>
      <a-mixin id="planet" geometry="primitive: sphere; radius: 0.5">a-mixin>
      <a-mixin id="orbitAnimation"
        animation="property: object3D.rotation.y; to: 360; loop: true; easing: linear; dur: 3000">a-mixin>
      <a-mixin id="spinAnimation"
        animation="property: object3D.rotation.y; to: 360; loop: true; easing: linear; dur: 96000">a-mixin>
      <img id="sun" src="images/sun.jpg">
    a-assets>
    
    <a-entity position="5 0 0" gltf-model="#XD40">a-entity>
    <a-entity position="-5 0 0" gltf-model="#XD40">a-entity>

    <a-entity position="0 6 -5">
      <a-entity light="type: point; intensity: 2">a-entity>
      <a-entity light="type: ambient; color: #888">a-entity>
      <a-entity mixin="planet spinAnimation" geometry="radius: 3" material="shader: flat; src: #sun">a-entity>
      <a-entity mixin="orbitAnimation" animation="dur: 8000">
        <a-entity mixin="planet" material="color: red" position="8 0 0" geometry="radius: 1">a-entity>
      a-entity>
      <a-entity mixin="orbitAnimation" animation="dur: 4000">
        <a-entity mixin="planet" material="color: blue" position="6 0 0">a-entity>
      a-entity>
      <a-entity mixin="orbitAnimation" animation="dur: 2000">
        <a-entity animation__p="property: geometry.p; dir: alternate; easing: linear; loop: true; to: 4"
          animation__q="property: geometry.q; dir: alternate; easing: linear; loop: true; to: 7"
          geometry="primitive: torusKnot; radius: .5; radiusTubular: .05" material="color: green" position="4 0 0">
        a-entity>
      a-entity>
    a-entity>

    <a-camera position='0 0 3' user-height='0' wasd-controls-enabled="true">a-camera>
  a-scene>

body>
html>
  • 运行结果:

4、Flask测试网页(统计图表)

4.1 基于echarts的统计图的网页

https://echarts.apache.org
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

  • test_echarts.py:
#***************************************************************
#   Purpose:   基于echarts的统计图的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-29
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************

from flask import Flask, Response, request
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os
import mimetypes
from flask_cors import CORS, cross_origin

app = Flask(__name__)
# cors = CORS(app)
CORS(app, supports_credentials=True)
# CORS(app, resources=r'/*')
# cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

# 跨域支持
@app.after_request
def af_request(resp):     
    """
    #请求钩子,在所有的请求发生后执行,加入headers。
    :param resp:
    :return:
    """
    resp = make_response(resp)
    resp.headers['Access-Control-Allow-Origin'] = '*'
    resp.headers['Access-Control-Allow-Methods'] = 'GET,POST'
    resp.headers['Access-Control-Allow-Headers'] = 'x-requested-with,content-type'
    return resp

# 只允许路径为'/login'跨域!
@app.route('/login')
@cross_origin()
def data():
    return jsonify({'name':'tomcat'})

@app.route('/test')
@cross_origin(supports_credentials=True)
def hello():
    name = request.args.get("name", "World")
    return f'Hello, {name}!'

@app.route('/')
def index():
    return render_template('test_echarts.html')

@app.route("/")
def get_cesiumfile(path):
    directory = os.getcwd() + "/static/echarts-5.3.2/package/dist/"
    response = make_response(send_from_directory(directory, path.encode('utf-8').decode('utf-8'), as_attachment=False))
    mime_type = mimetypes.guess_type(path)[0]
    if path.endswith(".js") :
       mime_type = "application/javascript"
    response.headers['Content-Type'] = mime_type
    print(directory, path, mime_type)
    return response

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
   app.run(debug = True)
  • 运行结果:


【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第11张图片

4.2 基于Highcharts.js的统计图的网页

https://www.highcharts.com.cn/

  • test_echarts.py:
#***************************************************************
#   Purpose:   基于Highcharts.js的统计图的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-29
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
from flask import Flask, Response, request
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os
import mimetypes
from flask_cors import CORS, cross_origin

app = Flask(__name__)
cors = CORS(app)
# CORS(app, supports_credentials=True)
# CORS(app, resources=r'/*')
# cors = CORS(app, resources={r"/api/*": {"origins": "*"}})

@app.route('/')
def index():
    return render_template('test_Highcharts.html')

@app.route("/")
def get_staticfile(path):
    directory = os.getcwd() + "/static/"
    print(directory)
    response = make_response(send_from_directory(directory, path.encode('utf-8').decode('utf-8'), as_attachment=False))
    mime_type = mimetypes.guess_type(path)[0]
    if path.endswith(".js") :
       mime_type = "application/javascript"
    response.headers['Content-Type'] = mime_type
    print(directory, path, mime_type)
    return response

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')

if __name__ == '__main__':
   app.run(debug = True)
  • 运行结果:
    【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第12张图片

5、Flask测试网页(后台框架模板)

5.1 基于layui的后台框架模板的网页

  • test_layui.py:
#***************************************************************
#   Purpose:   基于layui的后台框架模板的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-24
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
from flask import Flask, Response
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os

app = Flask(__name__)
#app = Flask(__name__, template_folder="templates")

app.jinja_env.block_start_string = '{%%'  # 修改块开始符号
app.jinja_env.block_end_string = '%%}'  # 修改块结束符号
app.jinja_env.variable_start_string = '{{{'  # 修改变量开始符号
app.jinja_env.variable_end_string = '}}}'  # 修改变量结束符号
app.jinja_env.comment_start_string = '##}'  # 修改注释开始符号
app.jinja_env.comment_end_string = '##}'  # 修改注释结束符号复制代码

# 因为vue和render_template的模板都是用{{  }},所以会冲突,将flask的修改为[[  ]]
##app.jinja_env.variable_start_string = '[['
##app.jinja_env.variable_end_string = ']]'

@app.route('/')
def index():
    return render_template('layui-v2.6.9/examples/table.html')

@app.route("/dist/css/")
@app.route("/src/css/")
def get_css2(path):
    data = FileIO("templates/layui-v2.6.9/src/css/{}".format(path))
    resp = Response(data, mimetype="text/css")
    return resp

@app.route("/dist/")
@app.route("/src/")
def get_json(path):
    data = FileIO("templates/layui-v2.6.9/src/{}".format(path))
    resp = Response(data, mimetype="application/javascript")
    return resp

@app.route("/json/")
def get_binary(path):
    data = FileIO("templates/layui-v2.6.9/examples/json/{}".format(path))
    resp = Response(data, mimetype="application/json")
    return resp

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')
    #
 
if __name__ == '__main__':
   app.run(debug = True)
  • 运行结果:
    【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第13张图片
    【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第14张图片

5.2 基于layuimini的后台框架模板的网页

  • test_layuimini.py:
#***************************************************************
#   Purpose:   基于layuimini的后台框架模板的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-30
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
from flask import Flask, Response
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os
import mimetypes

app = Flask(__name__)

app.jinja_env.block_start_string = '{%%'  # 修改块开始符号
app.jinja_env.block_end_string = '%%}'  # 修改块结束符号
app.jinja_env.variable_start_string = '{{{'  # 修改变量开始符号
app.jinja_env.variable_end_string = '}}}'  # 修改变量结束符号
app.jinja_env.comment_start_string = '##}'  # 修改注释开始符号
app.jinja_env.comment_end_string = '##}'  # 修改注释结束符号复制代码

@app.route('/')
def index():
    return render_template('layuimini-2/index.html')

@app.route("/")
def get_staticfile(path):
    directory = os.getcwd() + "/templates/layuimini-2/"
    print(directory)
    response = make_response(send_from_directory(directory, path.encode('utf-8').decode('utf-8'), as_attachment=False))
    mime_type = mimetypes.guess_type(path)[0]
    if path.endswith(".js") :
       mime_type = "application/javascript"
    response.headers['Content-Type'] = mime_type
    print(directory, path, mime_type)
    return response

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')
    #
 
if __name__ == '__main__':
   app.run(debug = True)
  • 运行结果:

5.3 基于Pear Admin Layui的后台框架模板的网页

  • test_layuimini.py:
#***************************************************************
#   Purpose:   基于Pear Admin Layui的后台框架模板的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-30
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
from flask import Flask, Response
from flask import render_template, make_response, jsonify, send_from_directory
from io import FileIO
import os
import mimetypes

app = Flask(__name__)

app.jinja_env.block_start_string = '{%%'  # 修改块开始符号
app.jinja_env.block_end_string = '%%}'  # 修改块结束符号
app.jinja_env.variable_start_string = '{{{'  # 修改变量开始符号
app.jinja_env.variable_end_string = '}}}'  # 修改变量结束符号
app.jinja_env.comment_start_string = '##}'  # 修改注释开始符号
app.jinja_env.comment_end_string = '##}'  # 修改注释结束符号复制代码

@app.route('/')
def index():
    return render_template('Pear-Admin-Layui-main/index.html')

@app.route("/")
def get_staticfile(path):
    directory = os.getcwd() + "/templates/Pear-Admin-Layui-main/"
    print(directory)
    response = make_response(send_from_directory(directory, path.encode('utf-8').decode('utf-8'), as_attachment=False))
    mime_type = mimetypes.guess_type(path)[0]
    if path.endswith(".js") :
       mime_type = "application/javascript"
    response.headers['Content-Type'] = mime_type
    print(directory, path, mime_type)
    return response

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')
    #
 
if __name__ == '__main__':
   app.run(debug = True)
  • 运行结果:

6、Flask测试网页(其他)

6.1 基于vue的考试题目列表的网页

  • test_vue.py:
#***************************************************************
#   Purpose:   基于vue的考试题目列表的网页(Flask的web服务器)
#   Author:    爱看书的小沐
#   Date:      2022-5-30
#   Languages: python
#   Platform:  python 3.9 win64
#   OS:        Win10 win64
# **************************************************************
import sqlite3,os
from flask import Flask
from flask import jsonify,render_template,send_from_directory
from flask_cors import CORS

app = Flask(__name__)

# CORS(app, supports_credentials=True)    #解决跨域问题
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})   #两种模式都行

@app.route('/')
def home():
    return render_template('test_vue.html',title='flask + vue example')

@app.route('/api/questions')
def get_questions():
    db_path = os.getcwd() + "/static/exam.db"
    conn = sqlite3.connect( db_path )
    conn.row_factory = sqlite3.Row
    cur = conn.cursor()
    # sql = 'select * from questions'
    sql = 'SELECT * from questions ORDER BY RANDOM () LIMIT 100'
    rows = cur.execute(sql).fetchall()
    rows = [dict(row) for row in rows]
    return jsonify(rows)

@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, 'static'), 'favicon.ico'
        , mimetype='image/vnd.microsoft.icon')

if __name__ == "__main__":
    app.run(debug=True, port=5000)
  • 运行结果:
    【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第15张图片

亲,相关功能正在建设中,请稍等。。。
【Web开发】Python实现Web服务器(Flask测试,cesium.js/echarts.js/three.js)_第16张图片

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!



在这里插入图片描述

你可能感兴趣的:(Python,Web,python,flask,前端,three,layui)