From 50595f9e1b05d33f47e540c24e33e50bd1625315 Mon Sep 17 00:00:00 2001 From: Li Haoyi Date: Fri, 14 Nov 2014 16:05:31 -0800 Subject: Moved some stuff around --- examples/demos/Controller.scala | 100 --------------------- examples/demos/ScrollMenu.scala | 50 ----------- .../src/main/scala/scrollmenu/Controller.scala | 99 ++++++++++++++++++++ .../src/main/scala/scrollmenu/ScrollMenu.scala | 49 ++++++++++ 4 files changed, 148 insertions(+), 150 deletions(-) delete mode 100644 examples/demos/Controller.scala delete mode 100644 examples/demos/ScrollMenu.scala create mode 100644 examples/demos/src/main/scala/scrollmenu/Controller.scala create mode 100644 examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala (limited to 'examples') diff --git a/examples/demos/Controller.scala b/examples/demos/Controller.scala deleted file mode 100644 index 6fd7ac7..0000000 --- a/examples/demos/Controller.scala +++ /dev/null @@ -1,100 +0,0 @@ -import acyclic.file -import scala.scalajs.js -import scala.scalajs.js.annotation.JSExport -import org.scalajs.dom -import org.scalajs.dom.extensions._ -import scala.collection.mutable -import scalatags.JsDom.all._ - - - -@JSExport -object Controller{ - - def munge(name: String) = { - name.replace(" ", "") - } - - @JSExport - def main(data: scala.scalajs.js.Any) = { - - val structure = upickle.readJs[Tree[String]](upickle.json.readJs(data)) - var i = 0 - def recurse(t: Tree[String], depth: Int): Tree[MenuNode] = { - val curr = - li( - a( - t.value, - href:="#"+munge(t.value), - cls:="menu-item" - ) - ) - val originalI = i - i += 1 - val children = t.children.map(recurse(_, depth + 1)) - Tree( - MenuNode( - curr(ul(paddingLeft := "15px",children.map(_.value.frag))).render, - originalI, - if (children.length > 0) children.map(_.value.end).max else originalI + 1 - ), - children - ) - } - - val Seq(main, menu, layout, menuLink) = Seq( - "main", "menu", "layout", "menuLink" - ).map(dom.document.getElementById) - - val snippets = dom.document.getElementsByClassName("highlight-me") - - snippets.foreach(js.Dynamic.global.hljs.highlightBlock(_)) - def offset(el: dom.HTMLElement, parent: dom.HTMLElement): Double = { - if (el == parent) 0 - else el.offsetTop + offset(el.offsetParent.asInstanceOf[dom.HTMLElement], parent) - } - val headers = { - - val menuItems = { - def rec(current: Tree[String]): Seq[String] = { - current.value +: current.children.flatMap(rec) - } - rec(structure).tail - } - menuItems.map(munge) - .map(dom.document.getElementById) - .map(offset(_, main)) - .toVector - } - println(headers) - - - - val domTrees = structure.children.map(recurse(_, 0)) - val scrollSpy = new ScrollSpy(headers, domTrees) - menu.appendChild( - div(cls:="pure-menu pure-menu-open")( - a(cls:="pure-menu-heading", href:="#")( - "Contents" - ), - ul(cls:="menu-item-list")( - domTrees.map(_.value.frag) - ) - ).render - ) - menuLink.onclick = (e: dom.MouseEvent) => { - layout.classList.toggle("active") - menu.classList.toggle("active") - menuLink.classList.toggle("active") - } - - - main.onscroll = (e: dom.UIEvent) => { - scrollSpy(main.scrollTop + main.clientHeight) - } - } - def isElementInViewport(el: dom.HTMLElement) = { - val rect = el.getBoundingClientRect() - rect.top >= 0 && rect.bottom <= dom.innerHeight - } -} diff --git a/examples/demos/ScrollMenu.scala b/examples/demos/ScrollMenu.scala deleted file mode 100644 index ccab4e9..0000000 --- a/examples/demos/ScrollMenu.scala +++ /dev/null @@ -1,50 +0,0 @@ -import acyclic.file -import org.scalajs.dom - -case class Tree[T](value: T, children: Vector[Tree[T]]) - -case class MenuNode(frag: dom.HTMLElement, start: Int, end: Int) - -/** - * High performance scrollspy to - */ -class ScrollSpy(headers: Vector[Double], domTrees: Seq[Tree[MenuNode]]){ - var scrolling = false - var lastSelected: dom.HTMLElement = null - def apply(threshold: Double) = if (!scrolling){ - scrolling = true - dom.requestAnimationFrame((d: Double) => start(threshold)) - } - def start(threshold: Double) = { - scrolling = false - def walkTree(tree: Tree[MenuNode]): Boolean = { - val Tree(MenuNode(menuItem, index, next), children) = tree - val before = headers(index) < threshold - val after = (next >= headers.length) || headers(next) > threshold - val win = before && after - if (win){ - menuItem.classList.remove("hide") - var winFound = false - - for(c <- tree.children){ - val newWinFound = walkTree(c) - if (!winFound) c.value.frag.classList.add("selected") - else c.value.frag.classList.remove("selected") - winFound = winFound | newWinFound - } - if (!winFound) { - tree.children.foreach(_.value.frag.classList.remove("selected")) - if (lastSelected != null) - lastSelected.children(0).classList.remove("pure-menu-selected") - menuItem.children(0).classList.add("pure-menu-selected") - lastSelected = menuItem - } - }else{ - menuItem.classList.add("hide") - menuItem.classList.remove("selected") - } - win - } - domTrees.map(walkTree) - } -} \ No newline at end of file diff --git a/examples/demos/src/main/scala/scrollmenu/Controller.scala b/examples/demos/src/main/scala/scrollmenu/Controller.scala new file mode 100644 index 0000000..1fcb68c --- /dev/null +++ b/examples/demos/src/main/scala/scrollmenu/Controller.scala @@ -0,0 +1,99 @@ +package scrollmenu + +import org.scalajs.dom +import org.scalajs.dom.extensions._ + +import scala.scalajs.js +import scala.scalajs.js.annotation.JSExport +import scalatags.JsDom.all._ + + + +@JSExport +object Controller{ + + def munge(name: String) = { + name.replace(" ", "") + } + + @JSExport + def main(data: scala.scalajs.js.Any) = { + + val structure = upickle.readJs[Tree[String]](upickle.json.readJs(data)) + var i = 0 + def recurse(t: Tree[String], depth: Int): Tree[MenuNode] = { + val curr = + li( + a( + t.value, + href:="#"+munge(t.value), + cls:="menu-item" + ) + ) + val originalI = i + i += 1 + val children = t.children.map(recurse(_, depth + 1)) + Tree( + MenuNode( + curr(ul(paddingLeft := "15px",children.map(_.value.frag))).render, + originalI, + if (children.length > 0) children.map(_.value.end).max else originalI + 1 + ), + children + ) + } + + val Seq(main, menu, layout, menuLink) = Seq( + "main", "menu", "layout", "menuLink" + ).map(dom.document.getElementById) + + val snippets = dom.document.getElementsByClassName("highlight-me") + + snippets.foreach(js.Dynamic.global.hljs.highlightBlock(_)) + def offset(el: dom.HTMLElement, parent: dom.HTMLElement): Double = { + if (el == parent) 0 + else el.offsetTop + offset(el.offsetParent.asInstanceOf[dom.HTMLElement], parent) + } + val headers = { + + val menuItems = { + def rec(current: Tree[String]): Seq[String] = { + current.value +: current.children.flatMap(rec) + } + rec(structure).tail + } + menuItems.map(munge) + .map(dom.document.getElementById) + .map(offset(_, main)) + .toVector + } + + val domTrees = structure.children.map(recurse(_, 0)) + val scrollSpy = new ScrollSpy(headers, domTrees) + + menu.appendChild( + div(cls:="pure-menu pure-menu-open")( + a(cls:="pure-menu-heading", href:="#")( + "Contents" + ), + ul(cls:="menu-item-list")( + domTrees.map(_.value.frag) + ) + ).render + ) + + menuLink.onclick = (e: dom.MouseEvent) => { + layout.classList.toggle("active") + menu.classList.toggle("active") + menuLink.classList.toggle("active") + } + + main.onscroll = (e: dom.UIEvent) => { + scrollSpy(main.scrollTop + main.clientHeight) + } + } + def isElementInViewport(el: dom.HTMLElement) = { + val rect = el.getBoundingClientRect() + rect.top >= 0 && rect.bottom <= dom.innerHeight + } +} diff --git a/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala b/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala new file mode 100644 index 0000000..9c0fbd2 --- /dev/null +++ b/examples/demos/src/main/scala/scrollmenu/ScrollMenu.scala @@ -0,0 +1,49 @@ +package scrollmenu + +import org.scalajs.dom + +case class Tree[T](value: T, children: Vector[Tree[T]]) + +case class MenuNode(frag: dom.HTMLElement, start: Int, end: Int) + +/** + * High performance scrollspy to work keep the left menu bar in sync. + * Lots of sketchy imperative code in order to maximize performance. + */ +class ScrollSpy(headers: Vector[Double], domTrees: Seq[Tree[MenuNode]]){ + var scrolling = false + def apply(threshold: Double) = if (!scrolling){ + scrolling = true + dom.requestAnimationFrame((d: Double) => start(threshold)) + } + def start(threshold: Double) = { + scrolling = false + def walkTree(tree: Tree[MenuNode]): Boolean = { + val Tree(MenuNode(menuItem, index, next), children) = tree + val before = headers(index) < threshold + val after = (next >= headers.length) || headers(next) > threshold + val win = before && after + if (win){ + menuItem.classList.remove("hide") + var winFound = false + + for(c <- tree.children){ + val newWinFound = walkTree(c) + if (!winFound) c.value.frag.classList.add("selected") + else c.value.frag.classList.remove("selected") + winFound = winFound | newWinFound + } + if (!winFound) { + tree.children.foreach(_.value.frag.classList.remove("selected")) + } + menuItem.children(0).classList.add("pure-menu-selected") + }else{ + menuItem.children(0).classList.remove("pure-menu-selected") + menuItem.classList.add("hide") + menuItem.classList.remove("selected") + } + win + } + domTrees.map(walkTree) + } +} \ No newline at end of file -- cgit v1.2.3