Я хочу создать эффект пишущей машинки с помощью нокаута, но я не могу хранить данные в своей таблице, чтобы создать указанный эффект. Я провел некоторое исследование в течение нескольких недель, и у меня нет фундаментальных знаний, чтобы наткнуться на эту проблему. Это мой первый раз, когда я спрашиваю о переполнении стека.
Это основано на этом codipen: https://codepen.io/drewdoesdev/pen/gVrOBm
Пробовал это для пишущей машинки codipen: https://codepen.io/sauranerd/pen/mKKXjV?editors=1111
Этот пример выше не помогает с получением данных и
Вот краткая версия моих переменных:
var story = {
0: {
text: "zzzzz",
image: "img/gargoylep.gif",
choices: [
{
choiceText: "wake them?",//this is a button that goes to the next story
storyLink: 1
},
]
},
1: {
image: "img/gargoylesk.gif",
text: "im mad",
choices: [
{
choiceText: "Continue",
storyLink: 2
}
]
},
}
Ниже это то, что отображает текст. Это работает следующим образом. Он запускает игру, переходит к 0, чтобы отобразить текст по порядку, затем меняет сцену (ссылку на историю) на следующую. Это очень похоже на «ужин с твоим отцом» Codipen выше.
<span class = "scene__text" data-bind = "text: gameText"></span>
<button class = "scene__choice" data-bind = "text: choiceText, click: changeScene">Click Here to Start</button>
Я не хочу делать этот эффект с помощью css, так как хочу контролировать скорость пишущей машинки. У меня есть код, который я мог бы использовать, если бы я мог как-то сохранить строку.
Дайте мне знать, если мне нужно показать больше кода или объяснить дальше. Пример рабочего кода помог бы мне больше всего. Я предполагаю, что мне просто полностью не хватает синтаксиса того, как они работают. Я ценю помощь!
Я следил за документацией по нокауту и читал на w3 о json. Продолжал получать «Объект Объект» в результате со своими примерами. Не уверен, смогу ли я каким-то образом получить отображаемый текст, а затем отправить его в написанную мной функцию машинописи.
Редактировать: Чтобы уточнить, я хочу назначить несколько функций для скорости набора текста (также известной как быстрая, медленная нормальная) для каждого уникального текста.
Вы можете создать пользовательскую привязку, которая вводит текст с помощью эффекта пишущей машинки.
Например, привязка typeWriter
ниже:
""
и заканчивается исходной строкой.text
по умолчанию к этому новому значению.Если вы хотите сделать длительность динамической, вы можете использовать параметр allBindings
для передачи дополнительных настроек (см. первый пример в документации)
const texts = [
"Something short.",
"Medium length, Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud",
"A longer paragraph: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
];
ko.bindingHandlers.typeWriter = {
init: (el, va) => {
const partialText = ko.observable("");
let animation;
const effect = ko.computed(() => {
const t0 = Date.now();
const fullText = ko.unwrap(va());
const duration = fullText.length * 10; // 10ms per char
animation = requestAnimationFrame(next);
function next() {
const p = (Date.now() - t0) / duration;
if (p >= 1) {
partialText(fullText);
}
partialText(
fullText.slice(0, Math.round(p * fullText.length))
);
animation = requestAnimationFrame(next);
}
});
ko.applyBindingsToNode(el, { text: partialText });
ko.utils.domNodeDisposal.addDisposeCallback(el, () => {
cancelAnimationFrame(animation);
effect.dispose();
});
}
}
const activeIdx = ko.observable(0);
const activeText = ko.pureComputed(() => texts[activeIdx()]);
const goNext = () => activeIdx((activeIdx() + 1) % texts.length);
ko.applyBindings({ activeText, goNext });
<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<button data-bind = "click: goNext">Next</button>
<h2>Typewriter text binding</h2>
<p data-bind = "typeWriter: activeText"></p>
Вот пример, в котором используется ваш объект модели: (Обратите внимание, просто ради развлечения я попросил ChatGPT написать для нас приключение :D)
// Set up view model
const activeStoryId = ko.observable(1)
// This forces a re-render if we ever want to loop back to the current story
.extend({ notify: "always" });
const activeStory = ko.pureComputed(() =>
story[activeStoryId()] ??
// Default to "The end" so user can restart
{ text: "The end", choices: [{ choiceText: "Back to start", storyLink: 1 }] }
);
const onChoice = ({ storyLink }) => activeStoryId(storyLink);
// Apply bindings
registerBinding();
ko.applyBindings({
onChoice,
activeStory
});
function registerBinding() {
ko.bindingHandlers.typeWriter = {
init: (el, va) => {
const partialText = ko.observable("");
let animation;
const effect = ko.computed(() => {
const t0 = Date.now();
const fullText = ko.unwrap(va());
const duration = fullText.length * 30; // 10ms per char
animation = requestAnimationFrame(next);
function next() {
const p = (Date.now() - t0) / duration;
if (p >= 1) {
partialText(fullText);
}
partialText(
fullText.slice(0, Math.round(p * fullText.length))
);
animation = requestAnimationFrame(next);
}
});
ko.applyBindingsToNode(el, {
text: partialText
});
ko.utils.domNodeDisposal.addDisposeCallback(el, () => {
cancelAnimationFrame(animation);
effect.dispose();
});
}
}
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script>
const story = {"1":{"text":"You are standing in front of a big castle. What do you do?","choices":[{"choiceText":"Enter the castle","storyLink":"2"},{"choiceText":"Walk around the castle","storyLink":"3"}]},"2":{"text":"You are inside the castle. You see two doors. Which one do you choose?","choices":[{"choiceText":"Left door","storyLink":"4"},{"choiceText":"Right door","storyLink":"5"}]},"3":{"text":"You are walking around the castle. Suddenly, you are attacked by a monster. What do you do?","choices":[{"choiceText":"Fight the monster","storyLink":"6"},{"choiceText":"Run away","storyLink":"7"}]},"4":{"text":"You find a treasure chest. What do you do?","choices":[{"choiceText":"Open the chest","storyLink":"8"},{"choiceText":"Leave the chest and continue","storyLink":"9"}]},"5":{"text":"You find yourself in a room with no way out. What do you do?","choices":[{"choiceText":"Search for a hidden passage","storyLink":"10"},{"choiceText":"Scream for help","storyLink":"7"}]},"6":{"text":"You fought bravely, but the monster was too strong. You died.","choices":[]},"7":{"text":"You run away and find yourself in front of the castle. What do you do?","choices":[{"choiceText":"Enter the castle","storyLink":"2"},{"choiceText":"Walk around the castle","storyLink":"3"}]},"8":{"text":"You found a magical sword inside the chest. What do you do?","choices":[{"choiceText":"Leave the castle with the sword","storyLink":"11"},{"choiceText":"Continue exploring the castle","storyLink":"2"}]},"9":{"text":"You continue exploring the castle and find a secret passage. What do you do?","choices":[{"choiceText":"Enter the passage","storyLink":"12"},{"choiceText":"Leave the passage and continue","storyLink":"5"}]},"10":{"text":"You found a hidden passage and escaped from the room. What do you do?","choices":[{"choiceText":"Continue exploring the castle","storyLink":"2"},{"choiceText":"Leave the castle","storyLink":"11"}]}}
</script>
<div data-bind = "with: activeStory">
<p data-bind = "typeWriter: text" style = "min-height: 50px"></p>
<!-- ko foreach: choices -->
<button data-bind = "click: $root.onChoice, text: choiceText"></button>
<!-- /ko -->
</div>
Святое дерьмо, это именно то, что я искал! Спасибо за такой подробный ответ. Безумно полезно!
Посмотрите на эту статью про трюки css . У него есть хороший учебник по имитации машинописи. В конце статьи есть хороший codepen где можно управлять скоростью машинки с помощью sass (второй параметр в
@include typed
после текста. Надеюсь поможет! По умолчанию 1.5, можете менять как хотите .