Update CI and cube projections
Some checks failed
Deploy to Production / deploy (push) Failing after 5s
Some checks failed
Deploy to Production / deploy (push) Failing after 5s
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
<script setup>
|
||||
import { Sun, Moon } from 'lucide-vue-next';
|
||||
import { Sun, Moon, Layers } from 'lucide-vue-next';
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { useSettings } from '../composables/useSettings';
|
||||
|
||||
const { showProjections, toggleProjections } = useSettings();
|
||||
const isDark = ref(true);
|
||||
|
||||
const setTheme = (dark) => {
|
||||
isDark.value = dark;
|
||||
const theme = dark ? 'dark' : 'light';
|
||||
document.documentElement.dataset.theme = theme;
|
||||
localStorage.setItem('theme', theme);
|
||||
};
|
||||
|
||||
const toggleTheme = () => {
|
||||
@@ -15,7 +18,12 @@ const toggleTheme = () => {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const savedTheme = localStorage.getItem('theme');
|
||||
if (savedTheme) {
|
||||
setTheme(savedTheme === 'dark');
|
||||
} else {
|
||||
setTheme(true);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -26,6 +34,11 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<div class="nav-container">
|
||||
<!-- Projections Toggle -->
|
||||
<button class="btn-neon nav-btn icon-only" @click="toggleProjections" :title="showProjections ? 'Ukryj rzuty' : 'Pokaż rzuty'" :class="{ active: showProjections }">
|
||||
<Layers :size="20" />
|
||||
</button>
|
||||
|
||||
<!-- Theme Toggle -->
|
||||
<button class="btn-neon nav-btn icon-only" @click="toggleTheme" :title="isDark ? 'Przełącz na jasny' : 'Przełącz na ciemny'">
|
||||
<Sun v-if="isDark" :size="20" />
|
||||
@@ -86,7 +99,13 @@ onMounted(() => {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-btn:hover {
|
||||
.nav-btn:hover,
|
||||
.nav-btn.active {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.nav-btn.active {
|
||||
color: var(--color-primary);
|
||||
box-shadow: 0 0 10px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
59
src/components/common/Line3D.vue
Normal file
59
src/components/common/Line3D.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
start: {
|
||||
type: Object,
|
||||
required: true // {x, y, z}
|
||||
},
|
||||
end: {
|
||||
type: Object,
|
||||
required: true // {x, y, z}
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: 'var(--text-color, #fff)'
|
||||
},
|
||||
thickness: {
|
||||
type: Number,
|
||||
default: 1
|
||||
}
|
||||
});
|
||||
|
||||
const style = computed(() => {
|
||||
const dx = props.end.x - props.start.x;
|
||||
const dy = props.end.y - props.start.y;
|
||||
const dz = props.end.z - props.start.z;
|
||||
|
||||
const length = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||
|
||||
if (length === 0) return {};
|
||||
|
||||
const midX = (props.start.x + props.end.x) / 2;
|
||||
const midY = (props.start.y + props.end.y) / 2;
|
||||
const midZ = (props.start.z + props.end.z) / 2;
|
||||
|
||||
// Rotation
|
||||
// Yaw (around Y axis)
|
||||
const yaw = Math.atan2(dz, dx);
|
||||
// Pitch (around Z axis)
|
||||
const pitch = Math.atan2(dy, Math.sqrt(dx * dx + dz * dz));
|
||||
|
||||
return {
|
||||
width: `${length}px`,
|
||||
height: `${props.thickness}px`,
|
||||
backgroundColor: props.color,
|
||||
position: 'absolute',
|
||||
top: '0',
|
||||
left: '0',
|
||||
transformOrigin: 'center center',
|
||||
transform: `translate3d(${midX}px, ${midY}px, ${midZ}px) rotateY(${-yaw}rad) rotateZ(${pitch}rad) translate(-50%, -50%)`,
|
||||
opacity: 0.3, // Delicate
|
||||
pointerEvents: 'none'
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="line-3d" :style="style"></div>
|
||||
</template>
|
||||
25
src/composables/useSettings.js
Normal file
25
src/composables/useSettings.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
let initialShowProjections = false;
|
||||
try {
|
||||
const stored = localStorage.getItem('showProjections');
|
||||
if (stored !== null) {
|
||||
initialShowProjections = stored === 'true';
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
const showProjections = ref(initialShowProjections);
|
||||
|
||||
export function useSettings() {
|
||||
const toggleProjections = () => {
|
||||
showProjections.value = !showProjections.value;
|
||||
try {
|
||||
localStorage.setItem('showProjections', String(showProjections.value));
|
||||
} catch (e) {}
|
||||
};
|
||||
|
||||
return {
|
||||
showProjections,
|
||||
toggleProjections
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user