|
@ -54,21 +54,115 @@ |
|
|
Your Statistics |
|
|
Your Statistics |
|
|
</h1> |
|
|
</h1> |
|
|
|
|
|
|
|
|
|
|
|
<button class="float-right" @click="captureGraphics()">Screenshot</button> |
|
|
|
|
|
|
|
|
<!-- Another place to play with the sizing is in Resizer.setSize --> |
|
|
<!-- Another place to play with the sizing is in Resizer.setSize --> |
|
|
<div id="scene-container" class="h-screen"></div> |
|
|
<div id="scene-container" class="h-screen"></div> |
|
|
</section> |
|
|
</section> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script lang="ts"> |
|
|
<script lang="ts"> |
|
|
|
|
|
import { SVGRenderer } from "three/addons/renderers/SVGRenderer.js"; |
|
|
import { Component, Vue } from "vue-facing-decorator"; |
|
|
import { Component, Vue } from "vue-facing-decorator"; |
|
|
import { World } from "@/components/World/World.js"; |
|
|
import { World } from "@/components/World/World.js"; |
|
|
|
|
|
|
|
|
@Component |
|
|
@Component |
|
|
export default class StatisticsView extends Vue { |
|
|
export default class StatisticsView extends Vue { |
|
|
|
|
|
world: World; |
|
|
|
|
|
|
|
|
mounted() { |
|
|
mounted() { |
|
|
const container = document.querySelector("#scene-container"); |
|
|
const container = document.querySelector("#scene-container"); |
|
|
const world = new World(container); |
|
|
const newWorld = new World(container); |
|
|
world.start(); |
|
|
newWorld.start(); |
|
|
|
|
|
this.world = newWorld; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public captureGraphics() { |
|
|
|
|
|
/** |
|
|
|
|
|
// from https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#examples |
|
|
|
|
|
// Adds a blank image |
|
|
|
|
|
const dataBlob = document |
|
|
|
|
|
.querySelector("#scene-container") |
|
|
|
|
|
.firstChild.toBlob((blob) => { |
|
|
|
|
|
const newImg = document.createElement("img"); |
|
|
|
|
|
const url = URL.createObjectURL(blob); |
|
|
|
|
|
|
|
|
|
|
|
newImg.onload = () => { |
|
|
|
|
|
// no longer need to read the blob so it's revoked |
|
|
|
|
|
URL.revokeObjectURL(url); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
newImg.src = url; |
|
|
|
|
|
document.body.appendChild(newImg); |
|
|
|
|
|
}); |
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
// Yields a blank page with the iframe below |
|
|
|
|
|
const dataUrl = document |
|
|
|
|
|
.querySelector("#scene-container") |
|
|
|
|
|
.firstChild.toDataURL("image/png"); |
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
// Yields a blank page with the iframe below |
|
|
|
|
|
const dataUrl = this.world.renderer.domElement.toDataURL("image/png"); |
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
// Show the image in a new tab |
|
|
|
|
|
const iframe = ` |
|
|
|
|
|
<iframe |
|
|
|
|
|
src="${dataUrl}" |
|
|
|
|
|
frameborder="0" |
|
|
|
|
|
style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" |
|
|
|
|
|
allowfullscreen> |
|
|
|
|
|
</iframe>`; |
|
|
|
|
|
const win = window.open(); |
|
|
|
|
|
win.document.open(); |
|
|
|
|
|
win.document.write(iframe); |
|
|
|
|
|
win.document.close(); |
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
|
|
|
|
// from https://stackoverflow.com/a/17407392/845494 |
|
|
|
|
|
// This yields a file with funny formatting. |
|
|
|
|
|
//const image = const dataUrl.replace("image/png", "image/octet-stream"); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
// Yields a blank image at the bottom of the page |
|
|
|
|
|
// from https://discourse.threejs.org/t/save-screenshot-on-server/39900/3 |
|
|
|
|
|
const img = new Image(); |
|
|
|
|
|
img.src = this.world.renderer.domElement.toDataURL(); |
|
|
|
|
|
document.body.appendChild(img); |
|
|
|
|
|
**/ |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* This yields an SVG that only shows white and black highlights |
|
|
|
|
|
// from https://stackoverflow.com/questions/27632621/exporting-from-three-js-scene-to-svg-or-other-vector-format |
|
|
|
|
|
**/ |
|
|
|
|
|
const rendererSVG = new SVGRenderer(); |
|
|
|
|
|
rendererSVG.setSize(window.innerWidth, window.innerHeight); |
|
|
|
|
|
rendererSVG.render(this.world.scene, this.world.camera); |
|
|
|
|
|
//document.body.appendChild(rendererSVG.domElement); |
|
|
|
|
|
ExportToSVG(rendererSVG, "test.svg"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function ExportToSVG(rendererSVG, filename) { |
|
|
|
|
|
const XMLS = new XMLSerializer(); |
|
|
|
|
|
const svgfile = XMLS.serializeToString(rendererSVG.domElement); |
|
|
|
|
|
const svgData = svgfile; |
|
|
|
|
|
const preface = '<?xml version="1.0" standalone="no"?>\r\n'; |
|
|
|
|
|
const svgBlob = new Blob([preface, svgData], { |
|
|
|
|
|
type: "image/svg+xml;charset=utf-8", |
|
|
|
|
|
}); |
|
|
|
|
|
const svgUrl = URL.createObjectURL(svgBlob); |
|
|
|
|
|
const downloadLink = document.createElement("a"); |
|
|
|
|
|
|
|
|
|
|
|
downloadLink.href = svgUrl; |
|
|
|
|
|
downloadLink.download = filename; |
|
|
|
|
|
document.body.appendChild(downloadLink); |
|
|
|
|
|
downloadLink.click(); |
|
|
|
|
|
document.body.removeChild(downloadLink); |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|