More animations

This commit is contained in:
BinarySandia04 2024-09-24 19:48:35 +02:00
parent 722f372a01
commit 80ede11f7c
10 changed files with 275 additions and 65 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.DS_Store .DS_Store
server/node_modules/ server/node_modules/
client/node_modules/ client/node_modules/
node_modules/
server/dist/ server/dist/
client/dist/ client/dist/

View File

@ -221,6 +221,17 @@ button:active {
width: 100%; width: 100%;
} }
.document.item {
text-align: center;
width: 220px;
}
.document.item img {
width: 64px;
height: 64px;
}
.document h1 { .document h1 {
font-weight: normal; font-weight: normal;
font-size: 32px; font-size: 32px;

View File

@ -8,7 +8,10 @@ let cursorY = 0;
let arrowIcon = "icons/iconoir/regular/nav-arrow-right.svg"; let arrowIcon = "icons/iconoir/regular/nav-arrow-right.svg";
import { animate } from 'motion'
function Show(){ function Show(){
console.log("SHOW")
let contextMenu = document.getElementById('context-menu'); let contextMenu = document.getElementById('context-menu');
contextMenu.style.display = "flex"; contextMenu.style.display = "flex";
contextMenu.style.top = (cursorY + margin) + "px"; contextMenu.style.top = (cursorY + margin) + "px";
@ -22,6 +25,8 @@ function HideContextMenu(){
function PopulateContext(val){ function PopulateContext(val){
let children = []; let children = [];
let elementNum = 0;
val.forEach(element => { val.forEach(element => {
let contextMenuElement = document.createElement('div'); let contextMenuElement = document.createElement('div');
contextMenuElement.classList.add("context-menu-element"); contextMenuElement.classList.add("context-menu-element");
@ -64,6 +69,14 @@ function PopulateContext(val){
} }
children.push(contextMenuElement); children.push(contextMenuElement);
animate(contextMenuElement, {
opacity: [0, 1],
translateY: [20, -2]
}, {delay: (elementNum / 2) * 0.1, duration: 0.25}).finished.then(() => {
});
elementNum++;
}); });
return children; return children;

View File

@ -1,19 +1,42 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { animate } from 'motion';
let content = ref(""); let content = ref("");
let margin = 14; let margin = 14;
let cursorX = 0; let cursorX = 0;
let cursorY = 0; let cursorY = 0;1
let showed = false;
let hided = false;
function ShowTooltip(){ function ShowTooltip(){
let tooltip = document.getElementById('mouse-tooltip'); let tooltip = document.getElementById('mouse-tooltip');
tooltip.style.display = "block"; tooltip.style.display = "block";
if(!showed){
animate(tooltip, {
opacity: [0, 1],
translateY: [20, 0]
}, {duration: 0.1, ease: 'ease-out'});
showed = true;
hided = false;
}
} }
function HideTooltip(){ function HideTooltip(){
let tooltip = document.getElementById('mouse-tooltip'); let tooltip = document.getElementById('mouse-tooltip');
tooltip.style.display = "none";
if(!hided){
animate(tooltip, {
opacity: [1, 0],
translateY: [0, 20]
}, {duration: 0.1, ease: 'ease-in'}).finished.then(() => tooltip.style.display = "none")
hided = true;
showed = false;
}
} }
function AddTooltip(element, val, data = {}){ function AddTooltip(element, val, data = {}){
@ -22,13 +45,21 @@ function AddTooltip(element, val, data = {}){
function UpdateVisibilityThread(){ function UpdateVisibilityThread(){
let tooltip = document.getElementById('mouse-tooltip'); let tooltip = document.getElementById('mouse-tooltip');
let element = document.elementFromPoint(cursorX, cursorY); let elements = document.elementsFromPoint(cursorX, cursorY);
if(element) if(element._dr_tooltip){
let visible = false;
for(let i = 0; i < elements.length; i++){
let element = elements[i];
if(element._dr_tooltip){
ShowTooltip(); ShowTooltip();
content.value = element._dr_tooltip.value; content.value = element._dr_tooltip.value;
if(element._dr_tooltip.max_width) tooltip.style.maxWidth = element._dr_tooltip.max_width + "px"; if(element._dr_tooltip.max_width) tooltip.style.maxWidth = element._dr_tooltip.max_width + "px";
else tooltip.style.maxWidth = "none"; else tooltip.style.maxWidth = "none";
} else HideTooltip(); visible = true;
break;
}
}
if(!visible) HideTooltip();
setTimeout(UpdateVisibilityThread, 0); setTimeout(UpdateVisibilityThread, 0);
} }

View File

@ -35,18 +35,18 @@ onMounted(() => {
flex-direction: column; flex-direction: column;
background-color: var(--tooltip-background);
-webkit-box-shadow: 0px 0px 5px -2px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 0px 5px -2px rgba(0,0,0,0.75);
box-shadow: 0px 0px 5px -2px rgba(0,0,0,0.75);
border: solid 1px var(--color-border);
.context-menu-element { .context-menu-element {
&:last-child {
border-width: 1px 1px 1px 1px;
}
border: solid 1px var(--color-border);
border-width: 1px 1px 0px 1px;
padding: 3px 5px 3px 5px; padding: 3px 5px 3px 5px;
cursor: default; cursor: default;
user-select: none; user-select: none;
background-color: var(--tooltip-background);
transition: background-color 100ms; transition: background-color 100ms;
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -0,0 +1,73 @@
<script setup>
import { onMounted, ref, watch } from 'vue';
import { AddContextMenu } from '@/services/ContextMenu';
import { AddTooltip } from '@/services/Tooltip';
import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
const props = defineProps(['element']);
const element = ref({});
const elementDiv = ref(null);
const tooltipContainer = ref(null);
function updateElement(){
element.value = props.element;
// Do whatever
let desc = element.value.info.description;
desc = desc ? marked.parse(desc) : '';
console.log(desc);
AddTooltip(tooltipContainer.value, `<div class='document item'>
<h2>${element.value.name}</h2>
<img src='${element.value.info.icon}'></img>
<div class='document'>${desc}</div>
</div>`)
}
onMounted(() => {
updateElement();
watch(() => props.element, () => {
updateElement();
});
AddContextMenu(elementDiv.value, [
{name: "Open"},
{name: "Delete"}
]);
})
</script>
<template>
<div class="concept-element" ref="elementDiv">
<div class="concept-tooltip-container" ref="tooltipContainer">
<img :src="element.info ? element.info.icon : 'icons/game-icons/ffffff/lorc/crossed-swords.svg'" class="concept-icon">
<span class="title">{{ element.name }}</span>
</div>
</div>
</template>
<style lang="scss">
.concept-tooltip-container {
display: flex;
align-items: center;
}
.concept-icon {
width: 36px;
height: 36px;
border: 1px solid var(--color-border);
}
.concept-element {
display: flex;
width: 100%;
padding: 10px;
align-items: center;
border-bottom: 1px solid var(--color-border-soft);
.title {
padding-left: 10px;
font-size: 16px;
font-weight: bold;
}
}
</style>

View File

@ -1,9 +1,11 @@
<script setup> <script setup>
import { onMounted, ref, watch } from 'vue'; import { onMounted, ref, watch } from 'vue';
import { GetCampaign } from '../../services/Dragonroll'; import { GetCampaign } from '../../services/Dragonroll';
import { ClearWindow, CreateWindow } from '../../services/Windows'; import { ClearWindow, CreateWindow } from '../../services/Windows';
import { animate } from "motion"
import ConceptEntry from './ConceptEntry.vue';
const props = defineProps(['elements']); const props = defineProps(['elements']);
const listContainer = ref(null); const listContainer = ref(null);
@ -17,64 +19,41 @@ onMounted(() => {
function OpenConcept(element){ function OpenConcept(element){
CreateWindow('item_sheet', { CreateWindow('item_sheet', {
id: 'item_sheet', id: 'item_sheet_' + element._id,
title: 'Edit Item', title: 'Edit Item',
item_id: element._id, item_id: element._id,
close: () => ClearWindow('item_sheet') close: () => ClearWindow('item_sheet_' + element._id)
});
}
function onBeforeEnter(el) {
el.style.opacity = 0
}
function onEnter(el, done) {
animate(el, {
opacity: [0, 1],
translateX: [20, 0]
}, {delay: el.dataset.index * 0.025})
}
function onLeave(el, done) {
animate(el, {
opacity: [1, 0],
translateX: [0, 20]
}); });
} }
</script> </script>
<template> <template>
<div class="list-container" ref="listContainer"> <div class="list-container" ref="listContainer">
<TransitionGroup name="list-element"> <TransitionGroup name="list-element" :css="false" @before-enter="onBeforeEnter" @enter="onEnter" @leave="onLeave">
<div class="list-element" v-for="element in elements" :key="element._id" v-on:click.prevent="OpenConcept(element)"> <ConceptEntry class="list-element" v-for="(element, index) in elements" :key="element._id" :element="element" v-on:click.prevent="OpenConcept(element)" :data-index="index"></ConceptEntry>
<img :src="element.info ? element.info.icon : 'icons/game-icons/ffffff/lorc/crossed-swords.svg'" class="concept-icon">
<span class="title">{{ element.name }}</span>
</div>
</TransitionGroup> </TransitionGroup>
</div> </div>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.concept-icon {
width: 36px;
height: 36px;
border: 1px solid var(--color-border);
}
.list-element {
display: flex;
width: 100%;
padding: 10px;
align-items: center;
border-bottom: 1px solid var(--color-border-soft);
.title {
padding-left: 10px;
font-size: 16px;
font-weight: bold;
}
}
.list-element-move, /* apply transition to moving elements */
.list-element-enter-active,
.list-element-leave-active {
transition: all 0.5s ease;
}
.list-element-enter-from,
.list-element-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* ensure leaving items are taken out of layout flow so that moving
animations can be calculated correctly. */
.list-element-leave-active {
position: absolute;
}
.list-container { .list-container {
display: flex; display: flex;

View File

@ -68,6 +68,7 @@ function SelectTab(row){
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute; position: absolute;
overflow-y: auto;
} }
.tab-content-inner { .tab-content-inner {

100
package-lock.json generated
View File

@ -1,6 +1,104 @@
{ {
"name": "dragonroll", "name": "dragonroll",
"version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": {} "packages": {
"": {
"name": "dragonroll",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"motion": "^10.18.0"
}
},
"node_modules/@motionone/animation": {
"version": "10.18.0",
"resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz",
"integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==",
"license": "MIT",
"dependencies": {
"@motionone/easing": "^10.18.0",
"@motionone/types": "^10.17.1",
"@motionone/utils": "^10.18.0",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/dom": {
"version": "10.18.0",
"resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.18.0.tgz",
"integrity": "sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==",
"license": "MIT",
"dependencies": {
"@motionone/animation": "^10.18.0",
"@motionone/generators": "^10.18.0",
"@motionone/types": "^10.17.1",
"@motionone/utils": "^10.18.0",
"hey-listen": "^1.0.8",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/easing": {
"version": "10.18.0",
"resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz",
"integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==",
"license": "MIT",
"dependencies": {
"@motionone/utils": "^10.18.0",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/generators": {
"version": "10.18.0",
"resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz",
"integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==",
"license": "MIT",
"dependencies": {
"@motionone/types": "^10.17.1",
"@motionone/utils": "^10.18.0",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/types": {
"version": "10.17.1",
"resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz",
"integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==",
"license": "MIT"
},
"node_modules/@motionone/utils": {
"version": "10.18.0",
"resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz",
"integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==",
"license": "MIT",
"dependencies": {
"@motionone/types": "^10.17.1",
"hey-listen": "^1.0.8",
"tslib": "^2.3.1"
}
},
"node_modules/hey-listen": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==",
"license": "MIT"
},
"node_modules/motion": {
"version": "10.18.0",
"resolved": "https://registry.npmjs.org/motion/-/motion-10.18.0.tgz",
"integrity": "sha512-MVAZZmwM/cp77BrNe1TxTMldxRPjwBNHheU5aPToqT4rJdZxLiADk58H+a0al5jKLxkB0OdgNq6DiVn11cjvIQ==",
"license": "MIT",
"dependencies": {
"@motionone/animation": "^10.18.0",
"@motionone/dom": "^10.18.0",
"@motionone/types": "^10.17.1",
"@motionone/utils": "^10.18.0"
}
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"license": "0BSD"
}
}
} }

View File

@ -7,5 +7,8 @@
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"author": "Aran Roig", "author": "Aran Roig",
"license": "ISC" "license": "ISC",
"dependencies": {
"motion": "^10.18.0"
}
} }