bx-865-apps #1

Merged
ksenia_mikhailova merged 140 commits from bx-865-apps into main 2024-06-27 15:03:27 +03:00
8 changed files with 187 additions and 132 deletions
Showing only changes of commit ac66af1fd7 - Show all commits

View File

@ -8579,7 +8579,7 @@
"kind": 5,
"importPath": "back.back.settings",
"description": "back.back.settings",
"peekOfCode": "CSRF_TRUSTED_ORIGINS = (\n \"https://demo.kustarshina.ru\",\n \"http://localhost\",\n \"http://localhost:3011\",\n \"http://192.168.103.159\",\n)\nCORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST = [\n \"null\",\n \"http://localhost\",",
"peekOfCode": "CSRF_TRUSTED_ORIGINS = (\n \"https://demo.kustarshina.ru\",\n \"http://localhost\",\n \"http://localhost:3011\",\n \"http://localhost:4173\",\n \"http://localhost:5173\",\n \"http://192.168.103.159:3011\",\n \"http://192.168.103.159\",\n)\nCORS_ORIGIN_ALLOW_ALL = False",
"detail": "back.back.settings",
"documentation": {}
},
@ -8588,7 +8588,7 @@
"kind": 5,
"importPath": "back.back.settings",
"description": "back.back.settings",
"peekOfCode": "CORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST = [\n \"null\",\n \"http://localhost\",\n \"http://localhost:3000\",\n \"http://localhost:3011\",\n \"http://localhost:4173\",\n \"http://localhost:5173\",\n \"http://localhost:8000\",\n \"http://127.0.0.1\",",
"peekOfCode": "CORS_ORIGIN_ALLOW_ALL = False\nCORS_ORIGIN_WHITELIST = [\n \"null\",\n \"http://localhost\",\n \"http://localhost:3011\",\n \"http://localhost:4173\",\n \"http://localhost:5173\",\n \"http://localhost:8000\",\n \"http://192.168.103.159:3011\",\n \"http://127.0.0.1\",",
"detail": "back.back.settings",
"documentation": {}
},
@ -8597,7 +8597,7 @@
"kind": 5,
"importPath": "back.back.settings",
"description": "back.back.settings",
"peekOfCode": "CORS_ORIGIN_WHITELIST = [\n \"null\",\n \"http://localhost\",\n \"http://localhost:3000\",\n \"http://localhost:3011\",\n \"http://localhost:4173\",\n \"http://localhost:5173\",\n \"http://localhost:8000\",\n \"http://127.0.0.1\",\n \"http://192.168.103.159\",",
"peekOfCode": "CORS_ORIGIN_WHITELIST = [\n \"null\",\n \"http://localhost\",\n \"http://localhost:3011\",\n \"http://localhost:4173\",\n \"http://localhost:5173\",\n \"http://localhost:8000\",\n \"http://192.168.103.159:3011\",\n \"http://127.0.0.1\",\n \"http://192.168.103.159\",",
"detail": "back.back.settings",
"documentation": {}
},

View File

