mirror of
https://github.com/robonen/eulerian-cycle.git
synced 2026-03-20 10:54:46 +00:00
Fixed displaying steps in the player
This commit is contained in:
@@ -509,15 +509,15 @@ p {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter-active {
|
.fade-up-enter-active {
|
||||||
animation: fade-in 0.5s;
|
animation: fade-up 0.5s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-leave-active {
|
.fade-up-leave-active {
|
||||||
animation: fade-in 0.5s reverse;
|
animation: fade-up 0.5s reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-up {
|
||||||
from {
|
from {
|
||||||
transform: translateY(-40px);
|
transform: translateY(-40px);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|||||||
@@ -131,6 +131,16 @@ export default {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const checkGraph = () => {
|
||||||
|
euler.loadLinks(Object.values(links.value));
|
||||||
|
|
||||||
|
if (links.value.length > 0 && euler.check()) {
|
||||||
|
emit("hasEuler", euler.find());
|
||||||
|
} else {
|
||||||
|
emit("hasEuler", null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
const activateNodes = (ids) =>
|
const activateNodes = (ids) =>
|
||||||
ids.forEach((e) => (nodes.value[e].selected = true));
|
ids.forEach((e) => (nodes.value[e].selected = true));
|
||||||
@@ -149,6 +159,7 @@ export default {
|
|||||||
|
|
||||||
if (hasntIntersections(newNode)) {
|
if (hasntIntersections(newNode)) {
|
||||||
nodes.value.push(newNode);
|
nodes.value.push(newNode);
|
||||||
|
emit("hasVertices", nodes.value.length);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,7 +178,8 @@ export default {
|
|||||||
|
|
||||||
nodes.value = nodes.value.filter((_, idx) => idx !== id);
|
nodes.value = nodes.value.filter((_, idx) => idx !== id);
|
||||||
|
|
||||||
emit("isEuler", []);
|
checkGraph();
|
||||||
|
emit("hasVertices", nodes.value.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectNode = (id) => {
|
const selectNode = (id) => {
|
||||||
@@ -245,10 +257,7 @@ export default {
|
|||||||
target,
|
target,
|
||||||
});
|
});
|
||||||
|
|
||||||
euler.loadLinks(Object.values(links.value));
|
checkGraph();
|
||||||
|
|
||||||
if (euler.check()) emit("isEuler", euler.find());
|
|
||||||
else emit("isEuler", []);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const removeLink = (id) => {
|
const removeLink = (id) => {
|
||||||
|
|||||||
@@ -25,16 +25,25 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
Popup,
|
Popup,
|
||||||
},
|
},
|
||||||
props: {
|
|
||||||
steps: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
|
// Const
|
||||||
|
const steps = [
|
||||||
|
{
|
||||||
|
name: "Создание вершин",
|
||||||
|
content:
|
||||||
|
"Для создания новой вершины необходимо дважды нажать левую кнопку мыши",
|
||||||
|
video: "/video/create.mp4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Связывание вершин",
|
||||||
|
content:
|
||||||
|
"Чтобы связать вершины, необходимо кликнуть левой кнопкой мыши по вершине, которую необходимо связать. Далее выбираются вершины, с которыми необходимо связать",
|
||||||
|
video: "/video/linking.mp4",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
// Reactive
|
// Reactive
|
||||||
const currentStep = ref(0);
|
const currentStep = ref(0);
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
const stepDown = () => {
|
const stepDown = () => {
|
||||||
if (currentStep.value <= 0) return;
|
if (currentStep.value <= 0) return;
|
||||||
@@ -43,7 +52,7 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const stepUp = () => {
|
const stepUp = () => {
|
||||||
if (currentStep.value + 1 >= props.steps.length) {
|
if (currentStep.value + 1 >= steps.length) {
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -57,6 +66,7 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
steps,
|
||||||
currentStep,
|
currentStep,
|
||||||
stepDown,
|
stepDown,
|
||||||
stepUp,
|
stepUp,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<guide v-show="showGuide" :steps="guide" @close="showGuide = false"></guide>
|
<guide v-show="showGuide" @close="showGuide = false"></guide>
|
||||||
<popup v-show="showInfo" @close="showInfo = false">
|
<popup v-show="showInfo" @close="showInfo = false">
|
||||||
<template v-slot:title>
|
<template v-slot:title>
|
||||||
Циклы в эйлером графе
|
Циклы в эйлером графе
|
||||||
@@ -28,33 +28,41 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<transition name="fade">
|
<transition name="fade-up">
|
||||||
<div v-if="errorText" class="error" @click="errorText = ''">
|
<div v-if="errorText" class="error" @click="errorText = ''">
|
||||||
{{ errorText }}
|
{{ errorText }}
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<div class="header-step-cont inaccessible">
|
<transition name="fade-up">
|
||||||
|
<div v-if="stepExists" class="header-step-cont">
|
||||||
<div class="header-step-text">
|
<div class="header-step-text">
|
||||||
<div class="header-vertex">
|
<div class="header-vertex">
|
||||||
{{ stepExists ? steps[currentStep].source : "-" }}
|
{{ currentStepData.source ?? "-" }}
|
||||||
</div>
|
</div>
|
||||||
<div class="header-arrow"></div>
|
<div class="header-arrow"></div>
|
||||||
<div class="header-vertex">
|
<div class="header-vertex">
|
||||||
{{ stepExists ? steps[currentStep].target : "-" }}
|
{{ currentStepData.target ?? "-" }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-step-description">
|
<div class="header-step-description">
|
||||||
шаг {{ stepExists ? currentStep + 1 : "-" }} /
|
шаг {{ stepExists ? currentStepNumber + 1 : "-" }} /
|
||||||
{{ stepExists ? stepsCount : "-" }}
|
{{ stepExists ? stepsTotal : "-" }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</transition>
|
||||||
</header>
|
</header>
|
||||||
<div class="graph-cont">
|
<div class="graph-cont">
|
||||||
<div class="empty-graph-cont">
|
<div v-if="!vertexExists" class="empty-graph-cont">
|
||||||
Нажмите ЛКМ дважды, чтобы добавить вершину
|
Нажмите ЛКМ дважды, чтобы добавить вершину
|
||||||
</div>
|
</div>
|
||||||
<graph @isEuler="getSteps" :stepData="currentStepData"></graph>
|
<graph
|
||||||
<div class="hints">Чтобы удалить вершину, нажмите ПКМ по ней</div>
|
:stepData="currentStepData"
|
||||||
|
@hasEuler="loadSteps"
|
||||||
|
@hasVertices="setVertices"
|
||||||
|
></graph>
|
||||||
|
<div v-if="vertexExists" class="hints">
|
||||||
|
Чтобы удалить вершину, нажмите ПКМ по ней
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-cont">
|
<div class="control-cont">
|
||||||
<div class="control-button" id="previous-step" @click="prevStep">
|
<div class="control-button" id="previous-step" @click="prevStep">
|
||||||
@@ -77,7 +85,6 @@
|
|||||||
>
|
>
|
||||||
<div class="prompt">Продолжить</div>
|
<div class="prompt">Продолжить</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-button" id="next-step" @click="nextStep">
|
<div class="control-button" id="next-step" @click="nextStep">
|
||||||
<div class="prompt">Следующий шаг</div>
|
<div class="prompt">Следующий шаг</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,14 +92,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="addition-cont">
|
<div class="addition-cont">
|
||||||
<div class="step-cont">
|
<div class="step-cont">
|
||||||
<div
|
<!-- <div
|
||||||
class="step"
|
class="step"
|
||||||
v-for="cs in stepsCount"
|
v-for="cs in stepsCount"
|
||||||
:key="cs"
|
:key="cs"
|
||||||
:class="{ 'active-step last-active-step': cs - 1 === currentStep }"
|
:class="{ 'active-step last-active-step': cs - 1 === currentStep }"
|
||||||
>
|
>
|
||||||
{{ cs }}
|
{{ cs }}
|
||||||
</div>
|
</div> -->
|
||||||
<!-- <div class="step active-step">2</div>
|
<!-- <div class="step active-step">2</div>
|
||||||
<div class="step active-step last-active-step">3</div>
|
<div class="step active-step last-active-step">3</div>
|
||||||
<div class="step">1</div>
|
<div class="step">1</div>
|
||||||
@@ -117,26 +124,16 @@ export default {
|
|||||||
setup() {
|
setup() {
|
||||||
// Const
|
// Const
|
||||||
let timer = null;
|
let timer = null;
|
||||||
const guide = [
|
const ANIMATION_DELAY = 1500;
|
||||||
{
|
const ERROR_DELAY = 5000;
|
||||||
name: "Создание вершин",
|
|
||||||
content:
|
|
||||||
"Для создания новой вершины необходимо дважды нажать левую кнопку мыши",
|
|
||||||
video: "/video/create.mp4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Связывание вершин",
|
|
||||||
content:
|
|
||||||
"Чтобы связать вершины, необходимо кликнуть левой кнопкой мыши по вершине, которую необходимо связать. Далее выбираются вершины, с которыми необходимо связать",
|
|
||||||
video: "/video/linking.mp4",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// Reactive
|
// Reactive
|
||||||
|
const vertices = ref(0);
|
||||||
const steps = ref([]);
|
const steps = ref([]);
|
||||||
const currentStep = ref(0);
|
const currentStepNumber = ref(0);
|
||||||
const currentStepData = ref({});
|
const currentStepData = ref({});
|
||||||
const played = ref(false);
|
const played = ref(false);
|
||||||
|
|
||||||
const showInfo = ref(false);
|
const showInfo = ref(false);
|
||||||
const showGuide = ref(false);
|
const showGuide = ref(false);
|
||||||
const errorText = ref("");
|
const errorText = ref("");
|
||||||
@@ -152,44 +149,58 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Computed
|
// Computed
|
||||||
|
const vertexExists = computed(() => {
|
||||||
|
return vertices.value > 0;
|
||||||
|
});
|
||||||
|
|
||||||
const stepExists = computed(() => {
|
const stepExists = computed(() => {
|
||||||
return steps.value.length > 0;
|
return steps.value.length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
const stepsCount = computed(() => {
|
const stepsTotal = computed(() => {
|
||||||
return steps.value.length;
|
return steps.value.length;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
const log = () => {
|
const showError = (msg) => {
|
||||||
showInfo.value = true;
|
errorText.value = msg;
|
||||||
|
setTimeout(() => (errorText.value = false), ERROR_DELAY);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSteps = (data) => {
|
const setVertices = (data) => {
|
||||||
steps.value = data;
|
vertices.value = data;
|
||||||
currentStep.value = 0;
|
};
|
||||||
currentStepData.value = steps.value[currentStep.value];
|
|
||||||
|
const loadSteps = (data) => {
|
||||||
|
steps.value = data ?? [];
|
||||||
|
currentStepNumber.value = 0;
|
||||||
|
currentStepData.value = steps.value[currentStepNumber.value] ?? {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const nextStep = () => {
|
const nextStep = () => {
|
||||||
if (currentStep.value >= stepsCount.value - 1) currentStep.value = 0;
|
if (currentStepNumber.value >= stepsTotal.value - 1)
|
||||||
else currentStep.value++;
|
currentStepNumber.value = 0;
|
||||||
|
else currentStepNumber.value++;
|
||||||
|
|
||||||
currentStepData.value = steps.value[currentStep.value];
|
currentStepData.value = steps.value[currentStepNumber.value];
|
||||||
};
|
};
|
||||||
|
|
||||||
const prevStep = () => {
|
const prevStep = () => {
|
||||||
if (currentStep.value <= 0) currentStep.value = stepsCount.value - 1;
|
if (currentStepNumber.value <= 0)
|
||||||
else currentStep.value--;
|
currentStepNumber.value = stepsTotal.value - 1;
|
||||||
|
else currentStepNumber.value--;
|
||||||
|
|
||||||
currentStepData.value = steps.value[currentStep.value];
|
currentStepData.value = steps.value[currentStepNumber.value];
|
||||||
};
|
};
|
||||||
|
|
||||||
const play = () => {
|
const play = () => {
|
||||||
if (!stepExists.value) return;
|
if (!stepExists.value) {
|
||||||
|
showError("Эйлеров цикл не найден!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
played.value = true;
|
played.value = true;
|
||||||
timer = setInterval(nextStep, 1000);
|
timer = setInterval(nextStep, ANIMATION_DELAY);
|
||||||
};
|
};
|
||||||
|
|
||||||
const stop = () => {
|
const stop = () => {
|
||||||
@@ -199,21 +210,26 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// Player properties
|
||||||
|
vertexExists,
|
||||||
steps,
|
steps,
|
||||||
stepsCount,
|
stepsTotal,
|
||||||
stepExists,
|
stepExists,
|
||||||
currentStep,
|
currentStepNumber,
|
||||||
currentStepData,
|
currentStepData,
|
||||||
played,
|
played,
|
||||||
getSteps,
|
|
||||||
|
// Player methods
|
||||||
|
setVertices,
|
||||||
|
loadSteps,
|
||||||
nextStep,
|
nextStep,
|
||||||
prevStep,
|
prevStep,
|
||||||
play,
|
play,
|
||||||
stop,
|
stop,
|
||||||
log,
|
|
||||||
|
// Helpers
|
||||||
showInfo,
|
showInfo,
|
||||||
showGuide,
|
showGuide,
|
||||||
guide,
|
|
||||||
errorText,
|
errorText,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user