Skip to content

Creating Tutorials

nbriz edited this page Aug 16, 2020 · 17 revisions

STILL IN PROGRESS STILL IN PROGRESS STILL IN PROGRESS

Within the context of netnet.stuio, a "tutorial" is a directory which consists of a metadata.json file, as well as a JavaScript files (with the tutorial's content) and any other accompanying assets (images, videos, etc).

netnet's TutorialManager.js (instantiated globally in main.js as NNT) is responsible for much of the interactive tutorials logic.

It can load tutorial data by passing a tutorial name into it's .load() method. It can also load tutorials hosted elsewhere on the Internet by passing it a URL (to a directory with a metadata.json file). It can also launch a tutorial on page load by passing netnet a tutorial URL parameter, ex: http://netnet.studio/?tutorial=tutorial-name-or-url.

metadata

{
  "title": "New Media Art",
  "sub-title": "understanding digital art as a metamedia",
  "author": "Nick Briz",
  "preferred-name": "Nick",
  "main": "main.js",
  "checkpoints": [
    "defining new media",
    "new media as a metamedium",
    "taxonomies && properties",
    "new media as a cultural movement",
    "new media as an ecology"
  ],
  "endnotes": [
    {
      "note": "'Murray, Janet H.\"Inventing the Medium\" The New Media Reader. Ed. Noah Wardrip-Fruin & Nick Montfort. MIT Press, 2003.",
      "url": "http://www.newmediareader.com/book_samples/nmr-intro-murray-excerpt.pdf"
    },
    {
      "note": "Kay, Alan & Adele Goldberg. \"Personal Dynamic Computer\" Computer 10(3):31-41. March 1977",
      "url": "http://www.newmediareader.com/book_samples/nmr-26-kay.pdf"
    }
  ]
}

main js file

window.TUTORIAL = {
  steps: [/* array of "step" objects */],
  widgets: {} // optional widgets created/used during tutorial
}

a "step" object

{
  id: 'defining new media',
  code: '<h1>code to be injected into netitor at this step</h1>',
  edit: false, // should netitor be editable during this step
  highlight: 5, // line of code in editor to highlight
  highlightColor: 'rgba(255, 255, 0, 0.5)',
  content: 'content to appear in text bubble',
  options: {/* buttons to appear in text bubble */}
}

the "steps" array

window.TUTORIAL = {
  steps: [
    { content: 'HTML isn\'t the only type of markup language.' },
    { content: 'Others include MathML and even SVG.' },
    { content: 'Artists like the Graffiti Research Lab have even made their own.'},
    { content: 'It\'s called GML or Graffiti Markup Language.'}
  ]
}

netnet dialogue

linear tutorials

window.TUTORIAL = {
  widgets: {
    'color explorer': new Widget({/* details */})
  },
  steps: [
    {
      content: 'Take a look at this line of code, notice anything?',
      highlight: 10
    },
    {
      content: 'We\'ve changed the way we\'re defining colors.'
    },
    {
      content: 'There are even more ways to specify colors in CSS.',
      options: {
        'launch color widget': () => {
          STORE.dispatch('OPEN_WIDGET', 'color explorer')
        },
        'cool, i\'ll experiment': () => {
          STORE.dispatch('HIDE_TUTORIAL_TEXT')
        }
      }
    }
  ]
}

netnet dialogue

customizing "next" and "previous" buttons

The TutorialManager handles creating "previous" and "next" buttons if/when there are prior/subsequent steps to display. It will additionally add an "ok" button to finish the tutorial at the last step. But you can override these defaults by passing in your own options object and using the TutorialManager's internal .next() and .prev() methods:

[
  {
    content: 'HTML isn\'t the only type of markup language.',
    options: {
      'oh no? what others are there?': (e) => { e.next() }
    }
  },
  {
    content: 'There\'s <a href="https://developer.mozilla.org/en-US/docs/Web/MathML" target="_blank">MathML</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/SVG" target="_blank">SVG</a>.',
    options: {
      'you don\'t say! Are there more?': (e) => { e.next() },
      'wait a sec, go back.':  (e) => { e.prev() }
    }
  },
  {
    content: 'Oh yes! Artists like the Graffiti Research Lab have even made their own.',
    options: {
      'really? What\'s it called?': (e) => { e.next() },
      'wait a sec, go back.':  (e) => { e.prev() }
    }
  },
  {
    content: 'It\'s called GML or <a href="https://en.wikipedia.org/wiki/Graffiti_Markup_Language" target="_blank">Graffiti Markup Language</a>.',
    options: {
      'wait a sec, go back.':  (e) => { e.prev() },
      'cool thnx for the info!': () => {
        STORE.dispatch('FINISH_TUTORIAL')
      }
    }
  }
]

netnet dialogue

non-linear tutorials

What if we want to have a non-linear conversation with netnet? Where the user's option determines which dialogue they see next? In these instances we need to give our step objects an additional id property, which can be any string (but need to be unique to other id's in the array). We can then use the TutorialManager's internal .goTo() method in the option's callback functions by passing in the id of the step we want netnet to switch to when the user picks that option.

const arr = [
  {
    id: 'begin',
    content: 'Would you like to experiment a bit more?',
    options: {
      'yes please': (e) => { e.goTo('more-experimenting') },
      'naw, i\'m good': (e) => { e.goTo('finished') }
    }
  },
  {
    id: 'more-experimenting',
    content: 'Ok great, dont\'t forget about the helpful widgets!',
    options: {
      'open color widget': () => {
        STORE.dispatch('OPEN_WIDGET', 'color picker')
      },
      'ok, i\'m done': (e) => { e.goTo('finished') }
    }
  },
  {
    id: 'finished',
    content: 'Great! hope you had a good time!',
    options: {
      'i did, thnx': () => {
        STORE.dispatch('FINISH_TUTORIAL')
      }
    }
  },
]

netnet dialogue

Clone this wiki locally