diff --git a/public/static/images/canvas/arr_btn_ico_white.svg b/public/static/images/canvas/arr_btn_ico_white.svg
new file mode 100644
index 00000000..31e04787
--- /dev/null
+++ b/public/static/images/canvas/arr_btn_ico_white.svg
@@ -0,0 +1,3 @@
+
diff --git a/public/static/images/canvas/ico-flx01.svg b/public/static/images/canvas/ico-flx01.svg
new file mode 100644
index 00000000..84185ff6
--- /dev/null
+++ b/public/static/images/canvas/ico-flx01.svg
@@ -0,0 +1,4 @@
+
diff --git a/public/static/images/canvas/ico-flx02.svg b/public/static/images/canvas/ico-flx02.svg
new file mode 100644
index 00000000..400d9732
--- /dev/null
+++ b/public/static/images/canvas/ico-flx02.svg
@@ -0,0 +1,5 @@
+
diff --git a/public/static/images/canvas/ico-flx03.svg b/public/static/images/canvas/ico-flx03.svg
new file mode 100644
index 00000000..44c2eeae
--- /dev/null
+++ b/public/static/images/canvas/ico-flx03.svg
@@ -0,0 +1,5 @@
+
diff --git a/public/static/images/canvas/ico-flx04.svg b/public/static/images/canvas/ico-flx04.svg
new file mode 100644
index 00000000..ae584b35
--- /dev/null
+++ b/public/static/images/canvas/ico-flx04.svg
@@ -0,0 +1,6 @@
+
diff --git a/public/static/images/main/main_background.png b/public/static/images/main/main_background.png
new file mode 100644
index 00000000..95b83229
Binary files /dev/null and b/public/static/images/main/main_background.png differ
diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx
index c8a48868..d8b4c25e 100644
--- a/src/components/Roof2.jsx
+++ b/src/components/Roof2.jsx
@@ -39,7 +39,7 @@ import QEmptyContextMenu from '@/components/common/context-menu/QEmptyContextMen
import InitSettingsModal from './InitSettingsModal'
import GridSettingsModal from './GridSettingsModal'
import { SurfaceShapeModal } from '@/components/ui/SurfaceShape'
-import { drawDirectionStringToArrow } from '@/util/qpolygon-utils'
+import { changeAllGableRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils'
import ThumbnailList from '@/components/ui/ThumbnailLIst'
import ObjectPlacement from '@/components/ui/ObjectPlacement'
@@ -627,6 +627,18 @@ export default function Roof2(props) {
const setDirectionStringToArrow = () => {
drawDirectionStringToArrow(canvas, globalCampass)
}
+
+ const setAllGableRoof = () => {
+ let offset = Number(prompt('gable roof offset', '50'))
+ if (!isNaN(offset) && offset > 0) {
+ const polygon = canvas?.getObjects()
+ console.log('gable roof offset : ', offset)
+ console.log('polygon : ', polygon)
+ changeAllGableRoof(polygon, offset, canvas)
+ } else {
+ alert('offset 은 0 보다 커야 함')
+ }
+ }
return (
<>
{canvas && (
@@ -753,6 +765,9 @@ export default function Roof2(props) {
>
)}
+
diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx
index a5553051..44d163a0 100644
--- a/src/components/auth/Login.jsx
+++ b/src/components/auth/Login.jsx
@@ -37,22 +37,41 @@ export default function Login(props) {
pwd: formData.get('password'),
}
- await post({ url: '/api/login/v1.0/login', data: param }).then((res) => {
- if (res) {
- if (res.result.resultCode == 'S') {
- // console.log('res.data', res.data)
- // 비밀번호 초기화가 필요한 경우
- // if (res.data.pwdInitYn != 'Y') {
- // alert('비밀번호 초기화가 필요한 경우')
- // } else {
- setSession(res.data)
- redirect('/')
- // }
- } else {
- alert(res.result.resultMsg)
- }
- }
+ // await post({ url: '/api/login/v1.0/login', data: param }).then((res) => {
+ // if (res) {
+ // if (res.result.resultCode == 'S') {
+ // // console.log('res.data', res.data)
+ // // 비밀번호 초기화가 필요한 경우
+ // // if (res.data.pwdInitYn != 'Y') {
+ // // alert('비밀번호 초기화가 필요한 경우')
+ // // } else {
+ // setSession(res.data)
+ // redirect('/')
+ // // }
+ // } else {
+ // alert(res.result.resultMsg)
+ // }
+ // }
+ // })
+
+ // 임시 로그인 처리
+ setSession({
+ userId: 'NEW016610',
+ saleStoreId: null,
+ name: null,
+ mail: null,
+ tel: null,
+ storeId: 'TEMP02',
+ userNm: 'ㅇㅇ6610',
+ userNmKana: '신규사용자 16610',
+ category: '인상6610',
+ telNo: '336610',
+ fax: null,
+ email: 't10t@naver.com',
+ pwdInitYn: 'N',
})
+ redirect('/')
+ // 임시 로그인 처리 끝
}
// 비밀번호 초기화 관련
diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js
index 55765279..da141287 100644
--- a/src/components/fabric/QLine.js
+++ b/src/components/fabric/QLine.js
@@ -1,6 +1,6 @@
import { fabric } from 'fabric'
import { v4 as uuidv4 } from 'uuid'
-import { getDirection, getDirectionByPoint } from '@/util/canvas-util'
+import { getDirectionByPoint } from '@/util/canvas-util'
export const QLine = fabric.util.createClass(fabric.Line, {
type: 'QLine',
@@ -52,6 +52,8 @@ export const QLine = fabric.util.createClass(fabric.Line, {
})
this.on('modified', (e) => {
+ this.startPoint = { x: this.x1, y: this.y1 }
+ this.endPoint = { x: this.x2, y: this.y2 }
this.addLengthText()
})
diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js
index 3c8b2148..84e57974 100644
--- a/src/components/fabric/QPolygon.js
+++ b/src/components/fabric/QPolygon.js
@@ -2,15 +2,7 @@ import { fabric } from 'fabric'
import { v4 as uuidv4 } from 'uuid'
import { QLine } from '@/components/fabric/QLine'
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
-import {
- calculateAngle,
- drawDirectionArrow,
- drawHippedRoof,
- drawPolygonArrow,
- inPolygon,
- splitPolygonWithLines,
- toGeoJSON,
-} from '@/util/qpolygon-utils'
+import { calculateAngle, drawDirectionArrow, drawHippedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils'
import * as turf from '@turf/turf'
export const QPolygon = fabric.util.createClass(fabric.Polygon, {
@@ -738,6 +730,6 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
this.addLengthText()
},
divideLine() {
- splitPolygonWithLines(this)
+ // splitPolygonWithLines(this)
},
})
diff --git a/src/components/floor-plan/CanvasFrame.jsx b/src/components/floor-plan/CanvasFrame.jsx
index 7c3e6c7c..f9bee2a4 100644
--- a/src/components/floor-plan/CanvasFrame.jsx
+++ b/src/components/floor-plan/CanvasFrame.jsx
@@ -8,7 +8,7 @@ export default function CanvasFrame() {
useEvent()
return (
-
+
)
diff --git a/src/components/floor-plan/CanvasMenu.jsx b/src/components/floor-plan/CanvasMenu.jsx
index 4533747a..cf5ada46 100644
--- a/src/components/floor-plan/CanvasMenu.jsx
+++ b/src/components/floor-plan/CanvasMenu.jsx
@@ -1,11 +1,16 @@
'use client'
import { useState } from 'react'
import MenuDepth01 from './MenuDepth01'
+import { useRecoilState } from 'recoil'
+import { modalState } from '@/store/modalAtom'
import QSelectBox from '@/components/common/select/QSelectBox'
+import { useMessage } from '@/hooks/useMessage'
-export default function CanvasMenu({ setModalOpen }) {
+export default function CanvasMenu() {
+ const [modalOption, setModalOption] = useRecoilState(modalState) //modal 열림닫힘 state
const [menuNumber, setMenuNumber] = useState(null)
const [vertical, setVertical] = useState(true)
+ const { getMessage } = useMessage()
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
const onClickNav = (number) => {
setMenuNumber(number)
@@ -14,83 +19,127 @@ export default function CanvasMenu({ setModalOpen }) {
}
}
return (
-
+
- onClickNav(0)}>
- onClickNav(1)}>
- onClickNav(2)}>
- onClickNav(3)}>
- onClickNav(4)}>
- onClickNav(5)}>
- onClickNav(6)}>
-
-
-
-
-
-
- 垂直水平モード
-
-
-
-
-
-
-
-
-
-
-
-
- 100%
-
-
-
-
-
-
-
+ {menuNumber !== 6 && menuNumber !== 5 && (
+ <>
+
+
+
+
+
+
+ {getMessage('plan.mode.vertical.horizontal')}
+
+
+
+
+
+
+
+
+
+
+
+
+ 100%
+
+
+
+
+
+
+
+ >
+ )}
+
+ {menuNumber === 5 && (
+ <>
+
+
+
+
+
+
+ >
+ )}
+ {menuNumber === 6 && (
+ <>
+
+
+
+
+ >
+ )}
-
- {menuNumber === 0 &&
}
- {menuNumber === 1 &&
}
+
{menuNumber === 2 && }
{menuNumber === 3 && }
{menuNumber === 4 && }
- {menuNumber === 5 && }
- {menuNumber === 6 && }
)
diff --git a/src/components/floor-plan/FloorPlan.jsx b/src/components/floor-plan/FloorPlan.jsx
index fecffea7..e7fe4225 100644
--- a/src/components/floor-plan/FloorPlan.jsx
+++ b/src/components/floor-plan/FloorPlan.jsx
@@ -1,9 +1,10 @@
'use client'
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
-import CanvasLayout from '@/components/floor-plan/CanvasLayout'
import SettingModal01 from '@/components/floor-plan/modal/settoing01/SettingModal01'
import { useState } from 'react'
+import CanvasLayout from '@/components/floor-plan/CanvasLayout'
+import '@/styles/contents.scss'
export default function FloorPlan() {
const [modalOpen, setModalOpen] = useState('option')
diff --git a/src/components/floor-plan/MenuDepth01.jsx b/src/components/floor-plan/MenuDepth01.jsx
index 90ba4e60..ce4bd6a4 100644
--- a/src/components/floor-plan/MenuDepth01.jsx
+++ b/src/components/floor-plan/MenuDepth01.jsx
@@ -1,8 +1,10 @@
'use client'
import { ToggleonMouse } from '@/components/header/Header'
+import { useMessage } from '@/hooks/useMessage'
export default function MenuDepth01() {
+ const { getMessage } = useMessage()
return (
@@ -30,7 +32,7 @@ export default function MenuDepth01() {
- ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
-
+
- ToggleonMouse(e, 'add', 'ul')} onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'ul')}>
diff --git a/src/components/floor-plan/modal/settoing01/FirstOption.jsx b/src/components/floor-plan/modal/settoing01/FirstOption.jsx
index e91f81ab..cddab6c0 100644
--- a/src/components/floor-plan/modal/settoing01/FirstOption.jsx
+++ b/src/components/floor-plan/modal/settoing01/FirstOption.jsx
@@ -1,9 +1,11 @@
import { useRecoilState } from 'recoil'
import { settingModalFirstOptionsState } from '@/store/settingAtom'
+import { useMessage } from '@/hooks/useMessage'
export default function FirstOption() {
const [settingsModalOptions, setSettingModalOptions] = useRecoilState(settingModalFirstOptionsState)
const { option1, option2 } = settingsModalOptions
+ const { getMessage } = useMessage()
const onClickOption = (option) => {
option.selected = !option.selected
@@ -13,23 +15,23 @@ export default function FirstOption() {
return (
<>
-
※図面に表示する項目をクリックすると適用されます。
+
{getMessage('modal.canvas.setting.first.option.info')}
{settingsModalOptions?.option1?.map((item) => (
))}
-
画面表示
+
{getMessage('modal.canvas.setting.first.option.display')}
{settingsModalOptions?.option2?.map((item) => (
))}
diff --git a/src/components/floor-plan/modal/settoing01/SettingModal01.jsx b/src/components/floor-plan/modal/settoing01/SettingModal01.jsx
index 5a79c795..6c9969d2 100644
--- a/src/components/floor-plan/modal/settoing01/SettingModal01.jsx
+++ b/src/components/floor-plan/modal/settoing01/SettingModal01.jsx
@@ -4,6 +4,7 @@ import { useState } from 'react'
import FirstOption from './FirstOption'
import WithDraggable from '@/components/common/draggable/withDraggable'
import SecondOption from '@/components/floor-plan/modal/settoing01/SecondOption'
+import { useMessage } from '@/hooks/useMessage'
export default function SettingModal01({ modalOpen, setModalOpen }) {
const [buttonAct, setButtonAct] = useState(1)
@@ -15,12 +16,13 @@ export default function SettingModal01({ modalOpen, setModalOpen }) {
setClose(false)
}, 180)
}
+ const { getMessage } = useMessage()
return (
-
Canvas設定
+
{getMessage('modal.canvas.setting')}
@@ -28,11 +30,11 @@ export default function SettingModal01({ modalOpen, setModalOpen }) {
{buttonAct === 1 &&
}
diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx
index 028ef6ed..f81a0ca7 100644
--- a/src/components/header/Header.jsx
+++ b/src/components/header/Header.jsx
@@ -2,6 +2,7 @@
import Link from 'next/link'
import QSelectBox from '@/components/common/select/QSelectBox'
import { usePathname } from 'next/navigation'
+import { useMessage } from '@/hooks/useMessage'
export const ToggleonMouse = (e, act, target) => {
const listWrap = e.target.closest(target)
@@ -19,6 +20,7 @@ export const ToggleonMouse = (e, act, target) => {
}
export default function Header() {
+ const { getMessage } = useMessage()
const pathName = usePathname()
if (pathName.includes('login') || pathName.includes('join')) {
return null
@@ -39,28 +41,28 @@ export default function Header() {
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
>
-
ホームへ
+
{getMessage('header.menus.home')}
- ToggleonMouse(e, 'add', 'nav > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
>
-
+
- ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
>
- 新規物件登録
+ {getMessage('header.menus.management.stuff')}
- ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
>
- モノ/図面管理
+ {getMessage('header.menus.management.plan')}
@@ -69,28 +71,28 @@ export default function Header() {
onMouseEnter={(e) => ToggleonMouse(e, 'add', 'nav > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'nav > ul')}
>
-
+
- ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
>
- お知らせ
+ {getMessage('header.menus.community.notice')}
- ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
>
- FAQ
+ {getMessage('header.menus.community.faq')}
- ToggleonMouse(e, 'add', 'li > ul')}
onMouseLeave={(e) => ToggleonMouse(e, 'remove', 'li > ul')}
>
- 素材のダウンロード
+ {getMessage('header.menus.community.archive')}
@@ -102,13 +104,13 @@ export default function Header() {
-
+
-
+
diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js
index 504724b6..bdd02fcf 100644
--- a/src/hooks/useMode.js
+++ b/src/hooks/useMode.js
@@ -1509,6 +1509,7 @@ export function useMode() {
return { x1: point.x, y1: point.y }
}),
)
+ roof.name = 'roofBase'
roof.setWall(polygon)
setRoof(roof)
setWall(polygon)
diff --git a/src/locales/ja.json b/src/locales/ja.json
index ecc55327..50172c83 100644
--- a/src/locales/ja.json
+++ b/src/locales/ja.json
@@ -1,6 +1,70 @@
{
"hi": "こんにちは",
"welcome": "환영합니다. {0}님",
+ "header.menus.home": "ホームへv",
+ "header.menus.management": "物品及び図面管理",
+ "header.menus.management.stuff": "新規物件登録",
+ "header.menus.management.plan": "モノ/図面管理",
+ "header.menus.community": "コミュニティ",
+ "header.menus.community.notice": "お知らせ",
+ "header.menus.community.faq": "FAQ",
+ "header.menus.community.archive": "素材のダウンロード",
+ "header.logout": "ログアウト",
+ "header.go": "移動",
+ "header.online.warranty.system": "オンライン保証シ",
+ "header.stem": "ステム",
+ "plan.menu.plan.drawing": "도면작성",
+ "plan.menu.placement.surface.initial.setting": "配置面 初期設定",
+ "plan.menu.root.cover": "지붕덮개",
+ "plan.menu.root.cover.outline.drawing": "외벽선 그리기",
+ "modal.cover.outline.drawing": "외벽선 그리기",
+ "modal.cover.outline": "외벽선",
+ "modal.cover.outline.right.angle": "직각",
+ "modal.cover.outline2": "이구배",
+ "modal.cover.outline.angle": "각도",
+ "modal.cover.outline.diagonal": "대각선",
+ "modal.cover.outline.setting": "설정",
+ "modal.cover.outline.length": "길이",
+ "modal.cover.outline.arrow": "방향(화살표)",
+ "modal.cover.outline.fix": "외벽선 확정",
+ "plan.menu.root.cover.roof.setting": "屋根形状設定",
+ "plan.menu.root.cover.roof.edit": "지붕형상 편집",
+ "plan.menu.root.cover.sub.line": "補助線を描",
+ "plan.menu.placement.surface": "配置面",
+ "plan.menu.placement.surface.drawing": "배치면 그리기",
+ "plan.menu.placement.surface.surface": "면형상 배치",
+ "plan.menu.placement.surface.object": "오브젝트 배치",
+ "plan.menu.module.circuit.setting": "モジュール回路構成",
+ "plan.menu.module.circuit.setting.default": "기본 설정",
+ "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로 및 가대 설정",
+ "plan.menu.estimate": "見積",
+ "plan.menu.estimate.roof.alloc": "屋根面の割り当て",
+ "plan.menu.estimate.save": "保存",
+ "plan.menu.estimate.reset": "初期化",
+ "plan.menu.estimate.copy": "コピー",
+ "plan.menu.simulation": "発展シミュレーション",
+ "plan.menu.simulation.excel": "Excel",
+ "plan.menu.simulation.pdf": "PDF",
+ "plan.mode.vertical.horizontal": "垂直水平モード",
+ "modal.canvas.setting": "Canvas設定",
+ "modal.canvas.setting.display": "ディスプレイ設定",
+ "modal.canvas.setting.font.plan": " フォントと図面サイズの設定",
+ "modal.canvas.setting.first.option.info": "※図面に表示する項目をクリックすると適用されます。",
+ "modal.canvas.setting.first.option.alloc": "할당표시",
+ "modal.canvas.setting.first.option.outline": "외벽선표시",
+ "modal.canvas.setting.first.option.plan": "도면표시",
+ "modal.canvas.setting.first.option.roof.line": "지붕선표시",
+ "modal.canvas.setting.first.option.grid": "그리드표시",
+ "modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
+ "modal.canvas.setting.first.option.word": "문자 표시",
+ "modal.canvas.setting.first.option.trestle": "가대 표시",
+ "modal.canvas.setting.first.option.flow": "흐름방향 표시",
+ "modal.canvas.setting.first.option.total": "집계표 표시",
+ "modal.canvas.setting.first.option.corridor.dimension": "복도치수 표시",
+ "modal.canvas.setting.first.option.display": "画面表示",
+ "modal.canvas.setting.first.option.border": "ボーダーのみ",
+ "modal.canvas.setting.first.option.line": "ラインハッチ",
+ "modal.canvas.setting.first.option.all": "All painted",
"common.message.no.data": "No data",
"common.message.no.dataDown": "ダウンロードするデータがありません",
"common.message.noData": "表示するデータがありません",
@@ -88,18 +152,14 @@
"common.message.writeToConfirm": "作成解除を実行しますか?",
"common.message.password.init.success": "パスワード [{0}] に初期化されました。",
"common.message.no.edit.save": "この文書は変更できません。",
-
"common.require": "필수",
-
"site.name": "Q.CAST III",
"site.sub_name": "태양광 발전 시스템 도면관리 사이트",
-
"login": "로그인",
"login.init_password.btn": "비밀번호 초기화 ja",
"login.init_password.title": "비밀번호 초기화",
"login.init_password.sub_title": "비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.",
"login.init_password.complete_message": "비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.",
-
"join.title": "Q.CAST3 로그인ID 발행 신청",
"join.sub1.title": "판매대리점 정보",
"join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점:××설비주식회사)」로 기입해 주세요.)",
@@ -141,7 +201,6 @@
"join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
"join.complete.email_comment": "담당자 이메일 주소",
"join.complete.email": "test@naver.com",
-
"stuff.gridHeader.lastEditDatetime": "갱신일시",
"stuff.gridHeader.objectNo": "물건번호",
"stuff.gridHeader.planTotCnt": "플랜 수",
diff --git a/src/locales/ko.json b/src/locales/ko.json
index 21b0115e..f519d872 100644
--- a/src/locales/ko.json
+++ b/src/locales/ko.json
@@ -1,6 +1,70 @@
{
"hi": "안녕하세요",
"welcome": "환영합니다. {0}님",
+ "header.menus.home": "Home",
+ "header.menus.management": "물건 및 도면 관리",
+ "header.menus.management.stuff": "신규 물건 등록",
+ "header.menus.management.plan": "사물/도면 관리",
+ "header.menus.community": "커뮤니티",
+ "header.menus.community.notice": "공지",
+ "header.menus.community.faq": "FAQ",
+ "header.menus.community.archive": "자료 다운로드",
+ "header.logout": "로그아웃",
+ "header.go": "이동",
+ "header.online.warranty.system": "온라인 보증 시스템",
+ "header.stem": "Stem",
+ "plan.menu.plan.drawing": "도면작성",
+ "plan.menu.placement.surface.initial.setting": "배치면 초기 설정",
+ "plan.menu.root.cover": "지붕덮개",
+ "plan.menu.root.cover.outline.drawing": "외벽선 그리기",
+ "modal.cover.outline.drawing": "외벽선 그리기",
+ "modal.cover.outline": "외벽선",
+ "modal.cover.outline.right.angle": "직각",
+ "modal.cover.outline2": "이구배",
+ "modal.cover.outline.angle": "각도",
+ "modal.cover.outline.diagonal": "대각선",
+ "modal.cover.outline.setting": "설정",
+ "modal.cover.outline.length": "길이",
+ "modal.cover.outline.arrow": "방향(화살표)",
+ "modal.cover.outline.fix": "외벽선 확정",
+ "plan.menu.root.cover.roof.setting": "지붕형상 설정",
+ "plan.menu.root.cover.roof.edit": "지붕형상 편집",
+ "plan.menu.root.cover.sub.line": "보조선 그리기",
+ "plan.menu.placement.surface": "배치면",
+ "plan.menu.placement.surface.drawing": "배치면 그리기",
+ "plan.menu.placement.surface.surface": "면형상 배치",
+ "plan.menu.placement.surface.object": "오브젝트 배치",
+ "plan.menu.module.circuit.setting": "모듈,회로 구성",
+ "plan.menu.module.circuit.setting.default": "기본 설정",
+ "plan.menu.module.circuit.setting.circuit.trestle.setting": "회로 및 가대 설정",
+ "plan.menu.estimate": "견적서",
+ "plan.menu.estimate.roof.alloc": "지붕면 할당",
+ "plan.menu.estimate.save": "저장",
+ "plan.menu.estimate.reset": "초기화",
+ "plan.menu.estimate.copy": "복사",
+ "plan.menu.simulation": "발전 시뮬레이션",
+ "plan.menu.simulation.excel": "Excel",
+ "plan.menu.simulation.pdf": "PDF",
+ "plan.mode.vertical.horizontal": "수직 수평 모드",
+ "modal.canvas.setting": "Canvas 설정",
+ "modal.canvas.setting.display": "디스플레이 설정",
+ "modal.canvas.setting.font.plan": "글꼴 및 도면 크기 설정",
+ "modal.canvas.setting.first.option.info": "※도면에 표시하는 항목을 클릭하면 적용됩니다.",
+ "modal.canvas.setting.first.option.alloc": "할당표시",
+ "modal.canvas.setting.first.option.outline": "외벽선표시",
+ "modal.canvas.setting.first.option.plan": "도면표시",
+ "modal.canvas.setting.first.option.roof.line": "지붕선표시",
+ "modal.canvas.setting.first.option.grid": "그리드표시",
+ "modal.canvas.setting.first.option.circuit.num": "회로 번호 표시",
+ "modal.canvas.setting.first.option.word": "문자 표시",
+ "modal.canvas.setting.first.option.trestle": "가대 표시",
+ "modal.canvas.setting.first.option.flow": "흐름방향 표시",
+ "modal.canvas.setting.first.option.total": "집계표 표시",
+ "modal.canvas.setting.first.option.corridor.dimension": "복도치수 표시",
+ "modal.canvas.setting.first.option.display": "화면 표시",
+ "modal.canvas.setting.first.option.border": "테두리만",
+ "modal.canvas.setting.first.option.line": "라인해치",
+ "modal.canvas.setting.first.option.all": "All painted",
"common.message.no.data": "No data",
"common.message.no.dataDown": "No data to download",
"common.message.noData": "No data to display",
@@ -88,18 +152,14 @@
"common.message.writeToConfirm": "작성 해제를 실행하시겠습니까?",
"common.message.password.init.success": "비밀번호 [{0}]로 초기화 되었습니다.",
"common.message.no.edit.save": "This document cannot be changed.",
-
"common.require": "필수",
-
"site.name": "Q.CAST III",
"site.sub_name": "태양광 발전 시스템 도면관리 사이트",
-
"login": "로그인",
"login.init_password.btn": "비밀번호 초기화",
"login.init_password.title": "비밀번호 초기화",
"login.init_password.sub_title": "비밀번호를 초기화할 아이디와 이메일 주소를 입력해 주세요.",
"login.init_password.complete_message": "비밀번호가 초기화 되었습니다. 초기화된 비밀번호는 아이디와 같습니다.",
-
"join.title": "Q.CAST3 로그인ID 발행 신청",
"join.sub1.title": "판매대리점 정보",
"join.sub1.comment": "※ 등록되는 리셀러의 회사 이름을 입력하십시오. (2차점은 「○○판매주식회사(2차점:××설비주식회사)」로 기입해 주세요.)",
@@ -141,7 +201,6 @@
"join.complete.contents": "※ 신청한 ID가 승인되면, 담당자 정보에 입력한 이메일 주소로 로그인 관련 안내 메일이 전송됩니다.",
"join.complete.email_comment": "담당자 이메일 주소",
"join.complete.email": "test@naver.com",
-
"stuff.gridHeader.lastEditDatetime": "갱신일시",
"stuff.gridHeader.objectNo": "물건번호",
"stuff.gridHeader.planTotCnt": "플랜 수",
diff --git a/src/store/canvasAtom.js b/src/store/canvasAtom.js
index 404b9106..4f274620 100644
--- a/src/store/canvasAtom.js
+++ b/src/store/canvasAtom.js
@@ -29,8 +29,8 @@ export const fontSizeState = atom({
export const canvasSizeState = atom({
key: 'canvasSize',
default: {
- vertical: 1500,
- horizontal: 1500,
+ vertical: 1000,
+ horizontal: 1600,
},
})
diff --git a/src/store/settingAtom.js b/src/store/settingAtom.js
index 0ab99ea1..3f91f509 100644
--- a/src/store/settingAtom.js
+++ b/src/store/settingAtom.js
@@ -4,22 +4,22 @@ export const settingModalFirstOptionsState = atom({
key: 'settingModalFirstOptions',
default: {
option1: [
- { id: 1, name: '割り当て表示', selected: false },
- { id: 2, name: '実寸表示', selected: false },
- { id: 3, name: '図面表示', selected: false },
- { id: 4, name: '寸法表示なし', selected: false },
- { id: 5, name: 'グリッド表示', selected: false },
- { id: 6, name: '架台表示', selected: false },
- { id: 7, name: '文字表示', selected: false },
- { id: 8, name: '座標表示', selected: false },
- { id: 9, name: '流れ方向表示', selected: false },
- { id: 10, name: '図面切替表示', selected: false },
- { id: 11, name: 'ü廊下寸法表示', selected: false },
+ { id: 1, name: 'modal.canvas.setting.first.option.alloc', selected: false },
+ { id: 2, name: 'modal.canvas.setting.first.option.outline', selected: false },
+ { id: 3, name: 'modal.canvas.setting.first.option.plan', selected: false },
+ { id: 4, name: 'modal.canvas.setting.first.option.roof.line', selected: false },
+ { id: 5, name: 'modal.canvas.setting.first.option.grid', selected: false },
+ { id: 6, name: 'modal.canvas.setting.first.option.circuit.num', selected: false },
+ { id: 7, name: 'modal.canvas.setting.first.option.word', selected: false },
+ { id: 8, name: 'modal.canvas.setting.first.option.trestle', selected: false },
+ { id: 9, name: 'modal.canvas.setting.first.option.flow', selected: false },
+ { id: 10, name: 'modal.canvas.setting.first.option.total', selected: false },
+ { id: 11, name: 'modal.canvas.setting.first.option.corridor.dimension', selected: false },
],
option2: [
- { id: 1, name: 'ボーダーのみ', selected: false },
- { id: 2, name: 'ラインハッチ', selected: false },
- { id: 3, name: 'All painted', selected: false },
+ { id: 1, name: 'modal.canvas.setting.first.option.border', selected: false },
+ { id: 2, name: 'modal.canvas.setting.first.option.line', selected: false },
+ { id: 3, name: 'modal.canvas.setting.first.option.all', selected: false },
],
},
dangerouslyAllowMutability: true,
diff --git a/src/styles/_contents.scss b/src/styles/_contents.scss
index b9dbe68e..216df145 100644
--- a/src/styles/_contents.scss
+++ b/src/styles/_contents.scss
@@ -131,7 +131,7 @@
transition: all .17s ease-in-out;
&.btn01 {
- background-image: url(../../public/static/images/canvas/side_icon01.svg);
+ background-image: url(../../public/static/images/canvas/side_icon03.svg);
}
&.btn02 {
@@ -139,7 +139,7 @@
}
&.btn03 {
- background-image: url(../../public/static/images/canvas/side_icon03.svg);
+ background-image: url(../../public/static/images/canvas/side_icon01.svg);
}
&.btn04 {
@@ -176,6 +176,39 @@
}
}
+ .ico-btn-from {
+ display: flex;
+ align-items: center;
+ gap: 5px;
+
+ button {
+ .ico {
+ display: block;
+ width: 14px;
+ height: 14px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+
+ &.ico01 {
+ background-image: url(../../public/static/images/canvas/ico-flx01.svg);
+ }
+
+ &.ico02 {
+ background-image: url(../../public/static/images/canvas/ico-flx02.svg);
+ }
+
+ &.ico03 {
+ background-image: url(../../public/static/images/canvas/ico-flx03.svg);
+ }
+
+ &.ico04 {
+ background-image: url(../../public/static/images/canvas/ico-flx04.svg);
+ }
+ }
+ }
+ }
+
.vertical-horizontal {
display: flex;
min-width: 170px;
@@ -200,6 +233,13 @@
font-weight: 400;
color: #fff;
padding: 0 7.5px;
+ transition: all .17s ease-in-out;
+ }
+
+ &.on {
+ button {
+ background-color: #1083E3;
+ }
}
}
diff --git a/src/styles/_reset.scss b/src/styles/_reset.scss
index 7dc13a69..30289000 100644
--- a/src/styles/_reset.scss
+++ b/src/styles/_reset.scss
@@ -149,7 +149,7 @@ button {
// button
.btn-frame {
display: inline-block;
- padding: 0 10px;
+ padding: 0 9px;
height: 34px;
line-height: 34px;
border-radius: 2px;
@@ -201,6 +201,7 @@ button {
}
}
+ &:hover,
&.act {
background-color: #1083E3;
border: 1px solid #1083E3;
@@ -212,6 +213,20 @@ button {
display: block;
width: 100%;
}
+
+ &.ico-flx {
+ display: flex;
+ align-items: center;
+
+ .ico {
+ margin-right: 10px;
+ }
+
+ &:hover,
+ &.act {
+ font-weight: 400;
+ }
+ }
}
// select
@@ -293,6 +308,16 @@ button {
}
// input
+.form-input {
+ label {
+ display: block;
+ color: #aaa;
+ font-size: 12px;
+ font-weight: 500;
+ margin-bottom: 10px;
+ }
+}
+
input[type=text] {
&.input-origin {
display: inline-block;
@@ -305,9 +330,15 @@ input[type=text] {
font-weight: 500;
font-family: 'Pretendard', sans-serif;
padding: 0 10px;
+ letter-spacing: 0px;
&::placeholder {
font-size: 12px;
+ letter-spacing: 0px;
+ }
+
+ &.block {
+ width: 100%;
}
}
}
@@ -428,4 +459,24 @@ input[type=text] {
}
}
}
+
+ &.dark {
+ text-align: center;
+ background-color: #272727;
+ border: 1px solid #484848;
+
+ span {
+ color: #Fff;
+
+ &:after {
+ background: url(../../public/static/images/canvas/arr_btn_ico_white.svg) no-repeat center;
+ }
+ }
+
+ &:hover,
+ &.act {
+ background-color: #1083E3;
+ border: 1px solid #1083E3;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/styles/common.scss b/src/styles/common.scss
index 8152784c..b9a87417 100644
--- a/src/styles/common.scss
+++ b/src/styles/common.scss
@@ -1,2 +1,3 @@
@import 'fonts.scss';
-@import 'reset.scss';
\ No newline at end of file
+@import 'reset.scss';
+@import '_layout.scss';
diff --git a/src/styles/contents.scss b/src/styles/contents.scss
new file mode 100644
index 00000000..90dfa532
--- /dev/null
+++ b/src/styles/contents.scss
@@ -0,0 +1,2 @@
+@import '_contents.scss';
+@import '_modal.scss';
\ No newline at end of file
diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js
index 8d8a28ec..7a20a2b4 100644
--- a/src/util/qpolygon-utils.js
+++ b/src/util/qpolygon-utils.js
@@ -967,6 +967,11 @@ export const splitPolygonWithLines = (polygon) => {
const roofs = []
const allLines = [...polygon.innerLines]
+ allLines.forEach((line) => {
+ line.startPoint = { x: line.x1, y: line.y1 }
+ line.endPoint = { x: line.x2, y: line.y2 }
+ })
+
// allLines에 x1,y1,x2,y2를 비교해서 중복되는 값을 제거한다.
allLines.forEach((line, index) => {
const startPoint = line.startPoint
@@ -1207,7 +1212,7 @@ const drawRoofRidge = (polygon, chon) => {
const walls = polygon.wall.lines // 외벽의 라인
const roofs = polygon.lines // 지붕의 라인
- const ridgeWall = []
+ let ridgeWall = []
walls.forEach((wall, index) => {
let currentRoof, prevWall, currentWall, nextWall
@@ -1227,7 +1232,7 @@ const drawRoofRidge = (polygon, chon) => {
nextWall = walls[index + 1]
}
- if (getLineDirection(prevWall) !== getLineDirection(nextWall) && currentWall.length < currentRoof.length) {
+ if (prevWall.direction !== nextWall.direction && currentWall.length < currentRoof.length) {
ridgeWall.push({ index: index, wall: currentWall, length: currentWall.length })
}
})
@@ -1503,6 +1508,7 @@ const drawRoofRidge = (polygon, chon) => {
fontSize: polygon.fontSize,
stroke: 'blue',
strokeWidth: 1,
+ name: 'ridgeLine',
},
)
polygon.canvas.add(ridge)
@@ -1657,6 +1663,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1686,6 +1693,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1715,6 +1723,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1744,6 +1753,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1814,6 +1824,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1839,6 +1850,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1868,6 +1880,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -1897,6 +1910,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -2204,6 +2218,7 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
@@ -2283,12 +2298,14 @@ const drawHips = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'red',
strokeWidth: 1,
+ name: 'hipLine',
})
polygon.canvas.add(hip)
polygon.hips.push(hip)
polygon.innerLines.push(hip)
}
})
+ console.log('polygon.hips : ', polygon.hips)
}
const getPointInPolygon = (polygon, point, isInclude = false) => {
@@ -2565,20 +2582,28 @@ const connectLinePoint = (polygon) => {
fontSize: polygon.fontSize,
stroke: 'blue',
strokeWidth: 1,
+ name: 'ridgeLine',
})
- polygon.canvas.remove(ridge)
- polygon.canvas.remove(ridge2)
- polygon.ridges = polygon.ridges.filter((r) => !(ridge.x1 === r.x1 && ridge.y1 === r.y1 && ridge.x2 === r.x2 && ridge.y2 === r.y2))
- polygon.ridges = polygon.ridges.filter((r) => !(ridge2.x1 === r.x1 && ridge2.y1 === r.y1 && ridge2.x2 === r.x2 && ridge2.y2 === r.y2))
- polygon.innerLines = polygon.innerLines.filter((r) => !(ridge.x1 === r.x1 && ridge.y1 === r.y1 && ridge.x2 === r.x2 && ridge.y2 === r.y2))
- polygon.innerLines = polygon.innerLines.filter((r) => !(ridge2.x1 === r.x1 && ridge2.y1 === r.y1 && ridge2.x2 === r.x2 && ridge2.y2 === r.y2))
+ console.log('newRidge : ', newRidge)
+ if (polygon.ridges.filter((r) => newRidge.x1 === r.x1 && newRidge.y1 === r.y1 && newRidge.x2 === r.x2 && newRidge.y2 === r.y2).length === 0) {
+ polygon.canvas.remove(ridge)
+ polygon.canvas.remove(ridge2)
+ polygon.ridges = polygon.ridges.filter((r) => !(ridge.x1 === r.x1 && ridge.y1 === r.y1 && ridge.x2 === r.x2 && ridge.y2 === r.y2))
+ polygon.ridges = polygon.ridges.filter((r) => !(ridge2.x1 === r.x1 && ridge2.y1 === r.y1 && ridge2.x2 === r.x2 && ridge2.y2 === r.y2))
+ polygon.innerLines = polygon.innerLines.filter((r) => !(ridge.x1 === r.x1 && ridge.y1 === r.y1 && ridge.x2 === r.x2 && ridge.y2 === r.y2))
+ polygon.innerLines = polygon.innerLines.filter(
+ (r) => !(ridge2.x1 === r.x1 && ridge2.y1 === r.y1 && ridge2.x2 === r.x2 && ridge2.y2 === r.y2),
+ )
- polygon.canvas.add(newRidge)
- polygon.ridges.push(newRidge)
- polygon.innerLines.push(newRidge)
+ polygon.canvas.add(newRidge)
+ polygon.ridges.push(newRidge)
+ polygon.innerLines.push(newRidge)
+ }
}
})
})
+
+ console.log('polygon : ', polygon)
}
/*
@@ -2654,6 +2679,310 @@ const getLineDirection = (line) => {
}
}
+export const changeAllGableRoof = (polygon, offset, canvas) => {
+ const roof = polygon.filter((p) => p.name === 'roofBase')[0] // 지붕
+ const roofLines = roof.lines // 지붕의 라인
+ const ridges = roof.ridges // 마루의 라인
+ const hips = roof.hips // 추녀마루의 라인
+
+ ridges.forEach((ridge) => {
+ let ridgeHip1 = hips.filter((hip) => hip.x2 === ridge.x1 && hip.y2 === ridge.y1)
+ let ridgeHip2 = hips.filter((hip) => hip.x2 === ridge.x2 && hip.y2 === ridge.y2)
+ let gableLines = []
+ if (ridgeHip1.length > 1) {
+ let x1 = ridgeHip1[0].x1,
+ y1 = ridgeHip1[0].y1,
+ x2 = ridgeHip1[1].x1,
+ y2 = ridgeHip1[1].y1
+ roofLines.filter((roofLine) => {
+ if (
+ (roofLine.x1 === x1 && roofLine.y1 === y1 && roofLine.x2 === x2 && roofLine.y2 === y2) ||
+ (roofLine.x1 === x2 && roofLine.y1 === y2 && roofLine.x2 === x1 && roofLine.y2 === y1)
+ ) {
+ gableLines.push(setGableRoof(polygon, ridge, ridgeHip1[0], ridgeHip1[1], offset, canvas))
+ }
+ })
+ }
+ if (ridgeHip2.length > 1) {
+ let x1 = ridgeHip2[0].x1,
+ y1 = ridgeHip2[0].y1,
+ x2 = ridgeHip2[1].x1,
+ y2 = ridgeHip2[1].y1
+ roofLines.filter((roofLine) => {
+ if (
+ (roofLine.x1 === x1 && roofLine.y1 === y1 && roofLine.x2 === x2 && roofLine.y2 === y2) ||
+ (roofLine.x1 === x2 && roofLine.y1 === y2 && roofLine.x2 === x1 && roofLine.y2 === y1)
+ ) {
+ gableLines.push(setGableRoof(polygon, ridge, ridgeHip2[0], ridgeHip2[1], offset, canvas))
+ }
+ })
+ }
+ gableLines.forEach((gableLine) => {
+ roof.innerLines.push(gableLine)
+ })
+ })
+
+ // splitPolygonWithLines(roof)
+}
+
+const setGableRoof = (polygon, ridge, hip1, hip2, offset, canvas) => {
+ let x1 = hip1.x1,
+ y1 = hip1.y1
+ let gableLine, diffOffset
+ if (ridge.direction === 'top') {
+ if (ridge.y1 > y1 && ridge.y2 > y1) {
+ offset = Math.abs(ridge.y1 - y1) - offset
+ ridge.set({
+ x1: ridge.x1,
+ y1: ridge.y1,
+ x2: ridge.x2,
+ y2: ridge.y2 + offset,
+ })
+
+ gableLine = new QLine([ridge.x2 - offset, ridge.y2, ridge.x2 + offset, ridge.y2], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x1 < hip1.x2 ? hip1.x2 - offset : hip1.x2 + offset,
+ y2: hip1.y2 + offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x1 < hip2.x2 ? hip2.x2 - offset : hip2.x2 + offset,
+ y2: hip2.y2 + offset,
+ })
+ }
+ if (ridge.y1 < y1 && ridge.y2 < y1) {
+ offset = Math.abs(ridge.y2 - y1) - offset
+ ridge.set({
+ x1: ridge.x1,
+ y1: ridge.y1 - offset,
+ x2: ridge.x2,
+ y2: ridge.y2,
+ })
+ gableLine = new QLine([ridge.x1 - offset, ridge.y1, ridge.x1 + offset, ridge.y1], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x1 < hip1.x2 ? hip1.x2 - offset : hip1.x2 + offset,
+ y2: hip1.y2 - offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x1 < hip2.x2 ? hip2.x2 - offset : hip2.x2 + offset,
+ y2: hip2.y2 - offset,
+ })
+ }
+ }
+ if (ridge.direction === 'bottom') {
+ if (ridge.y1 > y1 && ridge.y2 > y1) {
+ offset = Math.abs(ridge.y1 - y1) - offset
+ ridge.set({
+ x1: ridge.x1,
+ y1: ridge.y1 - offset,
+ x2: ridge.x2,
+ y2: ridge.y2,
+ })
+ gableLine = new QLine([ridge.x1 - offset, ridge.y1, ridge.x1 + offset, ridge.y1], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x1 < hip1.x2 ? hip1.x2 - offset : hip1.x2 + offset,
+ y2: hip1.y2 - offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x1 < hip2.x2 ? hip2.x2 - offset : hip2.x2 + offset,
+ y2: hip2.y2 - offset,
+ })
+ }
+ if (ridge.y1 < y1 && ridge.y2 < y1) {
+ offset = Math.abs(ridge.y2 - y1) - offset
+ ridge.set({
+ x1: ridge.x1,
+ y1: ridge.y1,
+ x2: ridge.x2,
+ y2: ridge.y2 + offset,
+ })
+
+ gableLine = new QLine([ridge.x2 - offset, ridge.y2, ridge.x2 + offset, ridge.y2], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x1 < hip1.x2 ? hip1.x2 - offset : hip1.x2 + offset,
+ y2: hip1.y2 + offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x1 < hip2.x2 ? hip2.x2 - offset : hip2.x2 + offset,
+ y2: hip2.y2 + offset,
+ })
+ }
+ }
+ if (ridge.direction === 'right') {
+ if (ridge.x1 > x1 && ridge.x2 > x1) {
+ offset = Math.abs(ridge.x1 - x1) - offset
+ ridge.set({
+ x1: ridge.x1 - offset,
+ y1: ridge.y1,
+ x2: ridge.x2,
+ y2: ridge.y2,
+ })
+ gableLine = new QLine([ridge.x1, ridge.y1 - offset, ridge.x1, ridge.y1 + offset], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x2 - offset,
+ y2: hip1.y1 < hip1.y2 ? hip1.y2 - offset : hip1.y2 + offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x2 - offset,
+ y2: hip2.y1 < hip2.y2 ? hip2.y2 - offset : hip2.y2 + offset,
+ })
+ }
+ if (ridge.x1 < x1 && ridge.x2 < x1) {
+ offset = Math.abs(ridge.x2 - x1) - offset
+ ridge.set({
+ x1: ridge.x1,
+ y1: ridge.y1,
+ x2: ridge.x2 + offset,
+ y2: ridge.y2,
+ })
+ gableLine = new QLine([ridge.x2, ridge.y2 - offset, ridge.x2, ridge.y2 + offset], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x2 + offset,
+ y2: hip1.y1 < hip1.y2 ? hip1.y2 - offset : hip1.y2 + offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x2 + offset,
+ y2: hip2.y1 < hip2.y2 ? hip2.y2 - offset : hip2.y2 + offset,
+ })
+ }
+ }
+ if (ridge.direction === 'left') {
+ if (ridge.x1 > x1 && ridge.x2 > x1) {
+ offset = Math.abs(ridge.x1 - x1) - offset
+ ridge.set({
+ x1: ridge.x1,
+ y1: ridge.y1,
+ x2: ridge.x2 + offset,
+ y2: ridge.y2,
+ })
+ gableLine = new QLine([ridge.x2, ridge.y2 - offset, ridge.x2, ridge.y2 + offset], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x2 + offset,
+ y2: hip1.y1 < hip1.y2 ? hip1.y2 - offset : hip1.y2 + offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x2 + offset,
+ y2: hip2.y1 < hip2.y2 ? hip2.y2 - offset : hip2.y2 + offset,
+ })
+ }
+ if (ridge.x1 < x1 && ridge.x2 < x1) {
+ offset = Math.abs(ridge.x2 - x1) - offset
+ ridge.set({
+ x1: ridge.x1 - offset,
+ y1: ridge.y1,
+ x2: ridge.x2,
+ y2: ridge.y2,
+ })
+ gableLine = new QLine([ridge.x1, ridge.y1 - offset, ridge.x1, ridge.y1 + offset], {
+ fontSize: polygon.fontSize,
+ stroke: 'blue',
+ strokeWidth: 1,
+ name: 'gableLine',
+ })
+ canvas?.add(gableLine)
+
+ hip1.set({
+ x1: hip1.x1,
+ y1: hip1.y1,
+ x2: hip1.x2 - offset,
+ y2: hip1.y1 < hip1.y2 ? hip1.y2 - offset : hip1.y2 + offset,
+ })
+
+ hip2.set({
+ x1: hip2.x1,
+ y1: hip2.y1,
+ x2: hip2.x2 - offset,
+ y2: hip2.y1 < hip2.y2 ? hip2.y2 - offset : hip2.y2 + offset,
+ })
+ }
+ }
+ canvas?.renderAll()
+ return gableLine
+}
+
function arePointsEqual(point1, point2) {
return point1.x === point2.x && point1.y === point2.y
}