bx-1316-refactoring #14

Merged
ksenia_mikhailova merged 46 commits from bx-1316-refactoring into dev 2024-08-28 15:06:52 +03:00
30 changed files with 311 additions and 224 deletions
Showing only changes of commit e9369dd053 - Show all commits

View File

@ -177,6 +177,94 @@
"detail": "django.db", "detail": "django.db",
"documentation": {} "documentation": {}
}, },
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "models",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "models",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "models",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "models",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "models",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{ {
"label": "models", "label": "models",
"importPath": "django.db", "importPath": "django.db",
@ -313,6 +401,14 @@
"detail": "django.db", "detail": "django.db",
"documentation": {} "documentation": {}
}, },
{
"label": "migrations",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{ {
"label": "models", "label": "models",
"importPath": "django.db", "importPath": "django.db",
@ -321,6 +417,23 @@
"detail": "django.db", "detail": "django.db",
"documentation": {} "documentation": {}
}, },
{
"label": "models",
"importPath": "django.db",
"description": "django.db",
"isExtraImport": true,
"detail": "django.db",
"documentation": {}
},
{
"label": "django.db.models.deletion",
"kind": 6,
"isExtraImport": true,
"importPath": "django.db.models.deletion",
"description": "django.db.models.deletion",
"detail": "django.db.models.deletion",
"documentation": {}
},
{ {
"label": "AppConfig", "label": "AppConfig",
"importPath": "django.apps", "importPath": "django.apps",
@ -337,6 +450,23 @@
"detail": "django.apps", "detail": "django.apps",
"documentation": {} "documentation": {}
}, },
{
"label": "object.models",
"kind": 6,
"isExtraImport": true,
"importPath": "object.models",
"description": "object.models",
"detail": "object.models",
"documentation": {}
},
{
"label": "Scene3D",
"importPath": "object.models",
"description": "object.models",
"isExtraImport": true,
"detail": "object.models",
"documentation": {}
},
{ {
"label": "logging", "label": "logging",
"kind": 6, "kind": 6,
@ -395,24 +525,6 @@
"detail": "django.core.validators", "detail": "django.core.validators",
"documentation": {} "documentation": {}
}, },
{
"label": "django.db.models.deletion",
"kind": 6,
"isExtraImport": true,
"importPath": "django.db.models.deletion",
"description": "django.db.models.deletion",
"detail": "django.db.models.deletion",
"documentation": {}
},
{
"label": "object.models",
"kind": 6,
"isExtraImport": true,
"importPath": "object.models",
"description": "object.models",
"detail": "object.models",
"documentation": {}
},
{ {
"label": "colorfield.fields", "label": "colorfield.fields",
"kind": 6, "kind": 6,
@ -694,7 +806,7 @@
"kind": 5, "kind": 5,
"importPath": "back.back.urls", "importPath": "back.back.urls",
"description": "back.back.urls", "description": "back.back.urls",
"peekOfCode": "router = routers.DefaultRouter()\nrouter.register(r'api/front_img', frontimg_views.ImageViewSet)\nrouter.register(r'api/obj/scene', object_views.Scene3DViewSet)\nrouter.register(r'api/obj/element', object_views.Element3DViewSet)\nrouter.register(r'api/obj/clickable', object_views.ClickableAreaViewSet)\nurlpatterns = [\n path('', include(router.urls)),\n path(\"admin/\", admin.site.urls),\n] + static('/files', document_root='files')", "peekOfCode": "router = routers.DefaultRouter()\nrouter.register(r'api/item', frontimg_views.ItemViewSet)\nrouter.register(r'api/front_img', frontimg_views.ImageViewSet)\nrouter.register(r'api/obj/scene', object_views.Scene3DViewSet)\nrouter.register(r'api/obj/element', object_views.Element3DViewSet)\nrouter.register(r'api/obj/clickable', object_views.ClickableAreaViewSet)\nurlpatterns = [\n path('', include(router.urls)),\n path(\"admin/\", admin.site.urls),\n] + static('/files', document_root='files')",
"detail": "back.back.urls", "detail": "back.back.urls",
"documentation": {} "documentation": {}
}, },
@ -725,6 +837,69 @@
"detail": "back.frontImages.migrations.0001_initial", "detail": "back.frontImages.migrations.0001_initial",
"documentation": {} "documentation": {}
}, },
{
"label": "Migration",
"kind": 6,
"importPath": "back.frontImages.migrations.0002_item",
"description": "back.frontImages.migrations.0002_item",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('frontImages', '0001_initial'),\n ('object', '0011_remove_element3d_parent_element3d_x_pos_and_more'),\n ]\n operations = [\n migrations.CreateModel(\n name='Item',\n fields=[\n ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),",
"detail": "back.frontImages.migrations.0002_item",
"documentation": {}
},
{
"label": "Migration",
"kind": 6,
"importPath": "back.frontImages.migrations.0003_delete_item",
"description": "back.frontImages.migrations.0003_delete_item",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('frontImages', '0002_item'),\n ]\n operations = [\n migrations.DeleteModel(\n name='Item',\n ),\n ]",
"detail": "back.frontImages.migrations.0003_delete_item",
"documentation": {}
},
{
"label": "Migration",
"kind": 6,
"importPath": "back.frontImages.migrations.0004_item",
"description": "back.frontImages.migrations.0004_item",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('frontImages', '0003_delete_item'),\n ('object', '0011_remove_element3d_parent_element3d_x_pos_and_more'),\n ]\n operations = [\n migrations.CreateModel(\n name='Item',\n fields=[\n ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),",
"detail": "back.frontImages.migrations.0004_item",
"documentation": {}
},
{
"label": "Migration",
"kind": 6,
"importPath": "back.frontImages.migrations.0005_item_name",
"description": "back.frontImages.migrations.0005_item_name",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('frontImages', '0004_item'),\n ]\n operations = [\n migrations.AddField(\n model_name='item',\n name='name',\n field=models.CharField(default='1'),\n preserve_default=False,",
"detail": "back.frontImages.migrations.0005_item_name",
"documentation": {}
},
{
"label": "Migration",
"kind": 6,
"importPath": "back.frontImages.migrations.0006_item_is_front",
"description": "back.frontImages.migrations.0006_item_is_front",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('frontImages', '0005_item_name'),\n ]\n operations = [\n migrations.AddField(\n model_name='item',\n name='is_front',\n field=models.BooleanField(default=True, unique=True),\n preserve_default=False,",
"detail": "back.frontImages.migrations.0006_item_is_front",
"documentation": {}
},
{
"label": "Migration",
"kind": 6,
"importPath": "back.frontImages.migrations.0007_item_slug",
"description": "back.frontImages.migrations.0007_item_slug",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('frontImages', '0006_item_is_front'),\n ]\n operations = [\n migrations.AddField(\n model_name='item',\n name='slug',\n field=models.SlugField(default='main'),\n preserve_default=False,",
"detail": "back.frontImages.migrations.0007_item_slug",
"documentation": {}
},
{
"label": "ItemAdmin",
"kind": 6,
"importPath": "back.frontImages.admin",
"description": "back.frontImages.admin",
"peekOfCode": "class ItemAdmin(admin.ModelAdmin):\n filter_horizontal = (\"images\",)\nadmin.site.register(Image)\nadmin.site.register(Item, ItemAdmin)",
"detail": "back.frontImages.admin",
"documentation": {}
},
{ {
"label": "FrontimagesConfig", "label": "FrontimagesConfig",
"kind": 6, "kind": 6,
@ -739,7 +914,16 @@
"kind": 6, "kind": 6,
"importPath": "back.frontImages.models", "importPath": "back.frontImages.models",
"description": "back.frontImages.models", "description": "back.frontImages.models",
"peekOfCode": "class Image(models.Model):\n file = models.ImageField(upload_to=group_based_upload_to)\n alt = models.CharField(max_length=255)\n title = models.CharField(max_length=255)\n def __str__(self):\n return self.title", "peekOfCode": "class Image(models.Model):\n file = models.ImageField(upload_to=group_based_upload_to)\n alt = models.CharField(max_length=255)\n title = models.CharField(max_length=255)\n def __str__(self):\n return self.title\nclass Item(models.Model):\n name = models.CharField()\n slug = models.SlugField(unique=True)\n images = models.ManyToManyField(Image)",
"detail": "back.frontImages.models",
"documentation": {}
},
{
"label": "Item",
"kind": 6,
"importPath": "back.frontImages.models",
"description": "back.frontImages.models",
"peekOfCode": "class Item(models.Model):\n name = models.CharField()\n slug = models.SlugField(unique=True)\n images = models.ManyToManyField(Image)\n scene_3d = models.ForeignKey(Scene3D, on_delete=models.RESTRICT)\n is_front = models.BooleanField(unique=True)\n def __str__(self):\n return f\"{self.id} {self.name} {'Главная' if self.is_front else ''}\"",
"detail": "back.frontImages.models", "detail": "back.frontImages.models",
"documentation": {} "documentation": {}
}, },
@ -766,7 +950,16 @@
"kind": 6, "kind": 6,
"importPath": "back.frontImages.serializers", "importPath": "back.frontImages.serializers",
"description": "back.frontImages.serializers", "description": "back.frontImages.serializers",
"peekOfCode": "class ImageSerializer(serializers.ModelSerializer):\n file = serializers.ImageField(use_url=False)\n class Meta:\n model = Image\n fields = \"__all__\"", "peekOfCode": "class ImageSerializer(serializers.ModelSerializer):\n file = serializers.ImageField(use_url=False)\n class Meta:\n model = Image\n fields = \"__all__\"\nclass ItemSerializer(serializers.ModelSerializer):\n images = ImageSerializer(many=True)\n class Meta:\n lookup_field = 'slug'\n model = Item",
"detail": "back.frontImages.serializers",
"documentation": {}
},
{
"label": "ItemSerializer",
"kind": 6,
"importPath": "back.frontImages.serializers",
"description": "back.frontImages.serializers",
"peekOfCode": "class ItemSerializer(serializers.ModelSerializer):\n images = ImageSerializer(many=True)\n class Meta:\n lookup_field = 'slug'\n model = Item\n fields = \"__all__\"\n def validate_is_front(self, value):\n if value:\n # Если у нас is_active=True, проверяем, есть ли другой объект с True\n if Item.objects.filter(is_front=True).exists():",
"detail": "back.frontImages.serializers", "detail": "back.frontImages.serializers",
"documentation": {} "documentation": {}
}, },
@ -775,7 +968,16 @@
"kind": 6, "kind": 6,
"importPath": "back.frontImages.views", "importPath": "back.frontImages.views",
"description": "back.frontImages.views", "description": "back.frontImages.views",
"peekOfCode": "class ImageViewSet(viewsets.ModelViewSet):\n queryset = Image.objects.all()\n serializer_class = ImageSerializer", "peekOfCode": "class ImageViewSet(viewsets.ModelViewSet):\n queryset = Image.objects.all()\n serializer_class = ImageSerializer\nclass ItemViewSet(viewsets.ModelViewSet):\n queryset = Item.objects.all()\n serializer_class = ItemSerializer\n lookup_field = 'slug'\n filterset_fields = ['is_front']",
"detail": "back.frontImages.views",
"documentation": {}
},
{
"label": "ItemViewSet",
"kind": 6,
"importPath": "back.frontImages.views",
"description": "back.frontImages.views",
"peekOfCode": "class ItemViewSet(viewsets.ModelViewSet):\n queryset = Item.objects.all()\n serializer_class = ItemSerializer\n lookup_field = 'slug'\n filterset_fields = ['is_front']",
"detail": "back.frontImages.views", "detail": "back.frontImages.views",
"documentation": {} "documentation": {}
}, },
@ -869,6 +1071,15 @@
"detail": "back.object.migrations.0010_environment_clear_color", "detail": "back.object.migrations.0010_environment_clear_color",
"documentation": {} "documentation": {}
}, },
{
"label": "Migration",
"kind": 6,
"importPath": "back.object.migrations.0011_remove_element3d_parent_element3d_x_pos_and_more",
"description": "back.object.migrations.0011_remove_element3d_parent_element3d_x_pos_and_more",
"peekOfCode": "class Migration(migrations.Migration):\n dependencies = [\n ('object', '0010_environment_clear_color'),\n ]\n operations = [\n migrations.RemoveField(\n model_name='element3d',\n name='parent',\n ),\n migrations.AddField(",
"detail": "back.object.migrations.0011_remove_element3d_parent_element3d_x_pos_and_more",
"documentation": {}
},
{ {
"label": "Scene3DAdmin", "label": "Scene3DAdmin",
"kind": 6, "kind": 6,

View File

@ -1,22 +0,0 @@
asgiref==3.8.1 ; python_version >= "3.10" and python_version < "4.0"
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0"
crispy-bootstrap4==2024.1 ; python_version >= "3.10" and python_version < "4.0"
django-cors-headers==4.3.1 ; python_version >= "3.10" and python_version < "4.0"
django-crispy-forms==2.2 ; python_version >= "3.10" and python_version < "4.0"
django-extensions==3.2.3 ; python_version >= "3.10" and python_version < "4.0"
django-filter==24.2 ; python_version >= "3.10" and python_version < "4.0"
django==5.0.6 ; python_version >= "3.10" and python_version < "4.0"
djangorestframework==3.15.1 ; python_version >= "3.10" and python_version < "4.0"
mslex==1.2.0 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"
numpy==1.26.4 ; python_version >= "3.10" and python_version < "4.0"
opencv-python==4.9.0.80 ; python_version >= "3.10" and python_version < "4.0"
pillow==10.3.0 ; python_version >= "3.10" and python_version < "4.0"
potracer==0.0.4 ; python_version >= "3.10" and python_version < "4.0"
psutil==5.9.8 ; python_version >= "3.10" and python_version < "4.0"
psycopg2==2.9.9 ; python_version >= "3.10" and python_version < "4.0"
python-dotenv==1.0.1 ; python_version >= "3.10" and python_version < "4.0"
sqlparse==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
taskipy==1.12.2 ; python_version >= "3.10" and python_version < "4.0"
tomli==2.0.1 ; python_version >= "3.10" and python_version < "4.0"
typing-extensions==4.11.0 ; python_version >= "3.10" and python_version < "3.11"
tzdata==2024.1 ; python_version >= "3.10" and python_version < "4.0" and sys_platform == "win32"

View File

@ -24,6 +24,7 @@ from frontImages import views as frontimg_views
from object import views as object_views from object import views as object_views
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'api/item', frontimg_views.ItemViewSet)
router.register(r'api/front_img', frontimg_views.ImageViewSet) router.register(r'api/front_img', frontimg_views.ImageViewSet)
router.register(r'api/obj/scene', object_views.Scene3DViewSet) router.register(r'api/obj/scene', object_views.Scene3DViewSet)
router.register(r'api/obj/element', object_views.Element3DViewSet) router.register(r'api/obj/element', object_views.Element3DViewSet)

View File

@ -1,4 +1,9 @@
from django.contrib import admin from django.contrib import admin
from .models import Image from .models import Image, Item
admin.site.register(Image) class ItemAdmin(admin.ModelAdmin):
filter_horizontal = ("images",)
admin.site.register(Image)
admin.site.register(Item, ItemAdmin)

View File

@ -1,19 +1,32 @@
from django.db import models from django.db import models
from object.models import Scene3D
import logging import logging
logger = logging.getLogger("root") logger = logging.getLogger("root")
def group_based_upload_to(instance, filename): def group_based_upload_to(instance, filename):
logger.info(instance) logger.info(instance)
return "files/image/{}/{}/{}".format( return "files/image/{}/{}/{}".format(
type(instance).__name__.lower(), instance.id, filename type(instance).__name__.lower(), instance.id, filename
) )
class Image(models.Model): class Image(models.Model):
file = models.ImageField(upload_to=group_based_upload_to) file = models.ImageField(upload_to=group_based_upload_to)
alt = models.CharField(max_length=255) alt = models.CharField(max_length=255)
title = models.CharField(max_length=255) title = models.CharField(max_length=255)
def __str__(self): def __str__(self):
return self.title return self.title
class Item(models.Model):
name = models.CharField()
slug = models.SlugField(unique=True)
images = models.ManyToManyField(Image)
scene_3d = models.ForeignKey(Scene3D, on_delete=models.RESTRICT)
is_front = models.BooleanField(unique=True)
def __str__(self):
return f"{self.id} {self.name} {'Главная' if self.is_front else ''}"

View File

@ -1,9 +1,27 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Image from .models import Image, Item
class ImageSerializer(serializers.ModelSerializer): class ImageSerializer(serializers.ModelSerializer):
file = serializers.ImageField(use_url=False) file = serializers.ImageField(use_url=False)
class Meta: class Meta:
model = Image model = Image
fields = "__all__" fields = "__all__"
class ItemSerializer(serializers.ModelSerializer):
images = ImageSerializer(many=True)
class Meta:
lookup_field = 'slug'
model = Item
fields = "__all__"
def validate_is_front(self, value):
if value:
# Если у нас is_active=True, проверяем, есть ли другой объект с True
if Item.objects.filter(is_front=True).exists():
raise serializers.ValidationError(
"Только один элемент может иметь is_front=True."
)
return value

View File

@ -2,9 +2,15 @@ from django.shortcuts import render
from rest_framework import viewsets from rest_framework import viewsets
from .models import Image from .models import Image, Item
from .serializers import ImageSerializer from .serializers import ImageSerializer, ItemSerializer
class ImageViewSet(viewsets.ModelViewSet): class ImageViewSet(viewsets.ModelViewSet):
queryset = Image.objects.all() queryset = Image.objects.all()
serializer_class = ImageSerializer serializer_class = ImageSerializer
class ItemViewSet(viewsets.ModelViewSet):
queryset = Item.objects.all()
serializer_class = ItemSerializer
lookup_field = 'slug'
filterset_fields = ['is_front']

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

View File

@ -1,35 +1,5 @@
@import 'grid.scss'; @import 'grid.scss';
// #06bcb3
// #e6d787
// #048280
// #a47f62
// #b1abd4
// #304c5a
.nav {
display: flex;
flex-direction: column;
position: fixed;
top: 0;
left: 0;
bottom: 0;
padding: 1rem;
max-width: 2rem;
font-size: 2rem;
background-color: #fff;
box-shadow: 0 0 4px rgba(#000, 0.5);
z-index: 100;
@media(max-width: 768px) {
display: none;
}
}
body {
padding-left: 2.5rem;
}
a[href] { a[href] {
color: #048280; color: #048280;

View File

@ -1,11 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { SERVER_URL, IMAGE_URL } from '../../constants'
import * as d3 from "d3" import * as d3 from "d3"
import { onMounted } from "vue" import { onMounted } from "vue"
import { IMAGE_URL } from '../../constants'
const props = defineProps(['files'])
onMounted(async () => { onMounted(async () => {
const res = await fetch(`${SERVER_URL}/api/front_img/`) const files = props.files
const files = await res.json()
const width = 1920 const width = 1920
const height = 1080 const height = 1080
// const width = window.innerWidth // const width = window.innerWidth
@ -34,7 +36,7 @@ onMounted(async () => {
.attr("x", 0) .attr("x", 0)
.attr("y", 0); .attr("y", 0);
}); });
const range = 20 const range = files.length + 2
const circles = d3.range(range).map(() => ({ const circles = d3.range(range).map(() => ({
x: Math.random() * (width - radius * 2) + radius, x: Math.random() * (width - radius * 2) + radius,
y: Math.random() * (height - radius * 2) + radius, y: Math.random() * (height - radius * 2) + radius,

View File

@ -1,18 +1,27 @@
<script setup lang="ts"> <script setup lang="ts">
import { useRouter } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import KLogo from "../../assets/promo/logo.svg"; import KLogo from "../../assets/promo/logo.svg";
import { SERVER_URL } from "../../constants";
import Gallery from "./gallery.vue"; import Gallery from "./gallery.vue";
const router = useRouter() const router = useRouter()
const route = useRoute()
const startColor = `hsl(${(Math.random() * 360).toFixed()}, 100%, 50%)` const startColor = `hsl(${(Math.random() * 360).toFixed()}, 100%, 50%)`
const endColor = `hsl(${(Math.random() * 360).toFixed()}, 100%, 50%)` const endColor = `hsl(${(Math.random() * 360).toFixed()}, 100%, 50%)`
const res = await fetch(`${SERVER_URL}/api/item/${route.params.item ? (route.params.item + '/') : '?is_front=true'}`)
const pageArray = await res.json()
const page = Array.isArray(pageArray) ? pageArray[0] : pageArray
</script> </script>
<template> <template>
<div class="main"> <div class="main">
<div class="pin" @click="router.push('/promo/main')"> <div class="pin" @click="router.push(`/${page.slug}/${page.scene_3d}`)">
<KLogo /> <KLogo />
</div> </div>
<Gallery /> <Gallery :files="page.images" />
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
@ -33,16 +42,16 @@ const endColor = `hsl(${(Math.random() * 360).toFixed()}, 100%, 50%)`
.pin { .pin {
cursor: pointer; cursor: pointer;
border-radius: 0.25rem; border-radius: 0.25rem;
overflow: hidden; overflow: hidden;
position: absolute; position: absolute;
bottom: 300px; bottom: 300px;
left: calc(50% - 80px); left: calc(50% - 80px);
color: white; color: white;
width: 2rem; width: 2rem;
height: 2rem; height: 2rem;
padding: 0.25rem; padding: 0.25rem;
@ -73,6 +82,7 @@ const endColor = `hsl(${(Math.random() * 360).toFixed()}, 100%, 50%)`
// animation-play-state: paused; // animation-play-state: paused;
animation: none; animation: none;
transform: scale(1.5); transform: scale(1.5);
&::before { &::before {
// animation-play-state: paused; // animation-play-state: paused;
} }

View File

@ -1,18 +0,0 @@
<script setup lang=ts>
import { useRoute } from 'vue-router';
const route = useRoute()
const name = route.params.name
</script>
<template>
<div class="container">
Это внутренняя страница #{{ name }}
<RouterLink to="/promo/main">Назад</RouterLink>
</div>
</template>
<style scoped>
.container {
font-size: 2rem;
}
</style>

View File

@ -72,7 +72,7 @@ watch(() => route.params.target, () => {
<a href="#" @click.prevent="sidebar.open" v-if="!sidebar.is_open"> <a href="#" @click.prevent="sidebar.open" v-if="!sidebar.is_open">
<i-mdi-page-previous-outline /> <i-mdi-page-previous-outline />
</a> </a>
<RouterLink to="/promo/main/"> <RouterLink to="/main/">
<i-mdi-home /> <i-mdi-home />
</RouterLink> </RouterLink>
</div> </div>

View File

@ -1,27 +0,0 @@
<script setup lang="ts">
import { useGLTF, } from '@tresjs/cientos'
const props = defineProps(['modelUrl', 'modelFile', 'onClick'])
let scene: any
if (props.modelUrl) {
let { scene: loaded_scene } = await useGLTF(props.modelUrl)
scene = loaded_scene.clone()
} else if (props.modelFile) {
scene = props.modelFile.clone()
}
function shadows_and_pos(scene: any) {
scene.children.forEach((el: any) => {
el.receiveShadow = true
el.castShadow = true
shadows_and_pos(el)
})
}
shadows_and_pos(scene)
</script>
<template>
<TresMesh v-if="scene.children[0].isObject3D">
<TresObject3D v-bind="scene.children[0].clone()"/>
</TresMesh>
</template>

View File

@ -1,69 +0,0 @@
<script setup lang="ts">
import { ACESFilmicToneMapping, RepeatWrapping } from 'three'
import { useTexture, useTresContext } from '@tresjs/core'
import { Environment } from '@tresjs/cientos'
// import andreyUrl from '../../assets/promo/models/quadro/andrey.fbx'
// import mangalUrl from '../../assets/promo/models/quadro/mangal.fbx'
// import pillarUrl from '../../assets/promo/models/quadro/pillar.fbx'
// import pointerUrl from '../../assets/promo/models/quadro/pointer.fbx'
// import quadUrl from '../../assets/promo/models/quadro/quad.fbx'
// import walkbayUrl from '../../assets/promo/models/quadro/walkway.fbx'
// import groundUrl from '../../assets/promo/models/quadro/ground.fbx'
// import skyUrl from '../../assets/promo/models/quadro/sky.fbx'
import hdrmap from "../../assets/promo/models/sunset.hdr"
import gr_map from '../../assets/promo/models/quadro/Ground_Color_1k.jpg'
import gr_normalMap from '../../assets/promo/models/quadro/Ground_Normal_1k.jpg'
import gr_roughnessMap from '../../assets/promo/models/quadro/Ground_Roughness_1k.jpg'
const { map, normalMap } = await useTexture({
map: gr_map,
normalMap: gr_normalMap,
roughnessMap: gr_roughnessMap,
})
const { renderer } = useTresContext()
renderer.value.toneMapping = ACESFilmicToneMapping
renderer.value.toneMappingExposure = 0.15
renderer.value.shadowMap.enabled = true
const repeat = 20
map.wrapS = RepeatWrapping
map.wrapT = RepeatWrapping
map.repeat.x = repeat
map.repeat.y = repeat
normalMap.wrapS = RepeatWrapping
normalMap.wrapT = RepeatWrapping
normalMap.repeat.x = repeat
normalMap.repeat.y = repeat
</script>
<template>
<TresGroup>
<Suspense>
<Environment background :files="hdrmap" />
</Suspense>
<TresMesh :rotate-x="-Math.PI * 0.5" receive-shadow>
<TresPlaneGeometry :args="[repeat * 20, repeat * 20]" />
<TresMeshStandardMaterial :map="map" :normalMap="normalMap" />
</TresMesh>
<ModelItem modelUrl="/walkway.glb" />
<ModelItem modelUrl="/andrey.glb" />
<!-- <ModelItem modelUrl="/Area_light.glb" /> -->
<!-- <ModelItem modelUrl="/Ground.glb" /> -->
<ModelItem modelUrl="/mangal.glb" />
<ModelItem modelUrl="/pillar.glb" />
<ModelItem modelUrl="/pointer.glb" />
<ModelItem modelUrl="/quad.glb" />
<!-- <ModelItem modelUrl="/Spot_light.glb" /> -->
<ModelItem modelUrl="/walkway.glb" />
<!-- <primitive :object="groundModel" /> -->
<!-- <primitive :object="skyModel" /> -->
</TresGroup>
</template>

View File

@ -23,7 +23,7 @@ const sidebar_obj = ref()
<p>{{ p }}</p> <p>{{ p }}</p>
</template> </template>
</template> </template>
<RouterLink class="btn" :to="`/promo/main/${sidebar.target}`" v-if="sidebar.target"> <RouterLink class="btn" :to="`/main/${sidebar.target}`" v-if="sidebar.target">
{{ sidebar.target_name }} {{ sidebar.target_name }}
</RouterLink> </RouterLink>
</template> </template>

View File

@ -5,17 +5,13 @@ import { createWebHistory, createRouter } from 'vue-router'
import './assets/main.scss' import './assets/main.scss'
import App from './App.vue' import App from './App.vue'
import Home from './components/Home.vue'
import Promo from './components/Promo/index.vue' import Promo from './components/Promo/index.vue'
import PromoMain from './components/Promo/main.vue' import PromoMain from './components/Promo/main.vue'
import PromoItem from './components/Promo/item.vue'
const routes = [ const routes = [
{ path: '/', component: Home }, { path: '/', component: Promo },
{ path: '/promo', component: Promo }, { path: '/:item', component: Promo },
{ path: '/promo/:page', component: PromoMain }, { path: '/:item/:target', component: PromoMain },
{ path: '/promo/:page/:target', component: PromoMain },
{ path: '/promo/:page/item/:name', component: PromoItem },
] ]
const router = createRouter({ const router = createRouter({

View File

@ -20,14 +20,6 @@ export default defineConfig({
}), }),
Icons(), Icons(),
svgLoader(), svgLoader(),
viteStaticCopy({
targets: [
{
src: 'src/assets/promo/models/quadro/*.jpg',
dest: 'assets'
}
]
})
], ],
assetsInclude: ['**/*.fbx','**/*.glb', '**/*.gltf', '**/*.hdr'], assetsInclude: ['**/*.fbx','**/*.glb', '**/*.gltf', '**/*.hdr'],
}) })