<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link href='http://bigemap.com:9000/bigemap-gl.js/v1.1.0/Widgets/widgets.css' rel='stylesheet' /> <script src='http://bigemap.com:9000/bigemap-gl.js/v1.1.0/bigemap-gl.js'></script> <script src='./templates/bmgl-header.js'></script> </head> <style> * { margin: 0; padding: 0; } #container { position: absolute; top: 0; bottom: 0; width: 100%; } #toolbar { position: absolute; background: rgba(212, 212, 212, 0.8); padding: 4px; border-radius: 4px; } #toolbar input { vertical-align: middle; padding-top: 2px; padding-bottom: 2px; } #toolbar .header { font-weight: bold; } </style> <body> <div id="container"></div> <div id="loadingOverlay"> <h1>Loading...</h1> </div> <div id="toolbar"> <table> <tbody> <tr> <td>烟雾速率</td> <td> <input type="range" min="0.0" max="100.0" step="1" data-bind="value: emissionRate, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: emissionRate"> </td> </tr> <tr> <td>烟雾尺寸大小</td> <td> <input type="range" min="2" max="60.0" step="1" data-bind="value: particleSize, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: particleSize"> </td> </tr> <tr> <td>最小存在时间</td> <td> <input type="range" min="0.1" max="30.0" step="1" data-bind="value: minimumParticleLife, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: minimumParticleLife"> </td> </tr> <tr> <td>最大存在时间</td> <td> <input type="range" min="0.1" max="30.0" step="1" data-bind="value: maximumParticleLife, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: maximumParticleLife"> </td> </tr> <tr> <td>最小速率</td> <td> <input type="range" min="0.0" max="30.0" step="1" data-bind="value: minimumSpeed, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: minimumSpeed"> </td> </tr> <tr> <td>最大速率</td> <td> <input type="range" min="0.0" max="30.0" step="1" data-bind="value: maximumSpeed, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: maximumSpeed"> </td> </tr> <tr> <td>开始的大小</td> <td> <input type="range" min="0.0" max="10.0" step="1" data-bind="value: startScale, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: startScale"> </td> </tr> <tr> <td>结束时的大小</td> <td> <input type="range" min="0.0" max="10.0" step="1" data-bind="value: endScale, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: endScale"> </td> </tr> <tr> <td>重力</td> <td> <input type="range" min="-20.0" max="20.0" step="1" data-bind="value: gravity, valueUpdate: 'input'"> <input type="text" size="5" data-bind="value: gravity"> </td> </tr> </tbody> </table> </div> </body> <script> bmgl.Config.HTTP_URL = 'http://bigemap.com:9000'; var viewer = new bmgl.Viewer('container', { timeline: true, fullscreenButton: true, mapId: 'bigemap.zhongkexingtu', }); bmgl.Math.setRandomNumberSeed(3); //添加时间控件 //Set bounds of our simulation time var start = bmgl.JulianDate.fromDate(new Date(2015, 2, 25, 16)); var stop = bmgl.JulianDate.addSeconds( start, 120, new bmgl.JulianDate() ); //Make sure viewer is at the desired time. viewer.clock.startTime = start.clone(); viewer.clock.stopTime = stop.clone(); viewer.clock.currentTime = start.clone(); viewer.clock.clockRange = bmgl.ClockRange.LOOP_STOP; //Loop at the end viewer.clock.multiplier = 1; viewer.clock.shouldAnimate = true; //Set timeline to simulation bounds viewer.timeline.zoomTo(start, stop); //绑定数据 var viewModel = { emissionRate: 5.0, gravity: 0.0, minimumParticleLife: 1.2, maximumParticleLife: 1.2, minimumSpeed: 1.0, maximumSpeed: 4.0, startScale: 1.0, endScale: 5.0, particleSize: 25.0, }; bmgl.knockout.track(viewModel); var toolbar = document.getElementById("toolbar"); bmgl.knockout.applyBindings(viewModel, toolbar); var entityPosition = new bmgl.Cartesian3(); var entityOrientation = new bmgl.Quaternion(); var rotationMatrix = new bmgl.Matrix3(); var modelMatrix = new bmgl.Matrix4(); function computeModelMatrix(entity, time) { return entity.computeModelMatrix(time, new bmgl.Matrix4()); } var emitterModelMatrix = new bmgl.Matrix4(); var translation = new bmgl.Cartesian3(); var rotation = new bmgl.Quaternion(); var hpr = new bmgl.HeadingPitchRoll(); var trs = new bmgl.TranslationRotationScale(); function computeEmitterModelMatrix() { hpr = bmgl.HeadingPitchRoll.fromDegrees(0.0, 0.0, 0.0, hpr); trs.translation = bmgl.Cartesian3.fromElements( -4.0, 0.0, 1.4, translation ); trs.rotation = bmgl.Quaternion.fromHeadingPitchRoll(hpr, rotation); return bmgl.Matrix4.fromTranslationRotationScale( trs, emitterModelMatrix ); } var pos1 = bmgl.Cartesian3.fromDegrees( -75.15787310614596, 39.97862668312678 ); var pos2 = bmgl.Cartesian3.fromDegrees( -75.1633691390455, 39.95355089912078 ); var position = new bmgl.SampledPositionProperty(); position.addSample(start, pos1); position.addSample(stop, pos2); var entity = viewer.entities.add({ availability: new bmgl.TimeIntervalCollection([ new bmgl.TimeInterval({ start: start, stop: stop, }), ]), model: { uri: "/templates/glb/bmglMilkTruck.glb", minimumPixelSize: 64, }, viewFrom: new bmgl.Cartesian3(-100.0, 0.0, 100.0), position: position, orientation: new bmgl.VelocityOrientationProperty(position), }); viewer.trackedEntity = entity; var scene = viewer.scene; var particleSystem = scene.primitives.add( new bmgl.ParticleSystem({ image: "/templates/img/smoke.png", startColor: bmgl.Color.LIGHTSEAGREEN.withAlpha(0.7), endColor: bmgl.Color.WHITE.withAlpha(0.0), startScale: viewModel.startScale, endScale: viewModel.endScale, minimumParticleLife: viewModel.minimumParticleLife, maximumParticleLife: viewModel.maximumParticleLife, minimumSpeed: viewModel.minimumSpeed, maximumSpeed: viewModel.maximumSpeed, imageSize: new bmgl.Cartesian2( viewModel.particleSize, viewModel.particleSize ), emissionRate: viewModel.emissionRate, bursts: [ // these burst will occasionally sync to create a multicolored effect new bmgl.ParticleBurst({ time: 5.0, minimum: 10, maximum: 100, }), new bmgl.ParticleBurst({ time: 10.0, minimum: 50, maximum: 100, }), new bmgl.ParticleBurst({ time: 15.0, minimum: 200, maximum: 300, }), ], lifetime: 16.0, emitter: new bmgl.CircleEmitter(2.0), emitterModelMatrix: computeEmitterModelMatrix(), updateCallback: applyGravity, }) ); var gravityScratch = new bmgl.Cartesian3(); function applyGravity(p, dt) { // We need to compute a local up vector for each particle in geocentric space. var position = p.position; bmgl.Cartesian3.normalize(position, gravityScratch); bmgl.Cartesian3.multiplyByScalar( gravityScratch, viewModel.gravity * dt, gravityScratch ); p.velocity = bmgl.Cartesian3.add( p.velocity, gravityScratch, p.velocity ); } viewer.scene.preUpdate.addEventListener(function (scene, time) { particleSystem.modelMatrix = computeModelMatrix(entity, time); // Account for any changes to the emitter model matrix. particleSystem.emitterModelMatrix = computeEmitterModelMatrix(); // Spin the emitter if enabled. if (viewModel.spin) { viewModel.heading += 1.0; viewModel.pitch += 1.0; viewModel.roll += 1.0; } }); bmgl.knockout .getObservable(viewModel, "emissionRate") .subscribe(function (newValue) { particleSystem.emissionRate = parseFloat(newValue); }); bmgl.knockout .getObservable(viewModel, "particleSize") .subscribe(function (newValue) { var particleSize = parseFloat(newValue); particleSystem.minimumImageSize.x = particleSize; particleSystem.minimumImageSize.y = particleSize; particleSystem.maximumImageSize.x = particleSize; particleSystem.maximumImageSize.y = particleSize; }); bmgl.knockout .getObservable(viewModel, "minimumParticleLife") .subscribe(function (newValue) { particleSystem.minimumParticleLife = parseFloat(newValue); }); bmgl.knockout .getObservable(viewModel, "maximumParticleLife") .subscribe(function (newValue) { particleSystem.maximumParticleLife = parseFloat(newValue); }); bmgl.knockout .getObservable(viewModel, "minimumSpeed") .subscribe(function (newValue) { particleSystem.minimumSpeed = parseFloat(newValue); }); bmgl.knockout .getObservable(viewModel, "maximumSpeed") .subscribe(function (newValue) { particleSystem.maximumSpeed = parseFloat(newValue); }); bmgl.knockout .getObservable(viewModel, "startScale") .subscribe(function (newValue) { particleSystem.startScale = parseFloat(newValue); }); bmgl.knockout .getObservable(viewModel, "endScale") .subscribe(function (newValue) { particleSystem.endScale = parseFloat(newValue); }); var options = [ { text: "Circle Emitter", onselect: function () { particleSystem.emitter = new bmgl.CircleEmitter(2.0); }, }, { text: "Sphere Emitter", onselect: function () { particleSystem.emitter = new bmgl.SphereEmitter(2.5); }, }, { text: "Cone Emitter", onselect: function () { particleSystem.emitter = new bmgl.ConeEmitter( bmgl.Math.toRadians(45.0) ); }, }, { text: "Box Emitter", onselect: function () { particleSystem.emitter = new bmgl.BoxEmitter( new bmgl.Cartesian3(10.0, 10.0, 10.0) ); }, }, ]; Sandcastle.addToolbarMenu(options); </script> </html>
源码