Add Dockerfile, nginx config, Gitea workflow and docker-compose
Some checks failed
Build and Publish Docker Image / build (push) Has been cancelled

This commit is contained in:
2026-02-15 20:14:58 +01:00
parent 91203e6c2c
commit 9272bd9c7d
11 changed files with 321 additions and 111 deletions

View File

@@ -1,107 +0,0 @@
<script setup>
</script>
<template>
<div class="container">
<div class="cube">
<div class="face top">Top</div>
<div class="face bottom">Bottom</div>
<div class="face left">Left</div>
<div class="face right">Right</div>
<div class="face front">Front</div>
<div class="face back">Back</div>
</div>
</div>
</template>
<style scoped>
.container {
width: 200px;
height: 200px;
perspective: 400px;
margin: 100px;
}
.top {
background: white;
}
.bottom {
background: yellow;
}
.front {
background: blue;
}
.back {
background: green;
}
.left {
background: red;
}
.right {
background: orange;
}
.cube {
position: relative;
width: 200px;
height: 200px;
transform-style: preserve-3d;
}
.face {
width: 200px;
height: 200px;
border: 0px solid black;
position: absolute;
opacity: 0.9;
display: flex;
align-items: center;
justify-content: center;
font-family: Arial, sans-serif;
font-size: 2rem;
}
.cube {
position: relative;
width: 200px;
height: 200px;
transform-style: preserve-3d;
transform: rotate3d(1, 1, 0, 45deg);
}
.front {
transform: translateZ(100px);
}
.back {
transform: translateZ(-100px) rotateY(180deg);
}
.left {
transform: translateX(-100px) rotateY(-90deg);
}
.right {
transform: translateX(100px) rotateY(90deg);
}
.top {
transform: translateY(-100px) rotateX(90deg);
}
.bottom {
transform: translateY(100px) rotateX(-90deg);
}
@keyframes turn {
from { transform: rotate3d(0, 0, 0, 0); }
to { transform: rotate3d(1, 1, 0, 360deg); }
}
.cube {
position: relative;
transform-style: preserve-3d;
animation: turn 3s linear infinite;
}
</style>

174
src/components/main.vue Normal file
View File

@@ -0,0 +1,174 @@
<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
const rx = ref(25)
const ry = ref(25)
const rz = ref(0)
const isDragging = ref(false)
const lastMouseX = ref(0)
const lastMouseY = ref(0)
const onMouseDown = (event) => {
isDragging.value = true
lastMouseX.value = event.clientX
lastMouseY.value = event.clientY
}
const onMouseMove = (event) => {
if (!isDragging.value) return
const deltaX = event.clientX - lastMouseX.value
const deltaY = event.clientY - lastMouseY.value
ry.value += deltaX * 0.5
rx.value -= deltaY * 0.5
lastMouseX.value = event.clientX
lastMouseY.value = event.clientY
}
const onMouseUp = () => {
isDragging.value = false
}
onMounted(() => {
window.addEventListener('mousemove', onMouseMove)
window.addEventListener('mouseup', onMouseUp)
})
onUnmounted(() => {
window.removeEventListener('mousemove', onMouseMove)
window.removeEventListener('mouseup', onMouseUp)
})
const cubeStyle = computed(() => ({
transform: `rotateX(${rx.value}deg) rotateY(${ry.value}deg) rotateZ(${rz.value}deg)`
}))
</script>
<template>
<div class="wrapper">
<div class="container" @mousedown="onMouseDown">
<div class="cube" :style="cubeStyle">
<div class="face top">
<div class="stickers">
<div class="sticker" v-for="i in 9" :key="'t'+i"></div>
</div>
</div>
<div class="face bottom">
<div class="stickers">
<div class="sticker" v-for="i in 9" :key="'b'+i"></div>
</div>
</div>
<div class="face left">
<div class="stickers">
<div class="sticker" v-for="i in 9" :key="'l'+i"></div>
</div>
</div>
<div class="face right">
<div class="stickers">
<div class="sticker" v-for="i in 9" :key="'r'+i"></div>
</div>
</div>
<div class="face front">
<div class="stickers">
<div class="sticker" v-for="i in 9" :key="'f'+i"></div>
</div>
</div>
<div class="face back">
<div class="stickers">
<div class="sticker" v-for="i in 9" :key="'k'+i"></div>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
}
.container {
width: 200px;
height: 200px;
perspective: 600px;
margin: 60px auto;
cursor: grab;
user-select: none;
}
.container:active {
cursor: grabbing;
}
.cube {
position: relative;
width: 200px;
height: 200px;
transform-style: preserve-3d;
}
.face {
width: 200px;
height: 200px;
background: #000;
padding: 6px;
box-sizing: border-box;
position: absolute;
opacity: 0.9;
}
.stickers {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 6px;
width: 100%;
height: 100%;
}
.sticker {
width: 100%;
height: 100%;
background: var(--sticker-color);
border-radius: 6px;
}
.top { --sticker-color: #ffffff; }
.bottom { --sticker-color: #ffd500; }
.front { --sticker-color: #0051ba; }
.back { --sticker-color: #009e60; }
.left { --sticker-color: #c41e3a; }
.right { --sticker-color: #ff5800; }
.front {
transform: translateZ(100px);
}
.back {
transform: translateZ(-100px) rotateY(180deg);
}
.left {
transform: translateX(-100px) rotateY(-90deg);
}
.right {
transform: translateX(100px) rotateY(90deg);
}
.top {
transform: translateY(-100px) rotateX(90deg);
}
.bottom {
transform: translateY(100px) rotateX(-90deg);
}
</style>