popupManager 개발 중
This commit is contained in:
parent
07e11f3148
commit
15af4655a3
@ -15,6 +15,7 @@ import './globals.css'
|
||||
import '../styles/style.scss'
|
||||
import '../styles/contents.scss'
|
||||
import Dimmed from '@/components/ui/Dimmed'
|
||||
import PopupManager from '@/components/common/popupManager/PopupManager'
|
||||
|
||||
// const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
@ -81,6 +82,7 @@ export default async function RootLayout({ children }) {
|
||||
)}
|
||||
<ToastContainer />
|
||||
<QModal />
|
||||
<PopupManager />
|
||||
</body>
|
||||
</html>
|
||||
</RecoilRootWrapper>
|
||||
|
||||
@ -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 { changeAllHipAndGableRoof, drawDirectionStringToArrow } from '@/util/qpolygon-utils'
|
||||
import { drawDirectionStringToArrow } from '@/util/qpolygon-utils'
|
||||
import ThumbnailList from '@/components/ui/ThumbnailLIst'
|
||||
import ObjectPlacement from '@/components/ui/ObjectPlacement'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
|
||||
@ -1,11 +1,30 @@
|
||||
import { HexColorPicker } from 'react-colorful'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
|
||||
export default function ColorPicker(props) {
|
||||
const { color, setColor } = props
|
||||
|
||||
const { getMessage } = useMessage()
|
||||
const defaultColors = ['#EA575D', '#F29955', '#F2C957', '#32975D', '#3D7FED', '#828282', '#ffffff', '#000000']
|
||||
return (
|
||||
<>
|
||||
<HexColorPicker color={color} onChange={setColor} />
|
||||
<div>
|
||||
<HexColorPicker color={color} onChange={setColor} />
|
||||
</div>
|
||||
<div className="hex-color-box">
|
||||
<div className="color-box-tit">HEX</div>
|
||||
<div className="color-hex-input">
|
||||
<input type="text" className="input-origin" value={color} onChange={(e) => setColor(e.target.value)} />
|
||||
</div>
|
||||
<div className="color-box" style={{ backgroundColor: color }}></div>
|
||||
</div>
|
||||
<div className="default-color-wrap">
|
||||
<div className="default-tit">{getMessage('modal.color.picker.default.color')}</div>
|
||||
<div className="color-button-wrap">
|
||||
{defaultColors.map((color, index) => (
|
||||
<button key={index} className="default-color" style={{ backgroundColor: color }} onClick={() => setColor(color)}></button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
44
src/components/common/color-picker/ColorPickerModal.jsx
Normal file
44
src/components/common/color-picker/ColorPickerModal.jsx
Normal file
@ -0,0 +1,44 @@
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import ColorPicker from '@/components/common/color-picker/ColorPicker'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export default function ColorPickerModal(props) {
|
||||
const { isShow, setIsShow, pos = { x: 800, y: -950 }, color = '#ff0000', setColor } = props
|
||||
const { getMessage } = useMessage()
|
||||
const [originColor, setOriginColor] = useState(color)
|
||||
useEffect(() => {
|
||||
setOriginColor(color)
|
||||
}, [isShow])
|
||||
return (
|
||||
<WithDraggable isShow={isShow} pos={pos}>
|
||||
<div className={`modal-pop-wrap lr`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage('modal.color.picker.title')}</h1>
|
||||
<button className="modal-close" onClick={() => setIsShow(false)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="color-setting-wrap">
|
||||
<div className="color-tit">COLOR PICKER</div>
|
||||
<div className="color-picker">
|
||||
<ColorPicker color={originColor} setColor={setOriginColor} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button
|
||||
className="btn-frame modal act"
|
||||
onClick={() => {
|
||||
setColor(originColor)
|
||||
setIsShow(false)
|
||||
}}
|
||||
>
|
||||
{getMessage('common.message.save')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
)
|
||||
}
|
||||
69
src/components/common/font/FontSetting.jsx
Normal file
69
src/components/common/font/FontSetting.jsx
Normal file
@ -0,0 +1,69 @@
|
||||
import WithDraggable from '@/components/common/draggable/withDraggable'
|
||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||
|
||||
const SelectOption = [{ name: '原寸' }, { name: '原寸' }, { name: '原寸' }, { name: '原寸' }]
|
||||
export default function FontSetting(props) {
|
||||
const { setShowFontSettingModal } = props
|
||||
console.log(
|
||||
Array.from({ length: 10 }).map((_, index) => {
|
||||
return { name: 5 + index }
|
||||
}),
|
||||
)
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: 800, y: -950 }}>
|
||||
<div className={`modal-pop-wrap r`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">フォント </h1>
|
||||
<button className="modal-close" onClick={() => setShowFontSettingModal(false)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="slope-wrap">
|
||||
<div className="font-option-warp">
|
||||
<div className="font-option-item">
|
||||
<div className="option-item-tit">文字(F)</div>
|
||||
<div className="grid-select">
|
||||
<QSelectBox title={'MS PGothic'} option={SelectOption} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="font-option-item">
|
||||
<div className="option-item-tit">フォントスタイル(Y)</div>
|
||||
<div className="grid-select">
|
||||
<QSelectBox title={'いつもの'} option={SelectOption} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="font-option-item">
|
||||
<div className="option-item-tit">サイズ(S)</div>
|
||||
<div className="grid-select">
|
||||
<QSelectBox
|
||||
title={'8'}
|
||||
options={Array.from({ length: 9 }).map((_, index) => {
|
||||
return { id: index, name: 8 * (index + 1) }
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="font-option-item">
|
||||
<div className="option-item-tit">フォン</div>
|
||||
<div className="grid-select">
|
||||
<QSelectBox title={'黒'} option={SelectOption} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="font-ex-wrap">
|
||||
<div className="font-ex-tit">見る</div>
|
||||
<div className="font-ex-box">
|
||||
<span style={{ fontSize: '12px', fontWeight: '400', color: '#101010' }}>Aaあぁアァ</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="normal-font">ントです。プリンタと画面 でも同じフォントを使用します.</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal act">ストレージ</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
)
|
||||
}
|
||||
8
src/components/common/popupManager/PopupManager.jsx
Normal file
8
src/components/common/popupManager/PopupManager.jsx
Normal file
@ -0,0 +1,8 @@
|
||||
'use client'
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { popupState } from '@/store/popupAtom'
|
||||
|
||||
export default function PopupManager() {
|
||||
const [popup, setPopup] = useRecoilState(popupState)
|
||||
return <>{popup.children?.map((child) => child.component)}</>
|
||||
}
|
||||
@ -8,11 +8,18 @@ import QContextMenu from '@/components/common/context-menu/QContextMenu'
|
||||
import { useContextMenu } from '@/hooks/useContextMenu'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { currentObjectState } from '@/store/canvasAtom'
|
||||
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
||||
|
||||
export default function CanvasFrame({ plan }) {
|
||||
const canvasRef = useRef(null)
|
||||
const { canvas } = useCanvas('canvas')
|
||||
const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu()
|
||||
const { handleZoomClear } = useCanvasEvent()
|
||||
const { contextMenu, currentContextMenu, setCurrentContextMenu } = useContextMenu({
|
||||
externalFn: {
|
||||
handleZoomClear,
|
||||
},
|
||||
})
|
||||
|
||||
const currentObject = useRecoilValue(currentObjectState)
|
||||
|
||||
useEffect(() => {
|
||||
@ -44,7 +51,17 @@ export default function CanvasFrame({ plan }) {
|
||||
{contextMenu.map((menus, index) => (
|
||||
<ul key={index}>
|
||||
{menus.map((menu) => (
|
||||
<li onClick={(e) => setCurrentContextMenu(menu)}>{menu.name}</li>
|
||||
<li
|
||||
key={menu.id}
|
||||
onClick={(e) => {
|
||||
if (menu.fn) {
|
||||
menu.fn()
|
||||
}
|
||||
setCurrentContextMenu(menu)
|
||||
}}
|
||||
>
|
||||
{menu.name}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
))}
|
||||
|
||||
@ -19,6 +19,10 @@ import { MENU } from '@/common/common'
|
||||
import KO from '@/locales/ko.json'
|
||||
import JA from '@/locales/ja.json'
|
||||
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
||||
import { useCanvasEvent } from '@/hooks/useCanvasEvent'
|
||||
import { popupState } from '@/store/popupAtom'
|
||||
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
|
||||
import { usePopup } from '@/hooks/usePopup'
|
||||
|
||||
const canvasMenus = [
|
||||
{ index: 0, name: 'plan.menu.plan.drawing', icon: 'con00', title: MENU.PLAN_DRAWING },
|
||||
@ -52,6 +56,7 @@ export default function CanvasMenu(props) {
|
||||
setShowPropertiesSettingModal,
|
||||
} = props
|
||||
|
||||
const { addPopup, closePopup } = usePopup()
|
||||
const [menuNumber, setMenuNumber] = useState(null)
|
||||
const [type, setType] = useState('')
|
||||
|
||||
@ -61,6 +66,7 @@ export default function CanvasMenu(props) {
|
||||
const setPoints = useSetRecoilState(outerLinePointsState)
|
||||
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||
const [currentCanvasPlan, setcurrentCanvasPlan] = useRecoilState(currentCanvasPlanState)
|
||||
const { handleZoomClear } = useCanvasEvent()
|
||||
|
||||
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
@ -69,7 +75,7 @@ export default function CanvasMenu(props) {
|
||||
const { getMessage } = useMessage()
|
||||
const { saveCanvas } = usePlan()
|
||||
const { swalFire } = useSwal()
|
||||
|
||||
const [popup, setPopup] = useRecoilState(popupState)
|
||||
const SelectOption = [{ name: '瓦53A' }, { name: '瓦53A' }]
|
||||
const onClickNav = (menu) => {
|
||||
setMenuNumber(menu.index)
|
||||
@ -143,13 +149,13 @@ export default function CanvasMenu(props) {
|
||||
setPoints([])
|
||||
canvas?.clear()
|
||||
}
|
||||
|
||||
const handleZoomClear = () => {
|
||||
setCanvasZoom(100)
|
||||
canvas.set({ zoom: 1 })
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
||||
canvas.renderAll()
|
||||
}
|
||||
//
|
||||
// const handleZoomClear = () => {
|
||||
// setCanvasZoom(100)
|
||||
// canvas.set({ zoom: 1 })
|
||||
// canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
||||
// canvas.renderAll()
|
||||
// }
|
||||
|
||||
useEffect(() => {
|
||||
if (globalLocale === 'ko') {
|
||||
@ -196,7 +202,8 @@ export default function CanvasMenu(props) {
|
||||
<QSelectBox title={'瓦53A'} option={SelectOption} />
|
||||
</div>
|
||||
<div className="btn-from">
|
||||
<button className="btn04" onClick={() => setShowCanvasSettingModal(true)}></button>
|
||||
{/*<button className="btn04" onClick={() => setShowCanvasSettingModal(true)}></button>*/}
|
||||
<button className="btn04" onClick={() => addPopup(<SettingModal01 />)}></button>
|
||||
<button className="btn05"></button>
|
||||
<button className="btn06"></button>
|
||||
</div>
|
||||
|
||||
@ -1,19 +1,17 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { globalLocaleStore } from '@/store/localeAtom'
|
||||
import { settingModalFirstOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
|
||||
import { settingModalFirstOptionsState, settingModalGridOptionsState, settingModalSecondOptionsState } from '@/store/settingAtom'
|
||||
import '@/styles/contents.scss'
|
||||
import CanvasMenu from '@/components/floor-plan/CanvasMenu'
|
||||
import SettingModal01 from '@/components/floor-plan/modal/setting01/SettingModal01'
|
||||
import CanvasLayout from '@/components/floor-plan/CanvasLayout'
|
||||
import DotLineGrid from '@/components/floor-plan/modal/grid/DotLineGrid'
|
||||
import WallLineSetting from '@/components/floor-plan/modal/outerlinesetting/WallLineSetting'
|
||||
import PropertiesSetting from '@/components/floor-plan/modal/outerlinesetting/PropertiesSetting'
|
||||
import PlacementShapeSetting from '@/components/floor-plan/modal/placementShape/PlacementShapeSetting'
|
||||
import GridColorSetting from './modal/grid/GridColorSetting'
|
||||
import RoofShapeSetting from '@/components/floor-plan/modal/roofShape/RoofShapeSetting'
|
||||
import PlacementShapeDrawing from '@/components/floor-plan/modal/placementShape/PlacementShapeDrawing'
|
||||
import Slope from '@/components/floor-plan/modal/Slope'
|
||||
@ -28,6 +26,8 @@ import MovementSetting from '@/components/floor-plan/modal/movement/MovementSett
|
||||
import RoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/RoofAllocationSetting'
|
||||
import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting'
|
||||
import CircuitTrestleSetting from '@/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting'
|
||||
import FontSetting from '@/components/common/font/FontSetting'
|
||||
import { gridColorState } from '@/store/gridAtom'
|
||||
|
||||
export default function FloorPlan() {
|
||||
const [showCanvasSettingModal, setShowCanvasSettingModal] = useState(false)
|
||||
@ -58,10 +58,15 @@ export default function FloorPlan() {
|
||||
const [showGridCopyModal, setShowGridCopyModal] = useState(false)
|
||||
const [showGridMoveModal, setShowGridMoveModal] = useState(false)
|
||||
const [showColorPickerModal, setShowColorPickerModal] = useState(false)
|
||||
const [color, setColor] = useRecoilState(gridColorState)
|
||||
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
|
||||
const [showFontSettingModal, setShowFontSettingModal] = useState(false)
|
||||
|
||||
const canvasSettingProps = {
|
||||
setShowCanvasSettingModal,
|
||||
setShowDotLineGridModal,
|
||||
setShowColorPickerModal,
|
||||
setShowFontSettingModal,
|
||||
}
|
||||
|
||||
const outlineProps = {
|
||||
@ -127,6 +132,9 @@ export default function FloorPlan() {
|
||||
|
||||
const gridColorProps = {
|
||||
setShowColorPickerModal,
|
||||
color,
|
||||
setColor,
|
||||
setSettingModalGridOptions,
|
||||
}
|
||||
|
||||
const propertiesSettingProps = {
|
||||
@ -141,12 +149,13 @@ export default function FloorPlan() {
|
||||
<CanvasMenu {...modalProps} />
|
||||
<div className="canvas-content">
|
||||
<CanvasLayout />
|
||||
{showCanvasSettingModal && <SettingModal01 {...canvasSettingProps} />}
|
||||
{/*{showCanvasSettingModal && <SettingModal01 {...canvasSettingProps} />}*/}
|
||||
{showOutlineModal && <WallLineSetting {...outlineProps} />}
|
||||
{showDotLineGridModal && <DotLineGrid {...dotLineProps} />}
|
||||
{showColorPickerModal && <GridColorSetting {...gridColorProps} />}
|
||||
{/*{showColorPickerModal && <GridColorSetting {...gridColorProps} />}*/}
|
||||
{showFontSettingModal && <FontSetting setShowFontSettingModal={setShowFontSettingModal} />}
|
||||
{showPropertiesSettingModal && <PropertiesSetting {...propertiesSettingProps} />}
|
||||
|
||||
{/*<DimensionLineSetting setShowFontSettingModal={setShowFontSettingModal} setShowColorPickerModal={setShowColorPickerModal} />*/}
|
||||
{showPlaceShapeModal && <PlacementShapeSetting setShowPlaceShapeModal={setShowPlaceShapeModal} />}
|
||||
{showRoofShapeSettingModal && <RoofShapeSetting setShowRoofShapeSettingModal={setShowRoofShapeSettingModal} />}
|
||||
{showRoofShapePassivitySettingModal && (
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { useState } from 'react'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import RightAngle from '@/components/floor-plan/modal/lineTypes/RightAngle'
|
||||
@ -6,7 +5,6 @@ import DoublePitch from '@/components/floor-plan/modal/lineTypes/DoublePitch'
|
||||
import Angle from '@/components/floor-plan/modal/lineTypes/Angle'
|
||||
import Diagonal from '@/components/floor-plan/modal/lineTypes/Diagonal'
|
||||
import { OUTER_LINE_TYPE } from '@/store/outerLineAtom'
|
||||
import { useOuterLineWall } from '@/hooks/roofcover/useOuterLineWall'
|
||||
import OuterLineWall from '@/components/floor-plan/modal/lineTypes/OuterLineWall'
|
||||
import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing'
|
||||
|
||||
@ -152,7 +150,7 @@ export default function AuxiliaryDrawing({ setShowAuxiliaryModal }) {
|
||||
{getMessage('modal.cover.outline.rollback')}
|
||||
</button>
|
||||
<button className="btn-frame modal act" onClick={() => handleFix(setShowAuxiliaryModal)}>
|
||||
{getMessage('modal.cover.outline.fix')}
|
||||
{getMessage('apply')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
import WithDraggable from '@/components/common/draggable/WithDraggable'
|
||||
import ColorPicker from '@/components/common/color-picker/ColorPicker'
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil'
|
||||
import { gridColorState } from '@/store/gridAtom'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useEffect } from 'react'
|
||||
import { settingModalGridOptionsState } from '@/store/settingAtom'
|
||||
|
||||
export default function GridColorSetting(props) {
|
||||
const { setShowColorPickerModal } = props
|
||||
const [color, setColor] = useRecoilState(gridColorState)
|
||||
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
|
||||
const { getMessage } = useMessage()
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
setSettingModalGridOptions((prev) => {
|
||||
const newSettingOptions = [...prev]
|
||||
newSettingOptions[3].selected = false
|
||||
return [...newSettingOptions]
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: 1300, y: -660 }}>
|
||||
<div className={`modal-pop-wrap ssm mount`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage('modal.canvas.setting.grid.color.setting')}</h1>
|
||||
<button className="modal-close" onClick={() => setShowColorPickerModal(false)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<ColorPicker color={color} setColor={setColor} />
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
)
|
||||
}
|
||||
@ -1,27 +1,45 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useRecoilState } from 'recoil'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil'
|
||||
import { settingModalGridOptionsState } from '@/store/settingAtom'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { adsorptionPointAddModeState } from '@/store/canvasAtom'
|
||||
import { useTempGrid } from '@/hooks/useTempGrid'
|
||||
import { gridColorState } from '@/store/gridAtom'
|
||||
import { useColor } from 'react-color-palette'
|
||||
import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal'
|
||||
|
||||
export default function GridOption(props) {
|
||||
const { setShowDotLineGridModal, setShowColorPickerModal } = props
|
||||
const { setShowDotLineGridModal } = props
|
||||
const [gridOptions, setGridOptions] = useRecoilState(settingModalGridOptionsState)
|
||||
const [gridColor, setGridColor] = useRecoilState(gridColorState)
|
||||
const [adsorptionPointAddMode, setAdsorptionPointAddMode] = useRecoilState(adsorptionPointAddModeState)
|
||||
const setSettingModalGridOptions = useSetRecoilState(settingModalGridOptionsState)
|
||||
const { getMessage } = useMessage()
|
||||
const { tempGridMode, setTempGridMode } = useTempGrid()
|
||||
|
||||
const [gridColor, setGridColor] = useRecoilState(gridColorState)
|
||||
const [color, setColor] = useColor(gridColor)
|
||||
const [showColorPickerModal, setShowColorPickerModal] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
console.log('GridOption useEffect 실행')
|
||||
console.log(color)
|
||||
setGridColor(color.hex)
|
||||
}, [color])
|
||||
|
||||
useEffect(() => {
|
||||
gridOptions[3].selected = showColorPickerModal
|
||||
setGridOptions([...gridOptions])
|
||||
}, [showColorPickerModal])
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
setSettingModalGridOptions((prev) => {
|
||||
const newSettingOptions = [...prev]
|
||||
newSettingOptions[3].selected = false
|
||||
return [...newSettingOptions]
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
const onClickOption = (option) => {
|
||||
const newGridOptions = [...gridOptions]
|
||||
newGridOptions.map((item) => {
|
||||
@ -54,6 +72,7 @@ export default function GridOption(props) {
|
||||
|
||||
if (option.id === 4) {
|
||||
// 그리드 색 설정
|
||||
console.log(option)
|
||||
if (option.selected) {
|
||||
setShowColorPickerModal(true)
|
||||
} else {
|
||||
@ -64,6 +83,17 @@ export default function GridOption(props) {
|
||||
setGridOptions(newGridOptions)
|
||||
}
|
||||
|
||||
const colorPickerProps = {
|
||||
color: gridColor,
|
||||
setColor: setGridColor,
|
||||
isShow: showColorPickerModal,
|
||||
setIsShow: setShowColorPickerModal,
|
||||
pos: {
|
||||
x: -515,
|
||||
y: -214,
|
||||
},
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="modal-check-btn-wrap">
|
||||
@ -77,6 +107,7 @@ export default function GridOption(props) {
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<ColorPickerModal {...colorPickerProps} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -5,8 +5,9 @@ import React, { useEffect, useState } from 'react'
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import { adsorptionPointModeState, adsorptionRangeState } from '@/store/canvasAtom'
|
||||
import DimensionLineSetting from '@/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting'
|
||||
|
||||
export default function SecondOption() {
|
||||
export default function SecondOption({ setShowFontSettingModal }) {
|
||||
const [objectNo, setObjectNo] = useState('test123240912001') // 이후 삭제 필요
|
||||
const [settingModalFirstOptions, setSettingModalFirstOptions] = useRecoilState(settingModalFirstOptionsState)
|
||||
const [settingModalSecondOptions, setSettingModalSecondOptions] = useRecoilState(settingModalSecondOptionsState)
|
||||
@ -18,6 +19,15 @@ export default function SecondOption() {
|
||||
const { getMessage } = useMessage()
|
||||
const { get, post } = useAxios()
|
||||
const { swalFire } = useSwal()
|
||||
const [showDimensionLineSettingModal, setShowDimensionLineSettingModal] = useState(false)
|
||||
const dimensionLineSettingProps = {
|
||||
isShow: showDimensionLineSettingModal,
|
||||
setIsShow: setShowDimensionLineSettingModal,
|
||||
pos: {
|
||||
x: -515,
|
||||
y: -214,
|
||||
},
|
||||
}
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
@ -31,7 +41,10 @@ export default function SecondOption() {
|
||||
const res = await get({ url: `/api/canvas-management/canvas-settings/by-object/${objectNo}` })
|
||||
const optionData1 = settingModalFirstOptions.option1.map((item) => ({ ...item, selected: res[item.column] }))
|
||||
const optionData2 = settingModalFirstOptions.option2.map((item) => ({ ...item, selected: res[item.column] }))
|
||||
const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({ ...item, selected: res[item.column] }))
|
||||
const optionData5 = settingModalFirstOptions.dimensionDisplay.map((item) => ({
|
||||
...item,
|
||||
selected: res[item.column],
|
||||
}))
|
||||
const optionData3 = settingModalSecondOptions.option3.map((item) => ({ ...item }))
|
||||
const optionData4 = settingModalSecondOptions.option4.map((item) => ({ ...item, selected: res[item.column] }))
|
||||
|
||||
@ -51,7 +64,14 @@ export default function SecondOption() {
|
||||
|
||||
const onClickOption = async (option) => {
|
||||
// option4에서 한 개만 선택 가능하도록 처리
|
||||
const updatedOption4 = option4.map((item) => (item.id === option.id ? { ...item, selected: true } : { ...item, selected: false }))
|
||||
const updatedOption4 = option4.map((item) =>
|
||||
item.id === option.id
|
||||
? { ...item, selected: true }
|
||||
: {
|
||||
...item,
|
||||
selected: false,
|
||||
},
|
||||
)
|
||||
|
||||
setSettingModalFirstOptions({ option1, option2, dimensionDisplay })
|
||||
setSettingModalSecondOptions({ option3, option4: updatedOption4 })
|
||||
@ -117,6 +137,7 @@ export default function SecondOption() {
|
||||
}
|
||||
setAdsorptionRange(option.range)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="modal-check-btn-wrap">
|
||||
@ -124,7 +145,7 @@ export default function SecondOption() {
|
||||
<div className="flex-check-box for2">
|
||||
{settingModalSecondOptions &&
|
||||
settingModalSecondOptions.option3.map((item) => (
|
||||
<button key={item.id} className="arr-btn">
|
||||
<button key={item.id} className="arr-btn" onClick={() => setShowFontSettingModal(true)}>
|
||||
<span>{getMessage(item.name)}</span>
|
||||
</button>
|
||||
))}
|
||||
@ -142,7 +163,7 @@ export default function SecondOption() {
|
||||
))}
|
||||
</div>
|
||||
<div className="flex-check-box for-line">
|
||||
<button className="arr-btn">
|
||||
<button className="arr-btn" onClick={() => setShowDimensionLineSettingModal(true)}>
|
||||
<span>{getMessage('modal.canvas.setting.font.plan.absorption.dimension.line')}</span>
|
||||
</button>
|
||||
<button className="arr-btn">
|
||||
@ -159,6 +180,7 @@ export default function SecondOption() {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<DimensionLineSetting {...dimensionLineSettingProps} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { canGridOptionSeletor } from '@/store/canvasAtom'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
|
||||
export default function SettingModal01(props) {
|
||||
const { setShowCanvasSettingModal, setShowDotLineGridModal, setShowColorPickerModal } = props
|
||||
const { setShowCanvasSettingModal, setShowDotLineGridModal, setShowFontSettingModal } = props
|
||||
const [buttonAct, setButtonAct] = useState(1)
|
||||
const { getMessage } = useMessage()
|
||||
const canGridOptionSeletorValue = useRecoilValue(canGridOptionSeletor)
|
||||
@ -20,34 +20,36 @@ export default function SettingModal01(props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={{ x: 1300, y: -950 }}>
|
||||
<div className={`modal-pop-wrap sm mount`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage('modal.canvas.setting')}</h1>
|
||||
<button className="modal-close" onClick={() => setShowCanvasSettingModal(false)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="modal-btn-wrap">
|
||||
<button className={`btn-frame modal ${buttonAct === 1 ? 'act' : ''}`} onClick={() => handleBtnClick(1)}>
|
||||
{getMessage('modal.canvas.setting.display')}
|
||||
<>
|
||||
<WithDraggable isShow={true} pos={{ x: 1300, y: -950 }}>
|
||||
<div className={`modal-pop-wrap sm mount`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage('modal.canvas.setting')}</h1>
|
||||
<button className="modal-close" onClick={() => setShowCanvasSettingModal(false)}>
|
||||
닫기
|
||||
</button>
|
||||
|
||||
<button className={`btn-frame modal ${buttonAct === 2 ? 'act' : ''}`} onClick={() => handleBtnClick(2)}>
|
||||
{getMessage('modal.canvas.setting.font.plan')}
|
||||
</button>
|
||||
{canGridOptionSeletorValue && (
|
||||
<button className={`btn-frame modal ${buttonAct === 3 ? 'act' : ''}`} onClick={() => handleBtnClick(3)}>
|
||||
{getMessage('modal.canvas.setting.grid')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{buttonAct === 1 && <FirstOption />}
|
||||
{buttonAct === 2 && <SecondOption />}
|
||||
{buttonAct === 3 && <GridOption setShowDotLineGridModal={setShowDotLineGridModal} setShowColorPickerModal={setShowColorPickerModal} />}
|
||||
<div className="modal-body">
|
||||
<div className="modal-btn-wrap">
|
||||
<button className={`btn-frame modal ${buttonAct === 1 ? 'act' : ''}`} onClick={() => handleBtnClick(1)}>
|
||||
{getMessage('modal.canvas.setting.display')}
|
||||
</button>
|
||||
|
||||
<button className={`btn-frame modal ${buttonAct === 2 ? 'act' : ''}`} onClick={() => handleBtnClick(2)}>
|
||||
{getMessage('modal.canvas.setting.font.plan')}
|
||||
</button>
|
||||
{canGridOptionSeletorValue && (
|
||||
<button className={`btn-frame modal ${buttonAct === 3 ? 'act' : ''}`} onClick={() => handleBtnClick(3)}>
|
||||
{getMessage('modal.canvas.setting.grid')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{buttonAct === 1 && <FirstOption />}
|
||||
{buttonAct === 2 && <SecondOption setShowFontSettingModal={setShowFontSettingModal} />}
|
||||
{buttonAct === 3 && <GridOption setShowDotLineGridModal={setShowDotLineGridModal} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
</WithDraggable>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
import WithDraggable from '@/components/common/draggable/withDraggable'
|
||||
|
||||
export default function DimensionLineSetting(props) {
|
||||
const { isShow, setIsShow, pos = { x: 800, y: -950 }, setShowFontSettingModal, setShowColorPickerModal } = props
|
||||
return (
|
||||
<WithDraggable isShow={isShow} pos={pos}>
|
||||
<div className={`modal-pop-wrap xxxm`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">寸法線 設定 </h1>
|
||||
<button className="modal-close">닫기</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="font-btn-wrap">
|
||||
<button className="btn-frame modal" onClick={() => setShowFontSettingModal(true)}>
|
||||
フォント設定
|
||||
</button>
|
||||
</div>
|
||||
<div className="line-color-wrap">
|
||||
<div className="outline-form mb10">
|
||||
<span style={{ width: 'auto' }}>寸法線の線太さ</span>
|
||||
<div className="input-grid mr5" style={{ width: '66px' }}>
|
||||
<input type="text" className="input-origin block" defaultValue={1} />
|
||||
</div>
|
||||
<span className="thin">pixel</span>
|
||||
</div>
|
||||
<div className="outline-form">
|
||||
<span style={{ width: 'auto' }}>寸法線の線の色</span>
|
||||
<button className="color-btn" style={{ backgroundColor: '#ff0000' }} onClick={() => setShowColorPickerModal(true)}></button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="font-ex-wrap">
|
||||
<div className="font-ex-tit">見る</div>
|
||||
<div className="form-box">
|
||||
<div className="line-form">
|
||||
<div className="line-font-box">
|
||||
<span className="font" style={{ fontSize: '12px', fontWeight: '400' }}>
|
||||
9,999
|
||||
</span>
|
||||
<span className="line" style={{ backgroundColor: '#ff0000', borderColor: '#ff0000', height: '1px' }}></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid-btn-wrap">
|
||||
<button className="btn-frame modal act">ストレージ</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithDraggable>
|
||||
)
|
||||
}
|
||||
@ -1,15 +1,17 @@
|
||||
import { useState } from 'react'
|
||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||
import { canvasSizeState, currentObjectState, fontFamilyState, fontSizeState } from '@/store/canvasAtom'
|
||||
import { canvasSizeState, canvasState, canvasZoomState, currentObjectState, fontFamilyState, fontSizeState } from '@/store/canvasAtom'
|
||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
|
||||
// 캔버스에 필요한 이벤트
|
||||
export function useCanvasEvent() {
|
||||
const [canvas, setCanvasForEvent] = useState(null)
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const [canvasForEvent, setCanvasForEvent] = useState(null)
|
||||
const [currentObject, setCurrentObject] = useRecoilState(currentObjectState)
|
||||
const canvasSize = useRecoilValue(canvasSizeState)
|
||||
const fontSize = useRecoilValue(fontSizeState)
|
||||
const fontFamily = useRecoilValue(fontFamilyState)
|
||||
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||
|
||||
// 기본적인 이벤트 필요시 추가
|
||||
const attachDefaultEventOnCanvas = () => {
|
||||
@ -167,7 +169,6 @@ export function useCanvasEvent() {
|
||||
const whiteList = ['mouseLine', 'guideLine']
|
||||
|
||||
if (whiteList.includes(e.target.name)) {
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -336,8 +337,16 @@ export function useCanvasEvent() {
|
||||
})
|
||||
}
|
||||
|
||||
const handleZoomClear = () => {
|
||||
setCanvasZoom(100)
|
||||
canvas.set({ zoom: 1 })
|
||||
canvas.viewportTransform = [1, 0, 0, 1, 0, 0]
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
return {
|
||||
setCanvasForEvent,
|
||||
attachDefaultEventOnCanvas,
|
||||
handleZoomClear,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { currentMenuState } from '@/store/canvasAtom'
|
||||
import { currentMenuState, currentObjectState } from '@/store/canvasAtom'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { MENU } from '@/common/common'
|
||||
import AuxiliaryMove from '@/components/floor-plan/modal/auxiliary/AuxiliaryMove'
|
||||
import AuxiliarySize from '@/components/floor-plan/modal/auxiliary/AuxiliarySize'
|
||||
|
||||
export function useContextMenu() {
|
||||
export function useContextMenu({ externalFn }) {
|
||||
const currentMenu = useRecoilValue(currentMenuState)
|
||||
const [contextMenu, setContextMenu] = useState([[]])
|
||||
const [currentContextMenu, setCurrentContextMenu] = useState(null)
|
||||
const currentObject = useRecoilValue(currentObjectState)
|
||||
|
||||
useEffect(() => {
|
||||
const currentMenuSetting = () => {
|
||||
console.log(currentMenu)
|
||||
switch (currentMenu) {
|
||||
case MENU.PLAN_DRAWING:
|
||||
setContextMenu([
|
||||
@ -50,6 +52,13 @@ export function useContextMenu() {
|
||||
case MENU.ROOF_COVERING.DEFAULT:
|
||||
setContextMenu([
|
||||
[
|
||||
{
|
||||
id: 'refresh',
|
||||
name: '새로고침',
|
||||
fn: () => {
|
||||
externalFn.handleZoomClear()
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialPlacement',
|
||||
name: '지붕재 배치',
|
||||
@ -150,8 +159,121 @@ export function useContextMenu() {
|
||||
setContextMenu([])
|
||||
break
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
currentMenuSetting()
|
||||
}, [currentMenu])
|
||||
|
||||
useEffect(() => {
|
||||
console.log('currentObject', currentObject)
|
||||
console.log('currentMenu', currentMenu)
|
||||
if (currentObject?.name) {
|
||||
console.log(currentObject)
|
||||
switch (currentObject.name) {
|
||||
case 'triangleDormer':
|
||||
setContextMenu([
|
||||
[
|
||||
{
|
||||
id: 'sizeEdit',
|
||||
name: '사이즈 변경',
|
||||
},
|
||||
{
|
||||
id: 'dormerRemove',
|
||||
name: '삭제(D)',
|
||||
},
|
||||
{
|
||||
id: 'dormerMove',
|
||||
name: '이동(M)',
|
||||
},
|
||||
{
|
||||
id: 'dormerCopy',
|
||||
name: '복사(C)',
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialEdit',
|
||||
name: '지붕재 변경',
|
||||
},
|
||||
{
|
||||
id: 'dormerOffset',
|
||||
name: '도머 오프셋',
|
||||
},
|
||||
],
|
||||
])
|
||||
break
|
||||
case 'roof':
|
||||
setContextMenu([
|
||||
[
|
||||
{
|
||||
id: 'sizeEdit',
|
||||
name: '사이즈 변경',
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialRemove',
|
||||
name: '삭제(D)',
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialMove',
|
||||
name: '이동(M)',
|
||||
},
|
||||
{
|
||||
id: 'roofMaterialCopy',
|
||||
name: '복사(C)',
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: 'roofMaterialEdit',
|
||||
name: '지붕재 변경',
|
||||
},
|
||||
{
|
||||
id: 'linePropertyEdit',
|
||||
name: '각 변 속성 변경',
|
||||
},
|
||||
{
|
||||
id: 'flowDirectionEdit',
|
||||
name: '흐름 뱡향 변경',
|
||||
},
|
||||
],
|
||||
])
|
||||
break
|
||||
case 'opening':
|
||||
setContextMenu([
|
||||
[
|
||||
{
|
||||
id: 'sizeEdit',
|
||||
name: '사이즈 변경',
|
||||
},
|
||||
{
|
||||
id: 'openingRemove',
|
||||
name: '삭제(D)',
|
||||
},
|
||||
{
|
||||
id: 'openingMove',
|
||||
name: '이동(M)',
|
||||
},
|
||||
{
|
||||
id: 'openingCopy',
|
||||
name: '복사(C)',
|
||||
},
|
||||
{
|
||||
id: 'openingOffset',
|
||||
name: '개구 오프셋',
|
||||
},
|
||||
],
|
||||
])
|
||||
break
|
||||
default:
|
||||
currentMenuSetting()
|
||||
}
|
||||
} else {
|
||||
currentMenuSetting()
|
||||
}
|
||||
}, [currentObject])
|
||||
|
||||
useEffect(() => {
|
||||
console.log(currentContextMenu)
|
||||
}, [currentContextMenu])
|
||||
|
||||
return {
|
||||
contextMenu,
|
||||
currentContextMenu,
|
||||
|
||||
26
src/hooks/usePopup.js
Normal file
26
src/hooks/usePopup.js
Normal file
@ -0,0 +1,26 @@
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { popupState } from '@/store/popupAtom'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
export function usePopup() {
|
||||
const [popup, setPopup] = useRecoilState(popupState)
|
||||
useEffect(() => {
|
||||
console.log(popup)
|
||||
}, [popup])
|
||||
|
||||
const addPopup = (component) => {
|
||||
setPopup({ children: [...popup.children, { id: uuidv4(), component: component }] })
|
||||
}
|
||||
|
||||
const closePopup = (id) => {
|
||||
setPopup({ children: popup.children.filter((child) => child.id !== id) })
|
||||
}
|
||||
|
||||
return {
|
||||
popup,
|
||||
setPopup,
|
||||
addPopup,
|
||||
closePopup,
|
||||
}
|
||||
}
|
||||
@ -247,6 +247,8 @@
|
||||
"modal.object.setting.direction.select": "方向の選択",
|
||||
"modal.placement.surface.setting.info": "ⓘ ①の長さ入力後に対角線の長さを入力すると、②の長さを自動計算します。",
|
||||
"modal.placement.surface.setting.diagonal.length": "斜めの長さ",
|
||||
"modal.color.picker.title": "色の設定",
|
||||
"modal.color.picker.default.color": "基本色",
|
||||
"setting": "設定",
|
||||
"common.message.no.data": "No data",
|
||||
"common.message.no.dataDown": "ダウンロードするデータがありません",
|
||||
|
||||
@ -252,6 +252,8 @@
|
||||
"modal.object.setting.direction.select": "방향 선택",
|
||||
"modal.placement.surface.setting.info": "ⓘ ①의 길이 입력 후 대각선 길이를 입력하면 ②의 길이를 자동 계산합니다.",
|
||||
"modal.placement.surface.setting.diagonal.length": "대각선 길이",
|
||||
"modal.color.picker.title": "색 설정",
|
||||
"modal.color.picker.default.color": "기본색상",
|
||||
"setting": "설정",
|
||||
"common.message.no.data": "No data",
|
||||
"common.message.no.dataDown": "No data to download",
|
||||
|
||||
13
src/store/popupAtom.js
Normal file
13
src/store/popupAtom.js
Normal file
@ -0,0 +1,13 @@
|
||||
import { atom } from 'recoil'
|
||||
|
||||
/*
|
||||
* id: uuid
|
||||
* component: Popup Component
|
||||
* */
|
||||
export const popupState = atom({
|
||||
key: 'popupState',
|
||||
default: {
|
||||
children: [],
|
||||
},
|
||||
dangerouslyAllowMutability: true,
|
||||
})
|
||||
@ -34,6 +34,9 @@ $alert-color: #101010;
|
||||
border-radius: 4px;
|
||||
background-color: #272727;
|
||||
z-index: 9999999;
|
||||
&.xsm{
|
||||
width: 200px;
|
||||
}
|
||||
&.xxxm{
|
||||
width: 240px;
|
||||
}
|
||||
@ -1505,7 +1508,7 @@ $alert-color: #101010;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
&.pink{
|
||||
border: 2px solid #EA10AC;
|
||||
border: 2px solid #ce1c9c;
|
||||
background-color: #16417D;
|
||||
}
|
||||
&.white{
|
||||
@ -1514,4 +1517,264 @@ $alert-color: #101010;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// color setting
|
||||
.color-setting-wrap{
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #424242;
|
||||
.color-tit{
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.color-picker{
|
||||
.react-colorful{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
gap: 20px;
|
||||
.react-colorful__pointer{
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border: 4px solid #Fff;
|
||||
}
|
||||
.react-colorful__saturation{
|
||||
border-radius: 2px;
|
||||
height: 200px;
|
||||
border-bottom: 5px solid #000;
|
||||
}
|
||||
.react-colorful__last-control{
|
||||
border-radius: 2px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
.hex-color-box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 15px;
|
||||
.color-box-tit{
|
||||
font-size: 12px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.color-hex-input{
|
||||
width: 150px;
|
||||
margin-right: 5px;
|
||||
input{
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.color-box{
|
||||
display: block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
.default-color-wrap{
|
||||
margin-top: 25px;
|
||||
.default-tit{
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.color-button-wrap{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 21px;
|
||||
.default-color{
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 글꼴 설정 팝업
|
||||
.font-option-warp{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 15px 5px;
|
||||
margin-bottom: 15px;
|
||||
.font-option-item{
|
||||
.option-item-tit{
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.font-ex-wrap{
|
||||
margin-bottom: 15px;
|
||||
.font-ex-tit{
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.font-ex-box{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 80px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 치수선 설정
|
||||
.font-btn-wrap{
|
||||
margin-bottom: 15px;
|
||||
button{
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.line-color-wrap{
|
||||
margin-bottom: 15px;
|
||||
.color-btn{
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.form-box{
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
padding: 10px 0 20px;
|
||||
.line-form{
|
||||
position: relative;
|
||||
width: 102px;
|
||||
height: 40px;
|
||||
margin: 0 auto;
|
||||
border-left: 1px dashed #101010;
|
||||
border-right: 1px dashed #101010;
|
||||
.line-font-box{
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
.font{
|
||||
display: block;
|
||||
padding-bottom: 6px;
|
||||
color: #101010;
|
||||
}
|
||||
.line{
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
border-radius: 30px;
|
||||
&::before{
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
left: 1px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border: 1px solid;
|
||||
border-color: inherit;
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
}
|
||||
&::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) rotate(45deg);
|
||||
right: 1px;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border: 1px solid;
|
||||
border-color: inherit;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 사이즈 변경
|
||||
.size-inner-warp{
|
||||
position: relative;
|
||||
}
|
||||
.size-check-wrap{
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 132px;
|
||||
height: 132px;
|
||||
margin: 0 auto;
|
||||
.size-btn{
|
||||
position: absolute;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 50%;
|
||||
&.act{
|
||||
&::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
&:nth-child(1){ top: 0; left: 0; }
|
||||
&:nth-child(2){ top: 0; right: 0; }
|
||||
&:nth-child(3){ bottom: 0; left: 0; }
|
||||
&:nth-child(4){ bottom: 0; right: 0; }
|
||||
}
|
||||
.size-box{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.size-option-top{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.size-option-side{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.size-option-wrap{
|
||||
width: 88px;
|
||||
margin: 0 auto;
|
||||
.size-option{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
input{
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
span{
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user