Merge branch 'dev' into dev-yj
This commit is contained in:
commit
bab7a1a36d
16
src/app/[locale]/initSettingsModal/page.jsx
Normal file
16
src/app/[locale]/initSettingsModal/page.jsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import Hero from '@/components/Hero'
|
||||||
|
import InitSettingsModal from '@/components/InitSettingsModal'
|
||||||
|
import { initCheck } from '@/util/session-util'
|
||||||
|
|
||||||
|
export default async function InitSettingsModalPage() {
|
||||||
|
await initCheck()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Hero title="Basic Settings" />
|
||||||
|
<div className="flex flex-col justify-center my-8">
|
||||||
|
<InitSettingsModal />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -10,6 +10,7 @@ export default function Headers() {
|
|||||||
<div className="space-x-4 text-xl">
|
<div className="space-x-4 text-xl">
|
||||||
<Link href="/intro">Intro</Link>
|
<Link href="/intro">Intro</Link>
|
||||||
<Link href="/playground">Playground</Link>
|
<Link href="/playground">Playground</Link>
|
||||||
|
<Link href="/initSettingsModal">Basic Settings</Link>
|
||||||
<Link href="/settings">Canvas Settings</Link>
|
<Link href="/settings">Canvas Settings</Link>
|
||||||
<Link href="/roof">Roof</Link>
|
<Link href="/roof">Roof</Link>
|
||||||
<Link href="/roof2">Roof2</Link>
|
<Link href="/roof2">Roof2</Link>
|
||||||
|
|||||||
@ -1,22 +1,31 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState, memo, useCallback } from 'react'
|
import { useEffect, useState, memo, useCallback } from 'react'
|
||||||
import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react'
|
import { Button, Checkbox, CheckboxGroup, RadioGroup, Radio, Input, Select, SelectItem } from '@nextui-org/react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { modalContent, modalState } from '@/store/modalAtom'
|
import { modalContent, modalState } from '@/store/modalAtom'
|
||||||
import { canvasSettingState } from '@/store/canvasAtom'
|
import { canvasSettingState } from '@/store/canvasAtom'
|
||||||
import { useAxios } from '@/hooks/useAxios'
|
import { useAxios } from '@/hooks/useAxios'
|
||||||
|
import { get, post } from '@/lib/Axios'
|
||||||
|
|
||||||
export default function InitSettingsModal(props) {
|
export default function InitSettingsModal(props) {
|
||||||
|
const [objectNo, setObjectNo] = useState('test123240909001') // 후에 삭제 필요
|
||||||
const [open, setOpen] = useRecoilState(modalState)
|
const [open, setOpen] = useRecoilState(modalState)
|
||||||
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
|
const [canvasSetting, setCanvasSetting] = useRecoilState(canvasSettingState)
|
||||||
const [roofMaterials, setRoofMaterials] = useState([])
|
const [roofMaterials, setRoofMaterials] = useState([])
|
||||||
const [basicSetting, setBasicSettings] = useState({
|
const [basicSetting, setBasicSettings] = useState({
|
||||||
type: '1',
|
roofDrawingSet: '1',
|
||||||
inputType: '1',
|
roofSizeSet: '1',
|
||||||
angleType: 'slope',
|
roofAngleSet: 'slope',
|
||||||
roofs: [],
|
roofs: [],
|
||||||
})
|
})
|
||||||
|
|
||||||
const { get, post } = useAxios()
|
const modelProps = {
|
||||||
|
open,
|
||||||
|
setOpen,
|
||||||
|
}
|
||||||
|
|
||||||
|
//const { get, post } = useAxios()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
get({ url: '/api/roof-material/roof-material-infos' }).then((res) => {
|
get({ url: '/api/roof-material/roof-material-infos' }).then((res) => {
|
||||||
@ -26,6 +35,41 @@ export default function InitSettingsModal(props) {
|
|||||||
setRoofMaterials(res)
|
setRoofMaterials(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${objectNo}` }).then((res) => {
|
||||||
|
if (!res) return
|
||||||
|
|
||||||
|
// 'roofs' 배열을 생성하여 각 항목을 추가
|
||||||
|
const roofsRow = res.map((item) => {
|
||||||
|
return {
|
||||||
|
roofDrawingSet: String(item.roofDrawingSet),
|
||||||
|
roofSizeSet: String(item.roofSizeSet),
|
||||||
|
roofAngleSet: item.roofAngleSet,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const roofsArray = res.map((item) => {
|
||||||
|
return {
|
||||||
|
roofSeq: String(item.roofSeq),
|
||||||
|
roofType: String(item.roofType),
|
||||||
|
roofWidth: String(item.roofWidth),
|
||||||
|
roofHeight: String(item.roofHeight),
|
||||||
|
roofGap: String(item.roofGap),
|
||||||
|
roofLayout: item.roofLayout,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 나머지 데이터와 함께 'roofs' 배열을 patternData에 넣음
|
||||||
|
const patternData = {
|
||||||
|
roofDrawingSet: roofsRow[0].roofDrawingSet, // 첫 번째 항목의 값을 사용
|
||||||
|
roofSizeSet: roofsRow[0].roofSizeSet, // 첫 번째 항목의 값을 사용
|
||||||
|
roofAngleSet: roofsRow[0].roofAngleSet, // 첫 번째 항목의 값을 사용
|
||||||
|
roofs: roofsArray, // 만들어진 roofs 배열
|
||||||
|
}
|
||||||
|
|
||||||
|
// 데이터 설정
|
||||||
|
setBasicSettings({ ...patternData })
|
||||||
|
})
|
||||||
|
|
||||||
if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) {
|
if (!(Object.keys(canvasSetting).length === 0 && canvasSetting.constructor === Object)) {
|
||||||
setBasicSettings({ ...canvasSetting })
|
setBasicSettings({ ...canvasSetting })
|
||||||
}
|
}
|
||||||
@ -46,12 +90,12 @@ export default function InitSettingsModal(props) {
|
|||||||
|
|
||||||
//기본값
|
//기본값
|
||||||
const newRoofSettings = {
|
const newRoofSettings = {
|
||||||
id: basicSetting.roofs.length + 1,
|
roofSeq: basicSetting.roofs.length + 1,
|
||||||
roofId: '3',
|
roofType: '3',
|
||||||
width: '200',
|
roofWidth: '200',
|
||||||
height: '200',
|
roofHeight: '200',
|
||||||
gap: '0',
|
roofGap: '0',
|
||||||
layout: 'parallel',
|
roofLayout: 'parallel',
|
||||||
}
|
}
|
||||||
|
|
||||||
setBasicSettings((prevState) => ({
|
setBasicSettings((prevState) => ({
|
||||||
@ -62,19 +106,45 @@ export default function InitSettingsModal(props) {
|
|||||||
|
|
||||||
//배열 값 변경 함수
|
//배열 값 변경 함수
|
||||||
const handleRoofSettings = (id, event) => {
|
const handleRoofSettings = (id, event) => {
|
||||||
const roof = basicSetting.roofs.map((roof, i) => (id === roof.id ? { ...roof, [event.target.name]: event.target.value } : roof))
|
const roof = basicSetting.roofs.map((roof, i) => (id === roof.roofSeq ? { ...roof, [event.target.name]: event.target.value } : roof))
|
||||||
setBasicSettings((prevState) => ({
|
setBasicSettings((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
roofs: [...roof],
|
roofs: [...roof],
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const submitCanvasConfig = () => {
|
//저장
|
||||||
post({ url: '/api/canvas-config', data: basicSetting }).then((res) => {
|
const submitCanvasConfig = async () => {
|
||||||
if (!res) {
|
if (!objectNo) {
|
||||||
setCanvasSetting({ ...basicSetting })
|
alert('object_no를 입력하세요.')
|
||||||
}
|
return
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const patternData = {
|
||||||
|
objectNo,
|
||||||
|
roofDrawingSet: basicSetting.roofDrawingSet,
|
||||||
|
roofSizeSet: basicSetting.roofSizeSet,
|
||||||
|
roofAngleSet: basicSetting.roofAngleSet,
|
||||||
|
roofMaterialsAddList: basicSetting.roofs,
|
||||||
|
}
|
||||||
|
await post({ url: `/api/canvas-management/canvas-basic-settings`, data: patternData })
|
||||||
|
|
||||||
|
//Recoil 설정
|
||||||
|
setCanvasSetting({ ...basicSetting })
|
||||||
|
|
||||||
|
// 저장 후 재조회
|
||||||
|
//await handleSelect()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 삭제버튼 클릭시 해당 요소 id를 targetId로 전달받음
|
||||||
|
const onRemove = async (targetId) => {
|
||||||
|
console.log(targetId)
|
||||||
|
|
||||||
|
setBasicSettings((prevState) => ({
|
||||||
|
...prevState,
|
||||||
|
roofs: prevState.roofs.filter((roof) => roof.roofSeq !== targetId),
|
||||||
|
}))
|
||||||
|
// setBasicSettings({ ...newRoofSettings }) // 삭제한 데이터 배열을 setData()에 상태를 변화시킴
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -84,7 +154,13 @@ export default function InitSettingsModal(props) {
|
|||||||
|
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
<RadioGroup label="도면 작성방법" name="type" orientation="horizontal" value={basicSetting.type} onChange={handleBasicSetting}>
|
<RadioGroup
|
||||||
|
label="도면 작성방법"
|
||||||
|
name="roofDrawingSet"
|
||||||
|
orientation="horizontal"
|
||||||
|
value={basicSetting.roofDrawingSet}
|
||||||
|
onChange={handleBasicSetting}
|
||||||
|
>
|
||||||
<Radio value="1">치수 입력에 의한 물건작성</Radio>
|
<Radio value="1">치수 입력에 의한 물건작성</Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
@ -92,7 +168,13 @@ export default function InitSettingsModal(props) {
|
|||||||
|
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
<RadioGroup label="치수 입력방법" name="inputType" orientation="horizontal" value={basicSetting.inputType} onChange={handleBasicSetting}>
|
<RadioGroup
|
||||||
|
label="치수 입력방법"
|
||||||
|
name="roofSizeSet"
|
||||||
|
orientation="horizontal"
|
||||||
|
value={basicSetting.roofSizeSet}
|
||||||
|
onChange={handleBasicSetting}
|
||||||
|
>
|
||||||
<Radio value="1">복사도 입력</Radio>
|
<Radio value="1">복사도 입력</Radio>
|
||||||
<Radio value="2">실측값 입력</Radio>
|
<Radio value="2">실측값 입력</Radio>
|
||||||
<Radio value="3">육지붕</Radio>
|
<Radio value="3">육지붕</Radio>
|
||||||
@ -102,13 +184,20 @@ export default function InitSettingsModal(props) {
|
|||||||
|
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
<RadioGroup label="지붕각도 설정" name="angleType" orientation="horizontal" value={basicSetting.angleType} onChange={handleBasicSetting}>
|
<RadioGroup
|
||||||
|
label="지붕각도 설정"
|
||||||
|
name="roofAngleSet"
|
||||||
|
orientation="horizontal"
|
||||||
|
value={basicSetting.roofAngleSet}
|
||||||
|
onChange={handleBasicSetting}
|
||||||
|
>
|
||||||
<Radio value="slope">경사</Radio>
|
<Radio value="slope">경사</Radio>
|
||||||
<Radio value="angle">각도</Radio>
|
<Radio value="angle">각도</Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex space-x-4">지붕재 추가(단위 : mm)</div>
|
||||||
<div className="flex items-center mb-4">
|
<div className="flex items-center mb-4">
|
||||||
<button className="px-3 py-1 bg-blue-500 text-white rounded mr-3" onClick={addRoofSetting}>
|
<button className="px-3 py-1 bg-blue-500 text-white rounded mr-3" onClick={addRoofSetting}>
|
||||||
Add
|
Add
|
||||||
@ -118,7 +207,7 @@ export default function InitSettingsModal(props) {
|
|||||||
|
|
||||||
{basicSetting.roofs &&
|
{basicSetting.roofs &&
|
||||||
basicSetting.roofs.map((roof, index) => {
|
basicSetting.roofs.map((roof, index) => {
|
||||||
return <RoofSelectBox roofMaterials={roofMaterials} roof={roof} key={index} onChange={handleRoofSettings} />
|
return <RoofSelectBox roofMaterials={roofMaterials} roof={roof} key={index} onChange={handleRoofSettings} onRemove={onRemove} />
|
||||||
})}
|
})}
|
||||||
|
|
||||||
<div className="flex gap-4 items-right">
|
<div className="flex gap-4 items-right">
|
||||||
@ -128,6 +217,7 @@ export default function InitSettingsModal(props) {
|
|||||||
<Button size="sm" onClick={() => setOpen(!open)}>
|
<Button size="sm" onClick={() => setOpen(!open)}>
|
||||||
취소
|
취소
|
||||||
</Button>
|
</Button>
|
||||||
|
<input type="text" placeholder="Object No 입력" value={objectNo} onChange={(e) => setObjectNo(e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@ -137,15 +227,16 @@ export default function InitSettingsModal(props) {
|
|||||||
const RoofSelectBox = (props) => {
|
const RoofSelectBox = (props) => {
|
||||||
return (
|
return (
|
||||||
<div className="mb-4 flex flex-wrap items-center space-x-4" style={{ border: '1px solid black' }}>
|
<div className="mb-4 flex flex-wrap items-center space-x-4" style={{ border: '1px solid black' }}>
|
||||||
|
<span> 타입 : </span>
|
||||||
<Select
|
<Select
|
||||||
aria-label="roofMaterial"
|
aria-label="roofMaterial"
|
||||||
className={'w-52'}
|
className={'w-52'}
|
||||||
name="roofId"
|
name="roofType"
|
||||||
onChange={(e) => props.onChange(props.roof.id, e)}
|
onChange={(e) => props.onChange(props.roof.roofSeq, e)}
|
||||||
items={props.roofMaterials}
|
items={props.roofMaterials}
|
||||||
defaultSelectedKeys={props.roof.roofId ? props.roof.roofId : ''}
|
defaultSelectedKeys={props.roof.roofType ? props.roof.roofType : ''}
|
||||||
selectedKeys={props.roof.roofId}
|
selectedKeys={props.roof.roofType}
|
||||||
value={props.roof.roofId}
|
value={props.roof.roofType}
|
||||||
>
|
>
|
||||||
{(roofMaterial) => (
|
{(roofMaterial) => (
|
||||||
<SelectItem key={roofMaterial.id} value={roofMaterial.id}>
|
<SelectItem key={roofMaterial.id} value={roofMaterial.id}>
|
||||||
@ -153,37 +244,58 @@ const RoofSelectBox = (props) => {
|
|||||||
</SelectItem>
|
</SelectItem>
|
||||||
)}
|
)}
|
||||||
</Select>
|
</Select>
|
||||||
|
<span> 너비 : </span>
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
name="width"
|
name="roofWidth"
|
||||||
placeholder="너비"
|
placeholder="너비"
|
||||||
value={props.roof.width}
|
value={props.roof.roofWidth}
|
||||||
className="w-24"
|
className="w-24"
|
||||||
onChange={(e) => props.onChange(props.roof.id, e)}
|
onChange={(e) => props.onChange(props.roof.roofSeq, e)}
|
||||||
/>
|
|
||||||
<Input
|
|
||||||
type="text"
|
|
||||||
name="height"
|
|
||||||
placeholder="높이"
|
|
||||||
value={props.roof.height}
|
|
||||||
className="w-24"
|
|
||||||
onChange={(e) => props.onChange(props.roof.id, e)}
|
|
||||||
/>
|
/>
|
||||||
mm
|
mm
|
||||||
<Input type="text" name="gap" placeholder="간격" value={props.roof.gap} className="w-24" onChange={(e) => props.onChange(props.roof.id, e)} />
|
<span> 높이 : </span>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
name="roofHeight"
|
||||||
|
placeholder="높이"
|
||||||
|
value={props.roof.roofHeight}
|
||||||
|
className="w-24"
|
||||||
|
onChange={(e) => props.onChange(props.roof.roofSeq, e)}
|
||||||
|
/>
|
||||||
|
mm
|
||||||
|
<span> 서까래 간격 : </span>
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
name="roofGap"
|
||||||
|
placeholder="간격"
|
||||||
|
value={props.roof.roofGap}
|
||||||
|
className="w-24"
|
||||||
|
onChange={(e) => props.onChange(props.roof.roofSeq, e)}
|
||||||
|
/>
|
||||||
mm
|
mm
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
orientation="horizontal"
|
orientation="horizontal"
|
||||||
name="layout"
|
name="roofLayout"
|
||||||
value={props.roof.layout}
|
value={props.roof.roofLayout}
|
||||||
defaultValue="parallel"
|
defaultValue="parallel"
|
||||||
onChange={(e) => props.onChange(props.roof.id, e)}
|
onChange={(e) => props.onChange(props.roof.roofSeq, e)}
|
||||||
>
|
>
|
||||||
<Radio value="parallel">병렬식</Radio>
|
<Radio value="parallel">병렬식</Radio>
|
||||||
<Radio value="cascade">계단식</Radio>
|
<Radio value="cascade">계단식</Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex space-x-4">
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
props.onRemove(props.roof.roofSeq)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
삭제
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,12 +6,57 @@ import { Button } from '@nextui-org/react'
|
|||||||
import { get, post } from '@/lib/Axios'
|
import { get, post } from '@/lib/Axios'
|
||||||
import { useRecoilState } from 'recoil'
|
import { useRecoilState } from 'recoil'
|
||||||
import { customSettingsState } from '@/store/canvasAtom'
|
import { customSettingsState } from '@/store/canvasAtom'
|
||||||
|
import { modalContent, modalState } from '@/store/modalAtom'
|
||||||
|
|
||||||
|
import ColorPicker from './common/color-picker/ColorPicker'
|
||||||
|
|
||||||
export default function Settings() {
|
export default function Settings() {
|
||||||
const [objectNo, setObjectNo] = useState('test123240829010')
|
const [objectNo, setObjectNo] = useState('test123240829010')
|
||||||
const [error, setError] = useState(null)
|
const [error, setError] = useState(null)
|
||||||
const [customSettings, setCustomSettings] = useRecoilState(customSettingsState)
|
const [customSettings, setCustomSettings] = useRecoilState(customSettingsState)
|
||||||
|
|
||||||
|
const [color, setColor] = useState('#ff0000')
|
||||||
|
|
||||||
|
const [open, setOpen] = useRecoilState(modalState)
|
||||||
|
const [contents, setContent] = useRecoilState(modalContent)
|
||||||
|
|
||||||
|
const handleSavePopup = () => {
|
||||||
|
console.log('color ', color)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClosePopup = () => {
|
||||||
|
setContent('')
|
||||||
|
setOpen(false)
|
||||||
|
console.log('colorSetting ', color)
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorSetting = (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<h1>React ColorPicker</h1>
|
||||||
|
<ColorPicker color={color} setColor={setColor} />
|
||||||
|
<div className="p-4">{color}</div>
|
||||||
|
<div>
|
||||||
|
<button onClick={handleSavePopup}>저장</button> <p />
|
||||||
|
<button onClick={handleClosePopup}>취소</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
const customStyles = {
|
||||||
|
overlay: {
|
||||||
|
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
width: '300px',
|
||||||
|
height: '400px',
|
||||||
|
margin: 'auto',
|
||||||
|
borderRadius: '4px',
|
||||||
|
boxShadow: '0 2px 4px rgba(0,0,0,0.2)',
|
||||||
|
padding: '20px',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// 상태를 하나의 객체로 관리
|
// 상태를 하나의 객체로 관리
|
||||||
const [settings, setSettings] = useState({
|
const [settings, setSettings] = useState({
|
||||||
display1: Array(11).fill(false), // 화면 표시1
|
display1: Array(11).fill(false), // 화면 표시1
|
||||||
@ -48,6 +93,21 @@ export default function Settings() {
|
|||||||
|
|
||||||
// 클릭 시 상태 변경 함수
|
// 클릭 시 상태 변경 함수
|
||||||
const handleToggle = (type, index) => {
|
const handleToggle = (type, index) => {
|
||||||
|
// '실선 그리드' 클릭 시 팝업 열기
|
||||||
|
if (type === 'gridSettings' && gridItems.gridSettings[index] === '실선 그리드') {
|
||||||
|
//openGridPopup()
|
||||||
|
}
|
||||||
|
|
||||||
|
// '그리드 색 설정' 클릭 시 팝업 열기
|
||||||
|
if (type === 'gridSettings' && gridItems.gridSettings[index] === '그리드 색 설정') {
|
||||||
|
//setSelectedGridSetting(gridItems.gridSettings[index])
|
||||||
|
//setIsPopupOpen(true)
|
||||||
|
//return prevSettings // 설정은 변경하지 않음
|
||||||
|
|
||||||
|
setOpen(true)
|
||||||
|
setContent({ ...colorSetting })
|
||||||
|
}
|
||||||
|
|
||||||
setSettings((prevSettings) => {
|
setSettings((prevSettings) => {
|
||||||
// prevSettings[type]이 배열인지 확인하고, 그렇지 않은 경우 빈 배열로 초기화
|
// prevSettings[type]이 배열인지 확인하고, 그렇지 않은 경우 빈 배열로 초기화
|
||||||
let updated = Array.isArray(prevSettings[type]) ? [...prevSettings[type]] : []
|
let updated = Array.isArray(prevSettings[type]) ? [...prevSettings[type]] : []
|
||||||
@ -61,6 +121,24 @@ export default function Settings() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// '실선 그리드' 클릭 시 팝업을 열기 위한 함수
|
||||||
|
const openGridPopup = () => {
|
||||||
|
const popupWidth = 500
|
||||||
|
const popupHeight = 300
|
||||||
|
|
||||||
|
// 팝업 창 위치를 화면 중앙으로 조정하기 위해 계산
|
||||||
|
const left = window.innerWidth / 2 - popupWidth / 2
|
||||||
|
const top = window.innerHeight / 2 - popupHeight / 2
|
||||||
|
|
||||||
|
// 새 창 열기
|
||||||
|
window
|
||||||
|
.open
|
||||||
|
//'./components/intro', // 팝업으로 띄울 페이지의 URL
|
||||||
|
//'_blank', // 새 창으로 열기
|
||||||
|
//`width=${popupWidth},height=${popupHeight},top=${top},left=${left}`, // 크기와 위치 지정
|
||||||
|
()
|
||||||
|
}
|
||||||
|
|
||||||
// Canvas Setting 조회 및 초기화
|
// Canvas Setting 조회 및 초기화
|
||||||
const handleSelect = async () => {
|
const handleSelect = async () => {
|
||||||
try {
|
try {
|
||||||
@ -221,6 +299,10 @@ export default function Settings() {
|
|||||||
<div className="grid-item">흡착점 ON</div>
|
<div className="grid-item">흡착점 ON</div>
|
||||||
</div>
|
</div>
|
||||||
<h1>[그리드 설정]</h1>
|
<h1>[그리드 설정]</h1>
|
||||||
|
<div>
|
||||||
|
<ColorPicker color={color} setColor={setColor} />
|
||||||
|
<div className="p-4">{color}</div>
|
||||||
|
</div>
|
||||||
<div className="grid-container2">
|
<div className="grid-container2">
|
||||||
{gridItems.gridSettings.map((item, index) => (
|
{gridItems.gridSettings.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -127,6 +127,9 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
|
|
||||||
this.on('modified', (e) => {
|
this.on('modified', (e) => {
|
||||||
this.addLengthText()
|
this.addLengthText()
|
||||||
|
if (this.arrow) {
|
||||||
|
drawDirectionArrow(this)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.on('selected', () => {
|
this.on('selected', () => {
|
||||||
@ -144,6 +147,17 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
this.canvas.remove(text)
|
this.canvas.remove(text)
|
||||||
})
|
})
|
||||||
this.texts = null
|
this.texts = null
|
||||||
|
|
||||||
|
if (this.arrow) {
|
||||||
|
this.canvas.remove(this.arrow)
|
||||||
|
this.canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === 'directionText' && obj.parent === this.arrow)
|
||||||
|
.forEach((text) => {
|
||||||
|
this.canvas.remove(text)
|
||||||
|
})
|
||||||
|
this.arrow = null
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// polygon.fillCell({ width: 50, height: 30, padding: 10 })
|
// polygon.fillCell({ width: 50, height: 30, padding: 10 })
|
||||||
|
|||||||
@ -32,7 +32,7 @@ import {
|
|||||||
import { QLine } from '@/components/fabric/QLine'
|
import { QLine } from '@/components/fabric/QLine'
|
||||||
import { fabric } from 'fabric'
|
import { fabric } from 'fabric'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
import offsetPolygon from '@/util/qpolygon-utils'
|
import offsetPolygon, { inPolygon } from '@/util/qpolygon-utils'
|
||||||
import { isObjectNotEmpty } from '@/util/common-utils'
|
import { isObjectNotEmpty } from '@/util/common-utils'
|
||||||
import * as turf from '@turf/turf'
|
import * as turf from '@turf/turf'
|
||||||
import { Mode } from '@/common/common'
|
import { Mode } from '@/common/common'
|
||||||
@ -1061,8 +1061,25 @@ export function useMode() {
|
|||||||
origY: 0,
|
origY: 0,
|
||||||
down: (o) => {
|
down: (o) => {
|
||||||
if (mode !== Mode.OPENING) return
|
if (mode !== Mode.OPENING) return
|
||||||
mouseEvent.openingMode.isDown = true
|
const roofs = canvas?._objects.filter((obj) => obj.name === 'roof')
|
||||||
|
if (roofs.length === 0) {
|
||||||
|
alert('지붕을 먼저 그려주세요')
|
||||||
|
setMode(Mode.DEFAULT)
|
||||||
|
return
|
||||||
|
}
|
||||||
const pointer = canvas.getPointer(o.e)
|
const pointer = canvas.getPointer(o.e)
|
||||||
|
let selectRoof = null
|
||||||
|
roofs.forEach((roof) => {
|
||||||
|
if (roof.inPolygon({ x: pointer.x, y: pointer.y })) {
|
||||||
|
selectRoof = roof
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (!selectRoof) {
|
||||||
|
alert('지붕 내부에만 생성 가능합니다.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mouseEvent.openingMode.isDown = true
|
||||||
|
|
||||||
mouseEvent.openingMode.origX = pointer.x
|
mouseEvent.openingMode.origX = pointer.x
|
||||||
mouseEvent.openingMode.origY = pointer.y
|
mouseEvent.openingMode.origY = pointer.y
|
||||||
mouseEvent.openingMode.rect = new fabric.Rect({
|
mouseEvent.openingMode.rect = new fabric.Rect({
|
||||||
@ -1123,17 +1140,21 @@ export function useMode() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rectPoints = [
|
||||||
|
{ x: rect.left, y: rect.top },
|
||||||
|
{ x: rect.left, y: rect.top + rect.height },
|
||||||
|
{ x: rect.left + rect.width, y: rect.top + rect.height },
|
||||||
|
{ x: rect.left + rect.width, y: rect.top },
|
||||||
|
]
|
||||||
|
|
||||||
for (let i = 0; i < openings.length; i++) {
|
for (let i = 0; i < openings.length; i++) {
|
||||||
const rect2 = openings[i]
|
const rect2 = openings[i]
|
||||||
// Check if one rectangle is to the left of the other
|
const rect2Points = [
|
||||||
if (rect.x + rect.width <= rect2.x || rect2.x + rect2.width <= rect.x) {
|
{ x: rect2.left, y: rect2.top },
|
||||||
return true
|
{ x: rect2.left, y: rect2.top + rect2.height },
|
||||||
}
|
{ x: rect2.left + rect2.width, y: rect2.top + rect2.height },
|
||||||
|
{ x: rect2.left + rect2.width, y: rect2.top },
|
||||||
// Check if one rectangle is above the other
|
]
|
||||||
if (rect.y + rect.height <= rect2.y || rect2.y + rect2.height <= rect.y) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
@ -1147,6 +1168,7 @@ export function useMode() {
|
|||||||
canvas?.remove(rect)
|
canvas?.remove(rect)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,90 @@
|
|||||||
{
|
{
|
||||||
"hi": "こんにちは"
|
"hi": "こんにちは",
|
||||||
|
"common.message.no.data": "No data",
|
||||||
|
"common.message.no.dataDown": "ダウンロードするデータがありません",
|
||||||
|
"common.message.noData": "表示するデータがありません",
|
||||||
|
"common.message.search": "search success",
|
||||||
|
"common.message.insert": "insert success",
|
||||||
|
"common.message.update": "update success",
|
||||||
|
"common.message.delete": "削除",
|
||||||
|
"common.message.restoration": "復元",
|
||||||
|
"common.message.cancel": "キャンセル",
|
||||||
|
"common.message.send": "メールを送信しました.",
|
||||||
|
"common.message.no.delete": "削除するデータがありません",
|
||||||
|
"common.message.save": "保存",
|
||||||
|
"common.message.transfer": "転送",
|
||||||
|
"common.message.batch.exec": "batch success",
|
||||||
|
"common.message.not.mov": "移動できません.",
|
||||||
|
"common.message.required.data": "{0} は入力必須項目となります。",
|
||||||
|
"common.message.save.error": "データの保存中にエラーが発生しました。 サイト管理者にお問い合わせください。",
|
||||||
|
"common.message.transfer.error": "データの転送中にエラーが発生しました。 サイト管理者にお問い合わせください。",
|
||||||
|
"common.message.delete.error": "データの削除中にエラーが発生しました。 サイト管理者にお問い合わせください。",
|
||||||
|
"common.message.batch.error": "バッチの実行中にエラーが発生しました。 サイト管理者に連絡してください。",
|
||||||
|
"common.message.send.error": "データの送信中にエラーが発生しました。サイト管理者にお問い合わせください",
|
||||||
|
"common.message.communication.error": "ネットワークエラーが発生しました。サイト管理者に連絡してください。",
|
||||||
|
"common.message.data.error": "{0} はデータ形式が無効です。",
|
||||||
|
"common.message.data.setting.error": "{0} は削除されたか、すでに構成されているデータです。",
|
||||||
|
"common.message.parameter.error": "パラメータエラー",
|
||||||
|
"common.message.product.parameter.error": "存在しない製品があります。",
|
||||||
|
"common.message.customer.parameter.error": "存在しない顧客があります。",
|
||||||
|
"common.message.file.exists.error": "ファイルが正常にアップロードされないためにエラーが発生しました",
|
||||||
|
"common.message.file.download.exists": "ファイルが存在しません。",
|
||||||
|
"common.message.file.download.error": "ァイルのダウンロードエラー",
|
||||||
|
"common.message.file.template.validation01": "フォルダをアップロードできません",
|
||||||
|
"common.message.file.template.validation02": "アップロードできるのはExcelファイルのみです。",
|
||||||
|
"common.message.file.template.validation03": "登録できない拡張子です",
|
||||||
|
"common.message.file.template.validation04": "容量を超えています アップロード可能な容量:{0} MB",
|
||||||
|
"common.message.file.template.validation05": "アップロードファイルを選択して下さい",
|
||||||
|
"common.message.multi.insert": "合計 {0} 件数 ({1}成功、 {2} 失敗 {3})",
|
||||||
|
"common.message.error": "エラーが発生しました。サイト管理者に連絡してください。",
|
||||||
|
"common.message.data.save": "保存しますか?",
|
||||||
|
"common.message.data.delete": " 削除しますか?",
|
||||||
|
"common.message.data.exists": "{0} はすでに存在するデータです。",
|
||||||
|
"common.message.data.no.exists": "{0} は存在しないデータです。",
|
||||||
|
"common.message.all": "All",
|
||||||
|
"common.message.tab.close.all": "すべてのタブを閉じますか?",
|
||||||
|
"common.message.transfer.save": "{0}件転送しますか?",
|
||||||
|
"common.message.confirm.save": "保存しますか?",
|
||||||
|
"common.message.confirm.confirm": "承認しますか?",
|
||||||
|
"common.message.confirm.request": "承認リクエストしますか?",
|
||||||
|
"common.message.confirm.delete": "削除しますか?",
|
||||||
|
"common.message.confirm.close": "閉じますか?",
|
||||||
|
"common.message.confirm.unclose": "クローズ中止しますか?",
|
||||||
|
"common.message.confirm.cancel": "キャンセルしますか?",
|
||||||
|
"common.message.confirm.uncancel": "キャンセル中止しますか?",
|
||||||
|
"common.message.confirm.copy": "コピーしますか?",
|
||||||
|
"common.message.confirm.createSo": "S/O作成しますか?",
|
||||||
|
"common.message.confirm.mark": "保存完了",
|
||||||
|
"common.message.confirm.mail": "メールを送信しますか?",
|
||||||
|
"common.message.confirm.printPriceItem": "価格を印刷しますか?",
|
||||||
|
"common.message.confirm.allAppr ": "Do you want to Batch approve the selected data?",
|
||||||
|
"common.message.confirm.deliveryFee": "送料を登録しますか?",
|
||||||
|
"common.message.success.delete": "削除完了",
|
||||||
|
"common.message.success.close": "閉じる",
|
||||||
|
"common.message.success.unclose": "キャンセルしました",
|
||||||
|
"common.message.validation.date": "終了日を開始日より前にすることはできません。 もう一度入力してください。",
|
||||||
|
"common.message.no.editfield": "フィールドを編集できません",
|
||||||
|
"common.message.success.rmmail": "リスク管理チームにメールを送信しました。",
|
||||||
|
"common.message.password.validation01": "パスワードの変更が一致しません。",
|
||||||
|
"common.message.password.validation02": "英語、数字、特殊文字を組み合わせた8桁以上を入力してください。",
|
||||||
|
"common.message.password.validation03": "パスワードをIDと同じにすることはできません。",
|
||||||
|
"common.message.menu.validation01": "注文を保存するメニューはありません.",
|
||||||
|
"common.message.menu.validation02": "The same sort order exists.",
|
||||||
|
"common.message.menuCode.check01": "登録可能",
|
||||||
|
"common.message.menuCode.check02": "登録できません",
|
||||||
|
"common.message.pleaseSelect": "{0}を選択してください",
|
||||||
|
"common.message.pleaseInput": "{0}を入力してください。",
|
||||||
|
"common.message.pleaseInputOr": "{0}または{1}を入力してください。",
|
||||||
|
"common.message.approved ": "承認済み",
|
||||||
|
"common.message.errorFieldExist": "エラー項目が存在します",
|
||||||
|
"common.message.storeIdExist ": "既に利用されている販売店IDです",
|
||||||
|
"common.message.userIdExist ": "すでに使用しているユーザーID。",
|
||||||
|
"common.message.noExists ": "削除された掲示物です",
|
||||||
|
"common.message.emailReqTo": "メール宛先が必要です",
|
||||||
|
"common.message.downloadPeriod": "ダウンロード検索期間を{0}日以内に選択してください。",
|
||||||
|
"common.message.backToSubmit": "販売店ブロック解除実行しますか?",
|
||||||
|
"common.message.backToG3": "Back to G3処理実行しますか?",
|
||||||
|
"common.message.writeToConfirm": "作成解除を実行しますか?",
|
||||||
|
"common.message.password.init.success": "パスワード [{0}] に初期化されました。",
|
||||||
|
"common.message.no.edit.save": "この文書は変更できません。"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,90 @@
|
|||||||
{
|
{
|
||||||
"hi": "안녕하세요"
|
"hi": "안녕하세요",
|
||||||
|
"common.message.no.data": "No data",
|
||||||
|
"common.message.no.dataDown": "No data to download",
|
||||||
|
"common.message.noData": "No data to display",
|
||||||
|
"common.message.search": "search success",
|
||||||
|
"common.message.insert": "insert success",
|
||||||
|
"common.message.update": "update success",
|
||||||
|
"common.message.delete": "Deleted",
|
||||||
|
"common.message.restoration": "Restored",
|
||||||
|
"common.message.cancel": "Canceled",
|
||||||
|
"common.message.send": "The mail has been sent.",
|
||||||
|
"common.message.no.delete": "There is no data to delete.",
|
||||||
|
"common.message.save": "Saved.",
|
||||||
|
"common.message.transfer": "Transfered",
|
||||||
|
"common.message.batch.exec": "batch success",
|
||||||
|
"common.message.not.mov": "Its impossible to move.",
|
||||||
|
"common.message.required.data": "{0} is required input value.",
|
||||||
|
"common.message.save.error": "An error occurred while saving the data. Please contact site administrator.",
|
||||||
|
"common.message.transfer.error": "An error occurred while transfer the data. Please contact site administrator.",
|
||||||
|
"common.message.delete.error": "An error occurred while deleting data. Please contact site administrator.",
|
||||||
|
"common.message.batch.error": "An error occurred while executing the batch. Please contact site administrator.",
|
||||||
|
"common.message.send.error": "Error sending data, please contact your administrator.",
|
||||||
|
"common.message.communication.error": "Network error occurred. \n Please contact site administrator.",
|
||||||
|
"common.message.data.error": "{0} The data format is not valid.",
|
||||||
|
"common.message.data.setting.error": "{0} is data that has been deleted or already configured.",
|
||||||
|
"common.message.parameter.error": "Parameter Error",
|
||||||
|
"common.message.product.parameter.error": "존재하지 않는 제품이 있습니다.",
|
||||||
|
"common.message.customer.parameter.error": "존재하지 않는 고객이 있습니다.",
|
||||||
|
"common.message.file.exists.error": "Error due to file not uploading normally",
|
||||||
|
"common.message.file.download.exists": "File does not exist.",
|
||||||
|
"common.message.file.download.error": "File download error",
|
||||||
|
"common.message.file.template.validation01": "Unable to upload folder",
|
||||||
|
"common.message.file.template.validation02": "Only Excel files can be uploaded.",
|
||||||
|
"common.message.file.template.validation03": "Non-registerable extension",
|
||||||
|
"common.message.file.template.validation04": "Exceed capacity \n Uploadable capacity : {0} MB",
|
||||||
|
"common.message.file.template.validation05": "업로드 파일을 선택해주세요.",
|
||||||
|
"common.message.multi.insert": "Total {0} cases ({1} successes, {2} failures {3})",
|
||||||
|
"common.message.error": "Error occurred, please contact site administrator.",
|
||||||
|
"common.message.data.save": "Do you want to save it?",
|
||||||
|
"common.message.data.delete": "Do you want to delete it?",
|
||||||
|
"common.message.data.exists": "{0} is data that already exists.",
|
||||||
|
"common.message.data.no.exists": "{0} is data that does not exist.",
|
||||||
|
"common.message.all": "All",
|
||||||
|
"common.message.tab.close.all": "Close all tabs?",
|
||||||
|
"common.message.transfer.save": "Want to {0} transfer it?",
|
||||||
|
"common.message.confirm.save": "Want to save it?",
|
||||||
|
"common.message.confirm.confirm": "Want to approve?",
|
||||||
|
"common.message.confirm.request": "Would you like to request a Approval?",
|
||||||
|
"common.message.confirm.delete": "Do you want to delete it?",
|
||||||
|
"common.message.confirm.close": "Want to close?",
|
||||||
|
"common.message.confirm.unclose": "Do you want to cancel the close?",
|
||||||
|
"common.message.confirm.cancel": "Want to cancellation?",
|
||||||
|
"common.message.confirm.uncancel": "Do you want to cancel the cancellation?",
|
||||||
|
"common.message.confirm.copy": "Do you want to copy?",
|
||||||
|
"common.message.confirm.createSo": "Create Sales Order?",
|
||||||
|
"common.message.confirm.mark": "Saved.",
|
||||||
|
"common.message.confirm.mail": "Do you want to send mail?",
|
||||||
|
"common.message.confirm.printPriceItem": "Would you like to print item price?",
|
||||||
|
"common.message.confirm.allAppr ": "Do you want to Batch approve the selected data?",
|
||||||
|
"common.message.confirm.deliveryFee": "Do you want to register shipping fee?",
|
||||||
|
"common.message.success.delete": "Deleted.",
|
||||||
|
"common.message.success.close": "Closed.",
|
||||||
|
"common.message.success.unclose": "Cancel Closed.",
|
||||||
|
"common.message.validation.date": "The end date cannot be earlier than the start date. Please enter it again.",
|
||||||
|
"common.message.no.editfield": "Can not edit field",
|
||||||
|
"common.message.success.rmmail": "You have successfully sent mail to the Risk Management team.",
|
||||||
|
"common.message.password.validation01": "Change passwords do not match.",
|
||||||
|
"common.message.password.validation02": "Please enter at least 8 digits combining English, numbers, and special characters.",
|
||||||
|
"common.message.password.validation03": "Password cannot be the same as ID.",
|
||||||
|
"common.message.menu.validation01": "There is no menu to save the order.",
|
||||||
|
"common.message.menu.validation02": "The same sort order exists.",
|
||||||
|
"common.message.menuCode.check01": "Registerable",
|
||||||
|
"common.message.menuCode.check02": "Unable to register",
|
||||||
|
"common.message.pleaseSelect": "Please Select {0}",
|
||||||
|
"common.message.pleaseInput": "Please Input a {0}.",
|
||||||
|
"common.message.pleaseInputOr": "Please Input a {0} or {1}.",
|
||||||
|
"common.message.approved ": "Approved.",
|
||||||
|
"common.message.errorFieldExist": "Error Field Exist",
|
||||||
|
"common.message.storeIdExist ": "이미 사용하고 있는 판매점 ID 입니다.",
|
||||||
|
"common.message.userIdExist ": "이미 사용하고 있는 사용자 ID 입니다.",
|
||||||
|
"common.message.noExists ": "삭제된 게시물 입니다.",
|
||||||
|
"common.message.emailReqTo": "Email To is required",
|
||||||
|
"common.message.downloadPeriod": "Please select the download search period within {0} days.",
|
||||||
|
"common.message.backToSubmit": "판매점 블록 해제를 실행하시겠습니까?",
|
||||||
|
"common.message.backToG3": "Back to G3 처리를 실행하시겠습니까?",
|
||||||
|
"common.message.writeToConfirm": "작성 해제를 실행하시겠습니까?",
|
||||||
|
"common.message.password.init.success": "비밀번호 [{0}]로 초기화 되었습니다.",
|
||||||
|
"common.message.no.edit.save": "This document cannot be changed."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -171,5 +171,5 @@ export const surfacePlacementModeState = atom({
|
|||||||
// 오브젝트 배치 모드
|
// 오브젝트 배치 모드
|
||||||
export const objectPlacementModeState = atom({
|
export const objectPlacementModeState = atom({
|
||||||
key: 'objectPlacementMode',
|
key: 'objectPlacementMode',
|
||||||
default: { width: 0, height: 0, areaBoundary: true, inputType: 'free', batchType: 'opening' },
|
default: { width: 0, height: 0, areaBoundary: false, inputType: 'free', batchType: 'opening' },
|
||||||
})
|
})
|
||||||
|
|||||||
@ -2714,6 +2714,12 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
if (!direction) {
|
if (!direction) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
polygon.canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === 'directionText' && obj.parent === polygon.arrow)
|
||||||
|
.forEach((obj) => polygon.canvas.remove(obj))
|
||||||
|
|
||||||
let arrow = null
|
let arrow = null
|
||||||
let points = []
|
let points = []
|
||||||
|
|
||||||
@ -2721,13 +2727,13 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
polygon.canvas.remove(polygon.arrow)
|
polygon.canvas.remove(polygon.arrow)
|
||||||
}
|
}
|
||||||
|
|
||||||
let centerPoint = polygon.getCenterPoint()
|
let centerPoint = { x: polygon.width / 2 + polygon.left, y: polygon.height / 2 + polygon.top }
|
||||||
let stickeyPoint
|
let stickeyPoint
|
||||||
|
|
||||||
const polygonMaxX = Math.max(...polygon.points.map((point) => point.x))
|
const polygonMaxX = Math.max(...polygon.getCurrentPoints().map((point) => point.x))
|
||||||
const polygonMinX = Math.min(...polygon.points.map((point) => point.x))
|
const polygonMinX = Math.min(...polygon.getCurrentPoints().map((point) => point.x))
|
||||||
const polygonMaxY = Math.max(...polygon.points.map((point) => point.y))
|
const polygonMaxY = Math.max(...polygon.getCurrentPoints().map((point) => point.y))
|
||||||
const polygonMinY = Math.min(...polygon.points.map((point) => point.y))
|
const polygonMinY = Math.min(...polygon.getCurrentPoints().map((point) => point.y))
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 'north':
|
case 'north':
|
||||||
@ -2800,6 +2806,7 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
polygon.arrow = arrow
|
polygon.arrow = arrow
|
||||||
polygon.canvas.add(arrow)
|
polygon.canvas.add(arrow)
|
||||||
polygon.canvas.renderAll()
|
polygon.canvas.renderAll()
|
||||||
|
drawDirectionStringToArrow(polygon.canvas, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2807,7 +2814,7 @@ export const drawDirectionArrow = (polygon) => {
|
|||||||
* @param canvas
|
* @param canvas
|
||||||
* @param compass
|
* @param compass
|
||||||
*/
|
*/
|
||||||
export const drawDirectionStringToArrow = (canvas, compass, fontSize) => {
|
export const drawDirectionStringToArrow = (canvas, compass = 0) => {
|
||||||
const arrows = canvas?.getObjects().filter((obj) => obj.name === 'arrow')
|
const arrows = canvas?.getObjects().filter((obj) => obj.name === 'arrow')
|
||||||
|
|
||||||
if (arrows.length === 0) {
|
if (arrows.length === 0) {
|
||||||
@ -3000,8 +3007,10 @@ const addTextByArrows = (arrows, txt, canvas) => {
|
|||||||
originX: 'center',
|
originX: 'center',
|
||||||
originY: 'center',
|
originY: 'center',
|
||||||
name: 'directionText',
|
name: 'directionText',
|
||||||
|
selectable: false,
|
||||||
left: arrow.stickeyPoint.x,
|
left: arrow.stickeyPoint.x,
|
||||||
top: arrow.stickeyPoint.y,
|
top: arrow.stickeyPoint.y,
|
||||||
|
parent: arrow,
|
||||||
})
|
})
|
||||||
canvas.add(text)
|
canvas.add(text)
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user