Permalink
Browse files

add the WebGL hook for the rgl package: http://stackoverflow.com/q/14…

  • Loading branch information...
1 parent f55dd71 commit 1f18ebbd22266fe988c05dff0ccad440e7f7442c @yihui committed Feb 15, 2013
Showing with 22 additions and 0 deletions.
  1. +2 −0 NEWS.md
  2. +20 −0 R/hooks-extra.R
View
@@ -14,6 +14,8 @@
- a new function `knit2wp()` which compiles R Markdown documents and publishes the results to WordPress; see http://yihui.name/knitr/demo/wordpress/ for details
+- a new hook `hook_webgl()` which writes the WebGL code of an **rgl** scene into the output using `rgl::writeWebGL()` so we can reproduce a 3D plot in the browser (thanks, Stephane Laurent http://stackoverflow.com/q/14879210/559676)
+
## BUG FIXES
- fixed #465: when `eval=FALSE` and `echo` is numeric, code was incorrectly filtered by the indices in `echo` (thanks, @ateucher)
View
@@ -13,6 +13,10 @@
#' according to chunk options \code{fig.width} and \code{fig.height}. Filenames
#' are derived from chunk labels and the \code{fig.path} option.
#'
+#' The function \code{hook_webgl} is a wrapper for the
+#' \code{\link[rgl]{writeWebGL}()} function in the \pkg{rgl} package. It writes
+#' WebGL code to the output to reproduce the \pkg{rgl} scene in a browser.
+#'
#' The function \code{hook_pdfcrop} can use the program \command{pdfcrop} to
#' crop the extra white margin when the plot format is PDF to make better use of
#' the space in the output document, otherwise we often have to struggle with
@@ -126,3 +130,19 @@ hook_plot_custom = function(before, options, envir){
str_c(res, collapse = '')
}
}
+#' @export
+#' @rdname chunk_hook
+hook_webgl = function(before, options, envir) {
+ library(rgl)
+ ## after a chunk has been evaluated
+ if (before || rgl.cur() == 0) return() # no active device
+ name = tempfile('rgl', '.', '.html'); on.exit(unlink(name))
+ par3d(windowRect = 100 + options$dpi * c(0, 0, options$fig.width, options$fig.height))
+ Sys.sleep(.05) # need time to respond to window size change
+
+ writeLines(c('%WebGL%', '<script>webGLStart();</script>'), tpl <- tempfile())
+ writeWebGL(dir = dirname(name), filename = name, template = tpl)
+ res = readLines(name)
+ res = res[!grepl('^\\s*$', res)] # remove blank lines
+ paste(gsub('^\\s*<', '<', res), collapse = '\n') # no spaces before HTML tags
+}

2 comments on commit 1f18ebb

Contributor
kohske commented on 1f18ebb Dec 19, 2013

This hook works brilliantly, and will you add a hook for webgl while embedding js file into the output html file?

Here is a pseudo code:

r <- capture.output(writeWebGL(file="", template=textConnection(c('%WebGL%', '<script>webGLStart();</script>')), snapshot=FALSE)))
r <- r[-grep("CanvasMatrix.js", r)]

cat('<script type="text/javascript">\n')
writeLines(readLines(system.file(file.path("WebGL", "CanvasMatrix.js"), package = "rgl")))
cat('</script>\n')
writeLines(r)

I want to make all stuff into a single file, which make to distribute the html much easier.
E.g., I cannot publish on Rpubs without embedding into one file (or replacing the link to JS by external web link).

I don't know how to embed the permission statement. Maybe the permission statement of CanvasMatrix.js should appear in the html file?

thanks,

kohske

Owner

I just put this in an Rmd document:

```{r setup, results='asis'}
knit_hooks$set(webgl = hook_webgl)
cat('<script type="text/javascript">', readLines(system.file('WebGL', 'CanvasMatrix.js', package = 'rgl')),
    '</script>', sep = '\n')
```

And it worked on RPubs: http://rpubs.com/yihui/webgl-rmd

Please sign in to comment.