|
@@ -1,77 +1,28 @@
|
|
|
-import { Input, Modal } from 'antd'
|
|
|
-import { useEffect, useRef, useState } from 'react'
|
|
|
+import { Input, Modal, Transfer } from 'antd'
|
|
|
+import { useEffect, useMemo, useRef, useState } from 'react'
|
|
|
import AMapLoader from '@amap/amap-jsapi-loader';
|
|
|
import style from './style.module.scss'
|
|
|
-// import html2canvas from 'html2canvas'
|
|
|
import { SceneType, SceneTypeDomain, SceneTypePaths } from 'constant';
|
|
|
-import { getHref } from 'utils';
|
|
|
+import { base64ToBlob, getHref } from 'utils';
|
|
|
import { asyncLoading } from 'components/loading';
|
|
|
+import { RedoOutlined } from '@ant-design/icons';
|
|
|
+import { fetchTaggings } from 'api'
|
|
|
|
|
|
+import type { Tagging } from 'api'
|
|
|
|
|
|
-const domScreenshot = async (dom: HTMLElement, foreignObjectRendering: boolean) => {
|
|
|
+const domScreenshot = async (dom: HTMLElement) => {
|
|
|
const canvas = (dom.tagName.toUpperCase() === 'CANVAS' ? dom : dom.querySelector('canvas')) as HTMLCanvasElement
|
|
|
return new Promise<Blob | null>(resolve => {
|
|
|
if (!canvas) {
|
|
|
- resolve(null)
|
|
|
+ return resolve(null)
|
|
|
}
|
|
|
- canvas.toBlob((blob) => {
|
|
|
- console.log(blob)
|
|
|
- if (blob) {
|
|
|
- window.open(URL.createObjectURL(blob))
|
|
|
- }
|
|
|
- resolve(blob)
|
|
|
- })
|
|
|
+ canvas.toBlob(resolve)
|
|
|
})
|
|
|
- // const imgs = Array.from(dom.querySelectorAll('img'))
|
|
|
- // try {
|
|
|
- // await Promise.all(
|
|
|
- // imgs.map(img => {
|
|
|
- // if (!img.src) {
|
|
|
- // return null;
|
|
|
- // }
|
|
|
- // const req = fetch(img.src, {
|
|
|
- // method: 'get'
|
|
|
- // })
|
|
|
- // return req
|
|
|
- // .then(res => res.blob())
|
|
|
- // .then(blob => {
|
|
|
- // const render = new FileReader()
|
|
|
- // return new Promise<void>(resolve => {
|
|
|
- // render.onload = e => {
|
|
|
- // if (e.target?.result) {
|
|
|
- // img.src = e.target?.result as string
|
|
|
- // }
|
|
|
- // resolve()
|
|
|
- // }
|
|
|
- // render.readAsDataURL(blob)
|
|
|
- // })
|
|
|
- // })
|
|
|
- // })
|
|
|
- // )
|
|
|
- // } catch {
|
|
|
- // }
|
|
|
-
|
|
|
- // const canvas = await html2canvas(dom, {
|
|
|
- // allowTaint: true,
|
|
|
- // useCORS: true,
|
|
|
- // imageTimeout: 0,
|
|
|
- // removeContainer: false,
|
|
|
- // foreignObjectRendering,
|
|
|
- // width: dom.offsetWidth,
|
|
|
- // height: dom.offsetHeight
|
|
|
- // })
|
|
|
-
|
|
|
- // return new Promise<Blob | null>(resolve => {
|
|
|
- // canvas.toBlob((blob) => {
|
|
|
- // resolve(blob)
|
|
|
- // })
|
|
|
- // })
|
|
|
}
|
|
|
|
|
|
-
|
|
|
type SelectImageProps = {
|
|
|
onClose: () => void
|
|
|
- onSave: (url: Blob) => void
|
|
|
+ onSave: (url: Blob | null, tagging: Tagging[]) => void
|
|
|
}
|
|
|
|
|
|
|
|
@@ -93,11 +44,9 @@ export const SelectMap = (props: SelectImageProps) => {
|
|
|
|
|
|
const onSubmit = async () => {
|
|
|
if (mapEle.current) {
|
|
|
- const blob = await domScreenshot(mapEle.current, false)
|
|
|
- if (blob) {
|
|
|
- await props.onSave(blob)
|
|
|
- setOpen(false)
|
|
|
- }
|
|
|
+ const blob = await domScreenshot(mapEle.current)
|
|
|
+ await props.onSave(blob, [])
|
|
|
+ setOpen(false)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -180,42 +129,72 @@ export const SelectMap = (props: SelectImageProps) => {
|
|
|
const getFuseUrl = (caseId: number) =>
|
|
|
`${getHref(SceneTypeDomain[SceneType.SWMX]!, SceneTypePaths[SceneType.SWMX][0], { caseId: caseId.toString() })}&share=1#show/summary`
|
|
|
|
|
|
-export const SelectFuse = (props: SelectImageProps & {caseId: number}) => {
|
|
|
- const url = getFuseUrl(props.caseId)
|
|
|
+
|
|
|
+const getFuseImage = async (iframe: HTMLIFrameElement) => {
|
|
|
+ const iframeElement = iframe.contentWindow?.document.documentElement
|
|
|
+ if (!iframeElement) {
|
|
|
+ return null
|
|
|
+ }
|
|
|
+ const extIframe = iframeElement.querySelector('.external') as HTMLIFrameElement
|
|
|
+ const targetIframe = extIframe || iframe
|
|
|
+ const targetWindow: any = targetIframe.contentWindow
|
|
|
+ const fuseCnavas = targetWindow.document.querySelector('.scene-canvas > canvas') as HTMLElement
|
|
|
+
|
|
|
+ if (fuseCnavas) {
|
|
|
+ return domScreenshot(fuseCnavas)
|
|
|
+ }
|
|
|
+ const isLaser = targetWindow.document.querySelector('.laser-layer')
|
|
|
+
|
|
|
+ if (isLaser) {
|
|
|
+ const sdk = await targetWindow.__sdk
|
|
|
+ return new Promise<Blob | null>(resolve => {
|
|
|
+ sdk.scene.screenshot(900, 900).done((data: string) => {
|
|
|
+ resolve(base64ToBlob(data))
|
|
|
+ })
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ const sdk = targetWindow.__sdk
|
|
|
+ return new Promise<Blob | null>(resolve => {
|
|
|
+ sdk.Camera.screenshot([ {width: 2048, height: 1024, name: '2k' }],false).then((result: any)=>{
|
|
|
+ resolve(base64ToBlob(result[0].data))
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+export const SelectFuse = (props: SelectImageProps & { caseId: number }) => {
|
|
|
const [open, setOpen] = useState(true)
|
|
|
+ const [blob, setBlob] = useState<Blob | null>(null)
|
|
|
+ const [tags, setTags] = useState<Tagging[]>([])
|
|
|
+ const [selectTags, setSelectTags] = useState<string[]>([])
|
|
|
+ const [addTags, setAddTags] = useState<string[]>([])
|
|
|
const iframeRef = useRef<HTMLIFrameElement>(null)
|
|
|
+ const coverUrl = useMemo(() => blob && URL.createObjectURL(blob), [blob])
|
|
|
+ const url = useMemo(() => getFuseUrl(props.caseId), [props.caseId])
|
|
|
+ const mockData = useMemo(() => tags.map(tag => ({
|
|
|
+ data: tag,
|
|
|
+ key: tag.tagId.toString()
|
|
|
+ })), [tags])
|
|
|
+
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ fetchTaggings(props.caseId.toString()).then(setTags)
|
|
|
+ }, [props.caseId])
|
|
|
|
|
|
const onSubmit = async () => {
|
|
|
- if (iframeRef.current?.contentWindow) {
|
|
|
- const iframeElement = iframeRef.current.contentWindow.document.documentElement
|
|
|
-
|
|
|
- let fuseBody: Element | null = null
|
|
|
- if (!fuseBody) {
|
|
|
- const iframe = iframeElement.querySelector('.external') as HTMLIFrameElement
|
|
|
- const childElement = iframe?.contentWindow?.document.documentElement
|
|
|
- if (childElement) {
|
|
|
- fuseBody = childElement.querySelector('.scene-canvas > canvas') ||
|
|
|
- childElement.querySelector('.player[name="main"] > canvas') ||
|
|
|
- childElement
|
|
|
- }
|
|
|
- console.log(fuseBody)
|
|
|
- }
|
|
|
- if (!fuseBody) {
|
|
|
- fuseBody = iframeElement.querySelector('.scene-canvas > canvas')
|
|
|
- }
|
|
|
- if (fuseBody) {
|
|
|
- const blob = await domScreenshot(fuseBody as HTMLElement, true)
|
|
|
- if (blob) {
|
|
|
- window.open(URL.createObjectURL(blob))
|
|
|
- // setOpen(false)
|
|
|
- }
|
|
|
- }
|
|
|
+ props.onSave(blob, tags.filter(tag => addTags.includes(tag.tagId.toString())))
|
|
|
+ }
|
|
|
+ const getCover = async () => {
|
|
|
+ if (iframeRef.current) {
|
|
|
+ const blob = await getFuseImage(iframeRef.current)
|
|
|
+ setBlob(blob)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
<Modal
|
|
|
- width="700px"
|
|
|
+ width="1060px"
|
|
|
title="选择户型图"
|
|
|
open={open}
|
|
|
onCancel={() => setOpen(false)}
|
|
@@ -224,8 +203,32 @@ export const SelectFuse = (props: SelectImageProps & {caseId: number}) => {
|
|
|
okText="确定"
|
|
|
cancelText="取消"
|
|
|
>
|
|
|
- <div className={style['iframe-layout']}>
|
|
|
- <iframe src={url} ref={iframeRef} title="fuce-code" />
|
|
|
+ <div className={style['house-layout']}>
|
|
|
+ <div className={style['iframe-layout']}>
|
|
|
+ <iframe src={url} ref={iframeRef} title="fuce-code" />
|
|
|
+ </div>
|
|
|
+ <div className={style['content-layout']}>
|
|
|
+ <div className={style['house-tags']}>
|
|
|
+ <h4>请选择要同步到现场图的标注:</h4>
|
|
|
+ <div className={style['tagging-transfer']}>
|
|
|
+ <Transfer
|
|
|
+ dataSource={mockData}
|
|
|
+ titles={['所有', '需要']}
|
|
|
+ targetKeys={addTags}
|
|
|
+ selectedKeys={selectTags}
|
|
|
+ onChange={setAddTags}
|
|
|
+ onSelectChange={(sKeys, tKeys) => setSelectTags([...sKeys, ...tKeys])}
|
|
|
+ render={(item) => item.data.tagTitle}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <h4>户型图:<RedoOutlined className='icon' onClick={getCover} /></h4>
|
|
|
+ <div className={style['house-image']}>
|
|
|
+ { coverUrl && <img src={coverUrl} alt="预览图" /> }
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</Modal>
|
|
|
)
|