Autodesk Forge 查看器自定义标记未在查看器上恢复
Autodesk forge viewer custom markup is not restored on viewer
我按照示例创建了自定义标记:
https://forge.autodesk.com/blog/implementing-custom-markups
标记已创建、突出显示和编辑。我们保存有关文档标记的信息并将其发送到服务器。当您打开文档时,原生标记被完美还原 - 编辑、突出显示。但是自定义标记有一个问题——它们显示在文档中,但无法编辑。它们不是供查看者使用的标记。在我看来,这是因为查看者不知道自定义标记的类型(在示例中 this.type = 'smiley';)
如何解决这个问题?谢谢!
我们这样还原标记:
forgeRef.viewer.loadExtension('Autodesk.Viewing.MarkupsCore').then((m: any) => {
setMarkup(m)
const currentMarkup = allMarkupElements.find(item => item.page === activePage)
if (currentMarkup) {
m.show()
m.loadMarkups(currentMarkup.data, 'Layer1')
m.viewer.restoreState(currentMarkup.viewerState, undefined, true)
if (!m.enterEditMode('Layer1')) {
console.error('enter edit mode returns false') // eslint-disable-line
}
} else if (!m.enterEditMode()) {
console.error('enter edit mode returns false') // eslint-disable-line
}
m.allowNavigation(true)
})
事实证明,通过重新初始化自定义标记可以解决问题。
currentMarkup.data 是一个 SVG 字符串,其中包含有关自定义标记的信息。
从这个字符串中,您需要使用解析器提取自定义标记并在没有它的情况下加载标记。然后您需要重新创建您的自定义标记。
之后,自定义标记将出现在查看器上并可以进行编辑。
import { parse, stringify } from 'svgson'
const splitLocationMarkup = async (svgData: string) => {
const parsedSvg = await parse(svgData)
const children = parsedSvg.children.filter(({ name }) => name !== 'metadata')
const location = children.find(
child => child.children[0].children[0].attributes.type === 'location'
)
const childrenWithoutLocation = parsedSvg.children.filter(
child => child.children[0].children[0]?.attributes.type !== 'location'
)
const svgWithoutLocation = stringify({
...parsedSvg,
children: childrenWithoutLocation,
})
return { location, svgWithoutLocation }
}
const initializingLocationMarkup = async (
location: any,
id: number | string,
markupInstance: any
) => {
if (location) {
const locationAttributes = location.children[0].children[0].attributes
const [positionX, positionY] = locationAttributes.position.split(' ').map(Number)
const position = { x: positionX, y: positionY }
const [sizeX, sizeY] = locationAttributes.size.split(' ').map(Number)
const style = {
'fill-color': locationAttributes['fill-color'],
'fill-opacity': locationAttributes['fill-opacity'],
'stroke-color': locationAttributes['stroke-color'],
'stroke-opacity': locationAttributes['stroke-opacity'],
'stroke-width': locationAttributes['stroke-width'],
}
// @ts-ignore
const { MarkupLocation } = await import(
'../../Viewer/CustomMarkups/LocationMarkup/location-markup'
)
const customLocationMarkup = new MarkupLocation(id, markupInstance.editFrame.editor)
// @ts-ignore
customLocationMarkup.setSize(position, sizeX, sizeY)
// @ts-ignore
customLocationMarkup.setStyle(style)
markupInstance.editFrame.editor.addMarkup(customLocationMarkup)
}
}
const handleDocumentLoaded = (doc: any, pages: number) => {
setPagesCount(pages)
if (forgeRef?.viewer) {
forgeRef.viewer.loadExtension('Autodesk.Viewing.MarkupsCore').then(async (m: any) => {
setMarkup(m)
const currentMarkup = allMarkupElements.find(item => item.page === activePage)
if (currentMarkup) {
m.show()
const { location, svgWithoutLocation } = await splitLocationMarkup(currentMarkup.data)
//Loading the markups without custom markup
m.loadMarkups(svgWithoutLocation, 'Layer1')
//Initializing custom markup
initializingLocationMarkup(location, 'location', m)
m.viewer.restoreState(currentMarkup.viewerState, undefined, true)
if (!m.enterEditMode('Layer1')) {
console.error('enter edit mode returns false') // eslint-disable-line
}
} else if (!m.enterEditMode()) {
console.error('enter edit mode returns false') // eslint-disable-line
}
m.allowNavigation(true)
})
}
}
我按照示例创建了自定义标记: https://forge.autodesk.com/blog/implementing-custom-markups
标记已创建、突出显示和编辑。我们保存有关文档标记的信息并将其发送到服务器。当您打开文档时,原生标记被完美还原 - 编辑、突出显示。但是自定义标记有一个问题——它们显示在文档中,但无法编辑。它们不是供查看者使用的标记。在我看来,这是因为查看者不知道自定义标记的类型(在示例中 this.type = 'smiley';)
如何解决这个问题?谢谢!
我们这样还原标记:
forgeRef.viewer.loadExtension('Autodesk.Viewing.MarkupsCore').then((m: any) => {
setMarkup(m)
const currentMarkup = allMarkupElements.find(item => item.page === activePage)
if (currentMarkup) {
m.show()
m.loadMarkups(currentMarkup.data, 'Layer1')
m.viewer.restoreState(currentMarkup.viewerState, undefined, true)
if (!m.enterEditMode('Layer1')) {
console.error('enter edit mode returns false') // eslint-disable-line
}
} else if (!m.enterEditMode()) {
console.error('enter edit mode returns false') // eslint-disable-line
}
m.allowNavigation(true)
})
事实证明,通过重新初始化自定义标记可以解决问题。 currentMarkup.data 是一个 SVG 字符串,其中包含有关自定义标记的信息。 从这个字符串中,您需要使用解析器提取自定义标记并在没有它的情况下加载标记。然后您需要重新创建您的自定义标记。
之后,自定义标记将出现在查看器上并可以进行编辑。
import { parse, stringify } from 'svgson'
const splitLocationMarkup = async (svgData: string) => {
const parsedSvg = await parse(svgData)
const children = parsedSvg.children.filter(({ name }) => name !== 'metadata')
const location = children.find(
child => child.children[0].children[0].attributes.type === 'location'
)
const childrenWithoutLocation = parsedSvg.children.filter(
child => child.children[0].children[0]?.attributes.type !== 'location'
)
const svgWithoutLocation = stringify({
...parsedSvg,
children: childrenWithoutLocation,
})
return { location, svgWithoutLocation }
}
const initializingLocationMarkup = async (
location: any,
id: number | string,
markupInstance: any
) => {
if (location) {
const locationAttributes = location.children[0].children[0].attributes
const [positionX, positionY] = locationAttributes.position.split(' ').map(Number)
const position = { x: positionX, y: positionY }
const [sizeX, sizeY] = locationAttributes.size.split(' ').map(Number)
const style = {
'fill-color': locationAttributes['fill-color'],
'fill-opacity': locationAttributes['fill-opacity'],
'stroke-color': locationAttributes['stroke-color'],
'stroke-opacity': locationAttributes['stroke-opacity'],
'stroke-width': locationAttributes['stroke-width'],
}
// @ts-ignore
const { MarkupLocation } = await import(
'../../Viewer/CustomMarkups/LocationMarkup/location-markup'
)
const customLocationMarkup = new MarkupLocation(id, markupInstance.editFrame.editor)
// @ts-ignore
customLocationMarkup.setSize(position, sizeX, sizeY)
// @ts-ignore
customLocationMarkup.setStyle(style)
markupInstance.editFrame.editor.addMarkup(customLocationMarkup)
}
}
const handleDocumentLoaded = (doc: any, pages: number) => {
setPagesCount(pages)
if (forgeRef?.viewer) {
forgeRef.viewer.loadExtension('Autodesk.Viewing.MarkupsCore').then(async (m: any) => {
setMarkup(m)
const currentMarkup = allMarkupElements.find(item => item.page === activePage)
if (currentMarkup) {
m.show()
const { location, svgWithoutLocation } = await splitLocationMarkup(currentMarkup.data)
//Loading the markups without custom markup
m.loadMarkups(svgWithoutLocation, 'Layer1')
//Initializing custom markup
initializingLocationMarkup(location, 'location', m)
m.viewer.restoreState(currentMarkup.viewerState, undefined, true)
if (!m.enterEditMode('Layer1')) {
console.error('enter edit mode returns false') // eslint-disable-line
}
} else if (!m.enterEditMode()) {
console.error('enter edit mode returns false') // eslint-disable-line
}
m.allowNavigation(true)
})
}
}