점 추가

This commit is contained in:
hyojun.choi 2024-06-24 14:57:19 +09:00
parent 414fb47c75
commit de380665f5
4 changed files with 160 additions and 1 deletions

16
src/app/roof2/page.jsx Normal file
View File

@ -0,0 +1,16 @@
'use client'
import Hero from '@/components/Hero'
import Roof from '@/components/Roof'
import Roof2 from '@/components/Roof2'
export default function RoofPage() {
return (
<>
<Hero title="Drawing on canvas 2D Roof" />
<div className="flex flex-col justify-center my-8">
<Roof2 />
</div>
</>
)
}

View File

@ -10,6 +10,7 @@ export default function Headers() {
<div className="space-x-4 text-xl">
<Link href="/intro">Intro</Link>
<Link href="/roof">Roof</Link>
<Link href="/roof2">Roof2</Link>
</div>
</nav>
</div>

139
src/components/Roof2.jsx Normal file
View File

@ -0,0 +1,139 @@
import { useCanvas } from '@/hooks/useCanvas'
import { useEffect, useRef } from 'react'
export default function Roof2() {
const { canvas } = useCanvas('canvas')
const points = useRef([])
useEffect(() => {
canvas?.on('mouse:down', function (options) {
const pointer = canvas?.getPointer(options.e)
const circle = new fabric.Circle({
radius: 5,
fill: 'transparent', // .
stroke: 'black', // .
left: pointer.x,
top: pointer.y,
originX: 'center',
originY: 'center',
selectable: false,
})
points.current.push(circle)
canvas?.add(circle)
if (points.current.length === 2) {
const length = Number(prompt('길이를 입력하세요:'))
// length
if (isNaN(length) || length === 0) {
// circle pointer .
points.current.forEach((point) => {
canvas?.remove(point)
})
points.current = []
return
}
if (length) {
const vector = {
x: points.current[1].left - points.current[0].left,
y: points.current[1].top - points.current[0].top,
}
const slope = Math.abs(vector.y / vector.x) //
let scaledVector
if (slope >= 1) {
// 1 x
scaledVector = {
x: 0,
y: vector.y >= 0 ? Number(length) : -Number(length),
}
} else {
// 1 y
scaledVector = {
x: vector.x >= 0 ? Number(length) : -Number(length),
y: 0,
}
}
let direction
if (Math.abs(vector.x) > Math.abs(vector.y)) {
// x
direction = vector.x > 0 ? 'right' : 'left'
} else {
// y
direction = vector.y > 0 ? 'bottom' : 'top'
}
const line = new fabric.Line(
[
points.current[0].left,
points.current[0].top,
points.current[0].left + scaledVector.x,
points.current[0].top + scaledVector.y,
],
{
stroke: 'black',
strokeWidth: 2,
selectable: false,
direction: direction,
},
)
const text = new fabric.Text(length.toString(), {
left:
(points.current[0].left +
points.current[0].left +
scaledVector.x) /
2,
top:
(points.current[0].top + points.current[0].top + scaledVector.y) /
2,
fontSize: 15,
originX: 'center',
originY: 'center',
selectable: false,
})
// .
const endPointCircle = new fabric.Circle({
radius: 5,
fill: 'transparent', // .
stroke: 'black', // .
left: points.current[0].left + scaledVector.x,
top: points.current[0].top + scaledVector.y,
originX: 'center',
originY: 'center',
selectable: false,
})
canvas?.add(line)
canvas?.add(text)
canvas?.add(endPointCircle)
points.current.forEach((point) => {
canvas?.remove(point)
})
points.current = [endPointCircle]
}
}
canvas?.renderAll()
})
}, [canvas])
return (
<>
<div className="flex justify-center my-8"></div>
<div
className="flex justify-center"
style={{
border: '1px solid',
width: 1000,
height: 1000,
margin: 'auto',
}}
>
<canvas id="canvas" />
</div>
</>
)
}

View File

@ -26,6 +26,7 @@ export function useCanvas(id) {
height: CANVAS.HEIGHT,
width: CANVAS.WIDTH,
backgroundColor: 'white',
selection: false,
})
// settings for all canvas in the app
@ -47,6 +48,8 @@ export function useCanvas(id) {
useEffect(() => {
if (canvas) {
initialize()
canvas?.on('mouse:move', drawMouseLines)
canvas?.on('mouse:out', removeMouseLines)
}
}, [canvas])
const addEventOnCanvas = () => {
@ -91,7 +94,7 @@ export function useCanvas(id) {
canvas?.clear()
// 기존 이벤트가 있을 경우 제거한다.
removeEventOnCanvas()
// removeEventOnCanvas()
// 작업 후에 event를 추가해준다.