这篇笔记详细说明了vtk.js项目是如何搭建的,旨在快速入手工程搭建,享受web vtk的快乐人生。
一.环境
首先,我们需要安装js的运行环境Node.js和npm:
从Node.js官网可以看到目前最新的版本是15.4.0,为了兼容,我们就选择推荐的14.15.1版本。
在Windows上安装需选择全部组件,包括Add to PATH.
安装完成后,可通过node -v命令查看结果:
$ node -v
v14.15.1
npm, node package manager, 即Node.js的包管理器。这个东西很强大,它在Node.js安装的时候就顺带安装好了,也可以通过npm -v命令查看:
$ npm -v
6.14.8
二.创建
Ok, 接下来我们来创建一个工程,看看它的结构如何。
1.创建工程主目录
$ mkdir MyVtkWebDemo
$ cd MyVtkWebDemo/
2.初始化
$ npm init
$ npm install vtk.js –save
可通过命令查看包详细信息:
$ npm info vtk.js
$ npm install –save-dev webpack
查看包信息:
$ npm info webpack
从这里可以看出,webpack的版本为5.10.0,那还需要安装CLI:
$ npm install –save-dev webpack-cli
5.新建./webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| var path = require('path'); var webpack = require('webpack'); var vtkRules = require('vtk.js/Utilities/config/dependency.js').webpack.core.rules;
var entry = path.join(__dirname, './src/index.js'); const sourcePath = path.join(__dirname, './src'); const outputPath = path.join(__dirname, './dist');
module.exports = { entry, output: { path: outputPath, filename: 'MyWebApp.js', }, module: { rules: [ { test: /\.html$/, loader: 'html-loader' }, ].concat(vtkRules), }, resolve: { modules: [ path.resolve(__dirname, 'node_modules'), sourcePath, ], }, };
|
6.修改package.json
将scripts
1 2 3
| "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }
|
替换为
1 2 3 4 5 6 7
| "scripts": { "build": "webpack --config webpack.config.js", "build:release": "webpack --progress --colors --mode production", "start": "webpack serve --content-base ./dist", "commit": "git cz", "semantic-release": "semantic-release" }
|
7.创建应用实例
./src/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor'; import vtkCalculator from 'vtk.js/Sources/Filters/General/Calculator'; import vtkConeSource from 'vtk.js/Sources/Filters/Sources/ConeSource'; import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; import { AttributeTypes } from 'vtk.js/Sources/Common/DataModel/DataSetAttributes/Constants'; import { FieldDataTypes } from 'vtk.js/Sources/Common/DataModel/DataSet/Constants';
import controlPanel from './controller.html';
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance(); const renderer = fullScreenRenderer.getRenderer(); const renderWindow = fullScreenRenderer.getRenderWindow();
const coneSource = vtkConeSource.newInstance({ height: 1.0 }); const filter = vtkCalculator.newInstance();
filter.setInputConnection(coneSource.getOutputPort()); filter.setFormula({ getArrays: inputDataSets => ({ input: [], output: [ { location: FieldDataTypes.CELL, name: 'Random', dataType: 'Float32Array', attribute: AttributeTypes.SCALARS }, ], }), evaluate: (arraysIn, arraysOut) => { const [scalars] = arraysOut.map(d => d.getData()); for (let i = 0; i < scalars.length; i++) { scalars[i] = Math.random(); } }, });
const mapper = vtkMapper.newInstance(); mapper.setInputConnection(filter.getOutputPort());
const actor = vtkActor.newInstance(); actor.setMapper(mapper);
renderer.addActor(actor); renderer.resetCamera(); renderWindow.render();
fullScreenRenderer.addController(controlPanel); const representationSelector = document.querySelector('.representations'); const resolutionChange = document.querySelector('.resolution');
representationSelector.addEventListener('change', (e) => { const newRepValue = Number(e.target.value); actor.getProperty().setRepresentation(newRepValue); renderWindow.render(); });
resolutionChange.addEventListener('input', (e) => { const resolution = Number(e.target.value); coneSource.setResolution(resolution); renderWindow.render(); });
|
8.控制模板
./src/controller.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <table> <tr> <td> <select class='representations' style="width: 100%"> <option value='0'>Points</option> <option value='1'>Wireframe</option> <option value='2' selected>Surface</option> </select> </td> </tr> <tr> <td> <input class='resolution' type='range' min='4' max='80' value='6' /> </td> </tr> </table>
|
9.用于加载生成的应用程序的主web页面
./dist/index.html
1 2 3 4 5 6 7 8 9 10
| <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <script type="text/javascript" src="MyWebApp.js"></script> </body> </html>
|
三. 编译
到这里,我们就可以编译工程了。
$ npm run build
看看./dist下面是否生成了应用文件。
$ ll dist/
四. 启动
最后,完事具备,只欠东风。
$ npm start
五.效果
有浏览器打开**http://localhost:8080/**,就可以看结果了。此时此刻,此情此景,你可以加个鸡腿了!
Ref
Using vtk.js as an ES6 dependency