@ -44,17 +44,20 @@ CSRF_TRUSTED_ORIGINS = (
"https://demo.kustarshina.ru",
"http://localhost",
"http://localhost:3011",
"http://localhost:4173",
"http://localhost:5173",
"http://192.168.103.159:3011",
"http://192.168.103.159",
)
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = [
"null",
"http://localhost",
"http://localhost:3000",
"http://localhost:3011",
"http://localhost:4173",
"http://localhost:5173",
"http://localhost:8000",
"http://192.168.103.159:3011",
"http://127.0.0.1",
"http://192.168.103.159",
"http://192.168.103.159:3000",

View File

@ -7,7 +7,9 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
copy: typeof import('./src/components/Floorplan copy.vue')['default']
Floorplan: typeof import('./src/components/Floorplan.vue')['default']
FloorplanItem: typeof import('./src/components/FloorplanItem.vue')['default']
Game: typeof import('./src/components/Game.vue')['default']
Home: typeof import('./src/components/Home.vue')['default']
IMdiFile: typeof import('~icons/mdi/file')['default']

View File

@ -1,133 +1,25 @@
<style lang="scss" scoped></style>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import PF, { Grid } from 'pathfinding'
import { onMounted, } from 'vue';
import { useFloorplanStore } from '../stores/floorplan';
type PathItem = { path: string, unwalkable: boolean, x: number, y: number }
const floorplan = useFloorplanStore()
const canvasElement = ref();
const context = ref();
const grid = ref<Grid>()
const startPoint = ref<{ x: number, y: number }>({ x: 25, y: 40 })
const endPoint = ref<{ x: number, y: number }>()
const startToEndPath = ref()
const plan = useFloorplanStore()
const paths = ref<PathItem[]>([])
const finder = new PF.AStarFinder();
const newDraw = () => {
endPoint.value = undefined
startToEndPath.value = undefined
context.value = canvasElement.value?.getContext('2d') || undefined;
const lines = plan.np_array
lines.forEach((line, indexY) => {
line.forEach((point, indexX) => {
if (canvasElement.value && context.value) {
context.value.fillStyle = point > 0 ? 'purple' : 'WHITE'
context.value.fillRect(indexX, indexY, 1, 1)
}
})
});
// if (canvasElement.value && context.value) {
// context.value.clearRect(0, 0, canvasElement.value.width, canvasElement.value.height);
// if (!plan.value.hasOwnProperty('paths')) return
// (plan.value).paths.forEach((path: string) => {
// if (!context.value) return
// context.value.fillStyle = 'rgba(255, 0, 255, 0.25)'
// context.value.fill(new Path2D(path));
// context.value.strokeStyle = 'blue'
// context.value.stroke(new Path2D(path));
// });
// }
const quantum_lines = plan.prepared_array
quantum_lines.forEach((line, indexY) => {
line.forEach((point, indexX) => {
const targetX = indexX * plan.chunkSize
const targetY = indexY * plan.chunkSize
paths.value.push({
path: `M${targetX} ${targetY} ${targetX + plan.chunkSize} ${targetY} ${targetX + plan.chunkSize} ${targetY + plan.chunkSize} ${targetX} ${targetY + plan.chunkSize}Z`,
unwalkable: !!point,
x: indexX,
y: indexY,
})
})
})
grid.value = new PF.Grid(plan.prepared_array.map(y => y.map(x => x > 0 ? 1 : 0)))
}
const findPath = async () => {
if (!endPoint.value) return
const localPath = finder.findPath(
Math.round(startPoint.value.x),
Math.round(startPoint.value.y),
Math.round(endPoint.value.x),
Math.round(endPoint.value.y),
(grid.value?.clone() as Grid)
);
startToEndPath.value = localPath
}
const setPointSvg = (item: PathItem) => {
// startToEndPath.value = []
endPoint.value = { x: item.x, y: item.y }
findPath()
}
onMounted(async () => {
await floorplan.getData()
newDraw()
await floorplan.getList()
})
const cw = 1920
const ch = 800
</script>
<template>
<div class="container" style="display: flex; justify-content: center; align-items: center; flex-direction: column;">
<canvas ref="canvasElement" :width="cw" :height="ch"></canvas>
<svg ref="svgElement" :width="cw" :height="ch" style="position: absolute;">
<path v-for="item in paths" :d="item.path" @click="setPointSvg(item)" :class="[
{ 'unwalkable': item.unwalkable },
{ 'endPoint': (endPoint && item.x == endPoint.x && item.y == endPoint.y) },
{ 'startPoint': (startPoint && item.x == startPoint.x && item.y == startPoint.y) },
{ 'pathPoint': (startToEndPath && startToEndPath.find((el: number[]) => el[0] == item.x && el[1] == item.y)) },
]">
</path>
</svg>
<div class="container">
<ul>
<li v-for="item in floorplan.items">
<RouterLink :to="`/floorplan/${item.id}`">
{{ item.title }}
</RouterLink>
</li>
</ul>
</div>
</template>
<style scoped>
svg path {
fill: transparent
}
svg path:hover {
fill: red
}
svg path.unwalkable {
/* fill: rgba(0, 0, 0, 0.5); */
}
svg path.endPoint {
fill: blue;
}
svg path.startPoint {
fill: lawngreen;
}
svg path.pathPoint {
fill: gold;
}
</style>

View File

