@z3dev Thank you for your help, good news! I successfully built a model display system using vue+JSCAD. It can directly display .dxf files. But I was frustrated to find that my system cannot display 2D graphics.
When did I have a problem because the system has no abnormal information. 2D files can also be successfully compiled, that is, there is no display on the canvas.
My key is to be consistent with the key code in vue-components. I didn't use vue-components directly, and I can also key code on the basis of vue.
export default {
name: 'cad-viewer',
props: {
solids: {
type: Array,
},
grid: {
type: Object,
},
axis: {
type: Object,
},
cameraPosition: {
type: Array,
default: () => [150, -180, 233],
},
},
data() {
return {
render: () => {},
updateView: true,
rotateDelta: [0, 0],
panDelta: [0, 0],
zoomDelta: 0,
zoom2Fit: false,
mouse: {
buttons: 0,
shiftKey: false,
isOrbiting: false,
lastClick: 0,
lastZoom: 0,
},
controls: orbitControls.defaults,
camera: {
...perspectiveCamera.defaults,
position: this.cameraPosition,
},
}
},
computed: {
gridOptions() {
const {
show = false,
color = [0, 0, 0, 1],
subColor = [0, 0, 1, 0.5],
fadeOut = false,
transparent = false,
size = [200, 200],
ticks = [50, 5],
} = this.grid
return {
visuals: {
drawCmd: 'drawGrid',
show,
color,
subColor,
fadeOut,
transparent,
},
size,
ticks,
}
},
axisOptions() {
const { show = true } = this.axis
return {
visuals: {
drawCmd: 'drawAxis',
show,
},
}
},
content() {
return {
camera: this.camera,
drawCommands: {
drawGrid: drawCommands.drawGrid,
drawAxis: drawCommands.drawAxis,
drawMesh: drawCommands.drawMesh,
},
entities: [this.gridOptions, this.axisOptions, ...this.solids],
}
},
},
watch: {
solids() {
this.updateView = true
},
grid() {
this.updateView = true
},
cameraPosition(position) {
this.camera.position = position
this.updateView = true
},
},
created() {
numberOfInstances++
this.id = numberOfInstances
},
mounted() {
this.initializeRenderer()
},
methods: {
initializeRenderer() {
this.$el.id = `viewer${this.id}`
const width = this.$el.clientWidth
const height = this.$el.clientHeight
perspectiveCamera.setProjection(this.camera, this.camera, {
width,
height,
})
perspectiveCamera.update(this.camera, this.camera)
const setupOptions = {
glOptions: { container: this.$el },
}
this.renderer = prepareRender(setupOptions)
window.addEventListener('resize', () => {
this.updateView = true
})
window.requestAnimationFrame(this.updateAndRender)
},
updateAndRender() {
this.doRotatePanZoom()
if (this.updateView) {
const updates = orbitControls.update({
controls: this.controls,
camera: this.camera,
})
this.controls = { ...this.controls, ...updates.controls }
this.updateView = this.controls.changed
this.camera.position = updates.camera.position
perspectiveCamera.update(this.camera)
this.resize()
const { content } = this
content.entities = content.entities
.reduce((pre, cur) => {
if (!cur.visuals) {
pre.push(...entitiesFromSolids({}, cur))
}
pre.push(cur)
return pre
}, [])
.filter((item) => item.visuals)
this.renderer(content)
}
window.requestAnimationFrame(this.updateAndRender)
},
doRotatePanZoom() {
let {
rotateDelta,
panDelta,
zoomDelta,
zoom2Fit,
controls,
camera,
content,
} = this
if (rotateDelta[0] || rotateDelta[1]) {
const updated = orbitControls.rotate(
{ controls, camera, speed: rotateSpeed },
rotateDelta
)
this.controls = { ...controls, ...updated.controls }
this.rotateDelta = [0, 0]
this.updateView = true
}
if (panDelta[0] || panDelta[1]) {
const updated = orbitControls.pan(
{ controls, camera, speed: panSpeed },
panDelta
)
this.camera.position = updated.camera.position
this.camera.target = updated.camera.target
this.panDelta = [0, 0]
this.updateView = true
}
if (zoomDelta) {
const updated = orbitControls.zoom(
{ controls, camera, speed: zoomSpeed },
zoomDelta
)
this.controls = { ...controls, ...updated.controls }
this.zoomDelta = 0
this.updateView = true
}
if (zoom2Fit) {
controls.zoomToFit.tightness = 2
const updated = orbitControls.zoomToFit({
controls,
camera,
entities: content.entities.filter((entity) => entity.geometry),
})
this.controls = { ...controls, ...updated.controls }
this.zoom2Fit = false
this.updateView = true
}
},
resize() {
const pixelRatio = window.devicePixelRatio || 1
const bounds = this.$el.getBoundingClientRect()
const width = (bounds.right - bounds.left) * pixelRatio
const height = (bounds.bottom - bounds.top) * pixelRatio
const prevWidth = this.$el.width
const prevHeight = this.$el.height
if (prevWidth !== width || prevHeight !== height) {
this.$el.width = width
this.$el.height = height
perspectiveCamera.setProjection(this.camera, this.camera, {
width,
height,
})
perspectiveCamera.update(this.camera, this.camera)
this.updateView = true
}
},
onMouseDown(event) {
const { mouse } = this
mouse.buttons = event.buttons
mouse.shiftKey = event.shiftKey
mouse.isOrbiting = true
},
onMouseUp() {
const now = Date.now()
const { mouse } = this
if (mouse.lastClick) {
const ms = now - mouse.lastClick
if (ms < doubleClickSpeed) {
if (mouse.isOrbiting) {
this.zoom2Fit = true
}
}
}
mouse.lastClick = now
mouse.buttons = 0
mouse.shiftKey = false
mouse.isOrbiting = false
},
onMouseMove(event) {
const { mouse, panDelta, rotateDelta } = this
if (mouse.isOrbiting) {
if (mouse.shiftKey) {
panDelta[0] -= event.movementX
panDelta[1] += event.movementY
} else {
rotateDelta[0] += event.movementX
rotateDelta[1] -= event.movementY
}
}
},
onScroll(event) {
event.preventDefault()
this.zoomDelta = event.deltaY
},
},
}