@ -0,0 +1,130 @@
<style lang="scss" scoped></style>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import PF, { Grid } from 'pathfinding'
import { useFloorplanStore } from '../stores/floorplan';
import { useRoute } from 'vue-router';
type PathItem = { path: string, unwalkable: boolean, x: number, y: number }
const floorplan = useFloorplanStore()
const canvasElement = ref();
const context = ref();
const grid = ref<Grid>()
const startPoint = ref<{ x: number, y: number }>({ x: 25, y: 40 })
const endPoint = ref<{ x: number, y: number }>()
const startToEndPath = ref()
const plan = useFloorplanStore()
const paths = ref<PathItem[]>([])
const finder = new PF.AStarFinder();
const nextFrame = () => new Promise(resolve => requestAnimationFrame(resolve));
const route = useRoute()
const newDraw = async () => {
endPoint.value = undefined
startToEndPath.value = undefined
context.value = canvasElement.value?.getContext('2d') || undefined;
const lines = plan.np_array
for (let indexY = 0; indexY < lines.length; indexY++) {
const line = lines[indexY];
for (let indexX = 0; indexX < line.length; indexX++) {
const point = line[indexX];
if (canvasElement.value && context.value && point > 0) {
context.value.fillStyle = 'purple'
context.value.fillRect(indexX, indexY, 1, 1)
}
}
if (indexY % 4 == 0) {
await nextFrame()
}
}
const quantum_lines = plan.prepared_array
quantum_lines.forEach((line, indexY) => {
line.forEach((point, indexX) => {
const chunkSize = plan.chunk_size || 8
const targetX = indexX * chunkSize
const targetY = indexY * chunkSize
paths.value.push({
path: `M${targetX} ${targetY} ${targetX + chunkSize} ${targetY} ${targetX + chunkSize} ${targetY + chunkSize} ${targetX} ${targetY + chunkSize}Z`,
unwalkable: !!point,
x: indexX,
y: indexY,
})
})
})
grid.value = new PF.Grid(plan.prepared_array.map(y => y.map(x => x > 0 ? 1 : 0)))
}
const findPath = async () => {
if (!endPoint.value) return
const localPath = finder.findPath(
Math.round(startPoint.value.x),
Math.round(startPoint.value.y),
Math.round(endPoint.value.x),
Math.round(endPoint.value.y),
(grid.value?.clone() as Grid)
);
startToEndPath.value = localPath
}
const setPointSvg = (item: PathItem) => {
// startToEndPath.value = []
endPoint.value = { x: item.x, y: item.y }
findPath()
}
onMounted(async () => {
await floorplan.getData(parseInt(route.params.id as string))
newDraw()
})
const cw = 1920
const ch = 800
</script>
<template>
<div class="container" style="display: flex; justify-content: center; align-items: center; flex-direction: column;">
<canvas ref="canvasElement" :width="cw" :height="ch"></canvas>
<svg ref="svgElement" :width="cw" :height="ch" style="position: absolute;">
<path v-for="item in paths" :d="item.path" @click="setPointSvg(item)" :class="[
{ 'unwalkable': item.unwalkable },
{ 'endPoint': (endPoint && item.x == endPoint.x && item.y == endPoint.y) },
{ 'startPoint': (startPoint && item.x == startPoint.x && item.y == startPoint.y) },
{ 'pathPoint': (startToEndPath && startToEndPath.find((el: number[]) => el[0] == item.x && el[1] == item.y)) },
]">
</path>
</svg>
</div>
</template>
<style scoped>
svg path {
fill: transparent
}
svg path:hover {
fill: red
}
svg path.unwalkable {
/* fill: rgba(0, 0, 0, 0.5); */
}
svg path.endPoint {
fill: blue;
}
svg path.startPoint {
fill: lawngreen;
}
svg path.pathPoint {
fill: gold;
}
</style>

View File

@ -9,12 +9,14 @@ import Home from './components/Home.vue'
import Projects from './components/Projects.vue'
import Game from './components/Game.vue'
import Floorplan from './components/Floorplan.vue'
import FloorplanItem from './components/FloorplanItem.vue'
const routes = [
{ path: '/', component: Home },
{ path: '/projects', component: Projects },
{ path: '/game', component: Game },
{ path: '/floorplan', component: Floorplan },
{ path: '/floorplan/:id', component: FloorplanItem },
]
const router = createRouter({

View File

@ -5,34 +5,60 @@ import { chunks } from '../helpers'
export const useFloorplanStore = defineStore('floorplan', {
state: () => {
return {
items: [] as { id: string, title: string }[],
title: undefined,
chunkSize: 7,
np_array: [] as number[][],
prepared_array: [] as number[][]
prepared_array: [] as number[][],
chunk_size: undefined as number | undefined,
threshold: undefined as number | undefined,
}
},
actions: {
async getData() {
async getList() {
try {
const res = await fetch(`${SERVER_URL}/api/floorplan`)
const res = await fetch(`${SERVER_URL}/api/floorplan/`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
})
const data = await res.json()
this.items = data
// this.title = data.title
// this.np_array = data.np_field
} catch (error) {
console.log(error)
}
},
async getData(id: number) {
try {
const res = await fetch(`${SERVER_URL}/api/floorplan/${id}`, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
})
const data = await res.json()
this.title = data.title
this.np_array = data.np_field
this.prepared_array = [...chunks(data.np_field, this.chunkSize)].map(line => {
this.chunk_size = data.d_size || 8
this.threshold = data.d_border || 20
this.prepared_array = [...chunks(data.np_field, this.chunk_size as number)].map(line => {
const line_data = [] as any[][]
line.map((item: any) => [...chunks(item, this.chunkSize)]).map((item) => {
line.map((item: any) => [...chunks(item, this.chunk_size as number)]).map((item) => {
item.map((one_line, k) => {
if (!line_data[k]) line_data[k] = []
line_data[k].push(...one_line)
})
})
return line_data.map(el => {
return el.filter(e => e > 0).length > 20 ? 1 : 0
return el.filter(e => e > 0).length > (this.threshold as number) ? 1 : 0
})
});
} catch (error) {
// this.list = []
console.log(error)
}
},
}
}
})

View File

@ -27,5 +27,5 @@ build-backend = "poetry.core.masonry.api"
export_req = "poetry export --without-hashes --format=requirements.txt > back/requirements.txt"
server = "back/manage.py runserver 0.0.0.0:8000"
front = "cd front && npm run build && npm run preview"
front_dev = "cd front && npm run dev"
front_dev = "cd front && npm run dev -- --host"
admin_front_dev = "cd admin_front && npm run dev"