├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── NAMESPACE ├── Package Helper.R ├── R ├── basic_html.R ├── helpers.R ├── html_stimulus.R ├── run_locally.R ├── stimulus_df_to_json.R ├── utils-pipe.R └── write_to_script.R ├── README.md ├── _pkgdown.yml ├── docs ├── 404.html ├── articles │ ├── closerlook.html │ ├── expo.png │ ├── index.html │ ├── jspsychr.html │ └── recognition.html ├── authors.html ├── docsearch.css ├── docsearch.js ├── index.html ├── link.svg ├── logo.png ├── pkgdown.css ├── pkgdown.js ├── pkgdown.yml ├── reference │ ├── figures │ │ ├── expo.png │ │ └── logo.png │ ├── html_stimulus.html │ ├── index.html │ ├── pipe.html │ ├── resource.html │ ├── run_locally.html │ ├── stimulus_df_to_json.html │ ├── unquote.html │ └── write_to_script.html └── sitemap.xml ├── inst └── rmarkdown │ ├── basic_template.html │ └── templates │ ├── jspsychr │ ├── skeleton │ │ ├── experiment │ │ │ ├── index.Rmd │ │ │ ├── index.html │ │ │ ├── jspsych-6-2 │ │ │ │ ├── css │ │ │ │ │ └── jspsych.css │ │ │ │ ├── examples │ │ │ │ │ ├── add-to-end-of-timeline.html │ │ │ │ │ ├── conditional-and-loop-functions.html │ │ │ │ │ ├── css │ │ │ │ │ │ └── jquery-ui.css │ │ │ │ │ ├── data-add-properties.html │ │ │ │ │ ├── data-as-function.html │ │ │ │ │ ├── data-from-timeline.html │ │ │ │ │ ├── data-from-url.html │ │ │ │ │ ├── demo-flanker.html │ │ │ │ │ ├── demo-simple-rt-task.html │ │ │ │ │ ├── demos │ │ │ │ │ │ ├── demo_1.html │ │ │ │ │ │ ├── demo_2.html │ │ │ │ │ │ └── demo_3.html │ │ │ │ │ ├── display-element-to-embed-experiment.html │ │ │ │ │ ├── end-active-node.html │ │ │ │ │ ├── end-experiment.html │ │ │ │ │ ├── exclusions.html │ │ │ │ │ ├── external_html │ │ │ │ │ │ └── simple_consent.html │ │ │ │ │ ├── img │ │ │ │ │ │ ├── 1.gif │ │ │ │ │ │ ├── 10.gif │ │ │ │ │ │ ├── 11.gif │ │ │ │ │ │ ├── 12.gif │ │ │ │ │ │ ├── 2.gif │ │ │ │ │ │ ├── 3.gif │ │ │ │ │ │ ├── 4.gif │ │ │ │ │ │ ├── 5.gif │ │ │ │ │ │ ├── 6.gif │ │ │ │ │ │ ├── 7.gif │ │ │ │ │ │ ├── 8.gif │ │ │ │ │ │ ├── 9.gif │ │ │ │ │ │ ├── age │ │ │ │ │ │ │ ├── of1.jpg │ │ │ │ │ │ │ ├── of2.jpg │ │ │ │ │ │ │ ├── of3.jpg │ │ │ │ │ │ │ ├── om1.jpg │ │ │ │ │ │ │ ├── om2.jpg │ │ │ │ │ │ │ ├── om3.jpg │ │ │ │ │ │ │ ├── yf1.jpg │ │ │ │ │ │ │ ├── yf4.jpg │ │ │ │ │ │ │ ├── yf5.jpg │ │ │ │ │ │ │ ├── ym2.jpg │ │ │ │ │ │ │ ├── ym3.jpg │ │ │ │ │ │ │ └── ym5.jpg │ │ │ │ │ │ ├── backwardN.gif │ │ │ │ │ │ ├── blue.png │ │ │ │ │ │ ├── con1.png │ │ │ │ │ │ ├── con2.png │ │ │ │ │ │ ├── fixation.gif │ │ │ │ │ │ ├── happy_face_1.jpg │ │ │ │ │ │ ├── happy_face_2.jpg │ │ │ │ │ │ ├── happy_face_3.jpg │ │ │ │ │ │ ├── happy_face_4.jpg │ │ │ │ │ │ ├── inc1.png │ │ │ │ │ │ ├── inc2.png │ │ │ │ │ │ ├── normalN.gif │ │ │ │ │ │ ├── orange.png │ │ │ │ │ │ ├── redX.png │ │ │ │ │ │ ├── ribbon.jpg │ │ │ │ │ │ ├── sad_face_1.jpg │ │ │ │ │ │ ├── sad_face_2.jpg │ │ │ │ │ │ ├── sad_face_3.jpg │ │ │ │ │ │ └── sad_face_4.jpg │ │ │ │ │ ├── js │ │ │ │ │ │ └── snap.svg-min.js │ │ │ │ │ ├── jspsych-animation.html │ │ │ │ │ ├── jspsych-audio-button-response.html │ │ │ │ │ ├── jspsych-audio-keyboard-response.html │ │ │ │ │ ├── jspsych-audio-slider-response.html │ │ │ │ │ ├── jspsych-call-function.html │ │ │ │ │ ├── jspsych-categorize-animation.html │ │ │ │ │ ├── jspsych-categorize-html.html │ │ │ │ │ ├── jspsych-categorize-image.html │ │ │ │ │ ├── jspsych-cloze.html │ │ │ │ │ ├── jspsych-free-sort.html │ │ │ │ │ ├── jspsych-fullscreen.html │ │ │ │ │ ├── jspsych-html-button-response.html │ │ │ │ │ ├── jspsych-html-keyboard-response.html │ │ │ │ │ ├── jspsych-html-slider-response.html │ │ │ │ │ ├── jspsych-iat.html │ │ │ │ │ ├── jspsych-image-button-response.html │ │ │ │ │ ├── jspsych-image-keyboard-response.html │ │ │ │ │ ├── jspsych-image-slider-response.html │ │ │ │ │ ├── jspsych-instructions.html │ │ │ │ │ ├── jspsych-rdk.html │ │ │ │ │ ├── jspsych-reconstruction.html │ │ │ │ │ ├── jspsych-resize.html │ │ │ │ │ ├── jspsych-same-different-html.html │ │ │ │ │ ├── jspsych-same-different-image.html │ │ │ │ │ ├── jspsych-serial-reaction-time-mouse.html │ │ │ │ │ ├── jspsych-serial-reaction-time.html │ │ │ │ │ ├── jspsych-survey-html-form.html │ │ │ │ │ ├── jspsych-survey-likert.html │ │ │ │ │ ├── jspsych-survey-multi-choice.html │ │ │ │ │ ├── jspsych-survey-multi-select.html │ │ │ │ │ ├── jspsych-survey-text.html │ │ │ │ │ ├── jspsych-video-button-response.html │ │ │ │ │ ├── jspsych-video-keyboard-response.html │ │ │ │ │ ├── jspsych-video-slider-response.html │ │ │ │ │ ├── jspsych-visual-search-circle.html │ │ │ │ │ ├── jspsych-vsl-animate-occlusion.html │ │ │ │ │ ├── jspsych-vsl-grid-scene.html │ │ │ │ │ ├── lexical-decision.html │ │ │ │ │ ├── manual-preloading.html │ │ │ │ │ ├── pause-unpause.html │ │ │ │ │ ├── progress-bar.html │ │ │ │ │ ├── sound │ │ │ │ │ │ ├── hammer.mp3 │ │ │ │ │ │ ├── sound.mp3 │ │ │ │ │ │ ├── speech_blue.mp3 │ │ │ │ │ │ ├── speech_green.mp3 │ │ │ │ │ │ ├── speech_joke.mp3 │ │ │ │ │ │ ├── speech_red.mp3 │ │ │ │ │ │ └── tone.mp3 │ │ │ │ │ ├── timeline-variables-sampling.html │ │ │ │ │ ├── timeline-variables.html │ │ │ │ │ └── video │ │ │ │ │ │ └── sample_video.mp4 │ │ │ │ ├── jspsych.js │ │ │ │ ├── license.txt │ │ │ │ └── plugins │ │ │ │ │ ├── jspsych-animation.js │ │ │ │ │ ├── jspsych-audio-button-response.js │ │ │ │ │ ├── jspsych-audio-keyboard-response.js │ │ │ │ │ ├── jspsych-audio-slider-response.js │ │ │ │ │ ├── jspsych-call-function.js │ │ │ │ │ ├── jspsych-categorize-animation.js │ │ │ │ │ ├── jspsych-categorize-html.js │ │ │ │ │ ├── jspsych-categorize-image.js │ │ │ │ │ ├── jspsych-cloze.js │ │ │ │ │ ├── jspsych-external-html.js │ │ │ │ │ ├── jspsych-free-sort.js │ │ │ │ │ ├── jspsych-fullscreen.js │ │ │ │ │ ├── jspsych-html-button-response.js │ │ │ │ │ ├── jspsych-html-keyboard-response.js │ │ │ │ │ ├── jspsych-html-slider-response.js │ │ │ │ │ ├── jspsych-iat-html.js │ │ │ │ │ ├── jspsych-iat-image.js │ │ │ │ │ ├── jspsych-image-button-response.js │ │ │ │ │ ├── jspsych-image-keyboard-response.js │ │ │ │ │ ├── jspsych-image-slider-response.js │ │ │ │ │ ├── jspsych-instructions.js │ │ │ │ │ ├── jspsych-rdk.js │ │ │ │ │ ├── jspsych-reconstruction.js │ │ │ │ │ ├── jspsych-resize.js │ │ │ │ │ ├── jspsych-same-different-html.js │ │ │ │ │ ├── jspsych-same-different-image.js │ │ │ │ │ ├── jspsych-serial-reaction-time-mouse.js │ │ │ │ │ ├── jspsych-serial-reaction-time.js │ │ │ │ │ ├── jspsych-survey-html-form.js │ │ │ │ │ ├── jspsych-survey-likert.js │ │ │ │ │ ├── jspsych-survey-multi-choice.js │ │ │ │ │ ├── jspsych-survey-multi-select.js │ │ │ │ │ ├── jspsych-survey-text.js │ │ │ │ │ ├── jspsych-video-button-response.js │ │ │ │ │ ├── jspsych-video-keyboard-response.js │ │ │ │ │ ├── jspsych-video-slider-response.js │ │ │ │ │ ├── jspsych-visual-search-circle.js │ │ │ │ │ ├── jspsych-vsl-animate-occlusion.js │ │ │ │ │ ├── jspsych-vsl-grid-scene.js │ │ │ │ │ └── template │ │ │ │ │ └── jspsych-plugin-template.js │ │ │ └── jspsychr │ │ │ │ └── jspsychr.js │ │ ├── run.R │ │ └── skeleton.Rmd │ └── template.yaml │ └── jspsychr_basic_html │ ├── skeleton │ └── skeleton.Rmd │ └── template.yaml ├── jsPsychR.Rproj ├── man ├── basic_html.Rd ├── figures │ ├── expo.png │ └── logo.png ├── html_stimulus.Rd ├── pipe.Rd ├── resource.Rd ├── run_locally.Rd ├── stimulus_df_to_json.Rd ├── unquote.Rd └── write_to_script.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── vignettes ├── .gitignore ├── closerlook.Rmd ├── expo.png ├── jspsychr.Rmd └── recognition.Rmd └── xtra └── logo.png /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^_pkgdown\.yml$ 4 | ^docs$ 5 | ^pkgdown$ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | inst/doc 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: jspsychr 2 | Title: Templates and functions for writing and running jspsych experiments from R-studio 3 | Version: 0.0.1.0000 4 | Date: 2019-12-13 5 | URL: https://github.com/CrumpLab/jspsychr 6 | Authors@R: 7 | person(given = "Matthew J. C.", 8 | family = "Crump", 9 | role = c("aut", "cre"), 10 | email = "mcrump@brooklyn.cuny.edu", 11 | comment = c(ORCID = "0000-0002-5612-0090")) 12 | Description: Templates and functions for writing and running jspsych experiments from R-studio. 13 | License: MIT + file LICENSE 14 | Encoding: UTF-8 15 | LazyData: true 16 | RoxygenNote: 7.1.2 17 | Imports: 18 | plumber, 19 | jsonlite, 20 | readr, 21 | tidyr, 22 | htmltools, 23 | magrittr 24 | Suggests: 25 | knitr, 26 | rmarkdown 27 | VignetteBuilder: knitr 28 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(basic_html) 5 | export(html_stimulus) 6 | export(resource) 7 | export(run_locally) 8 | export(stimulus_df_to_json) 9 | export(unquote) 10 | export(write_to_script) 11 | importFrom(magrittr,"%>%") 12 | -------------------------------------------------------------------------------- /Package Helper.R: -------------------------------------------------------------------------------- 1 | # Package helper 2 | library(usethis) # helpful automation functions for common tasks in package development 3 | library(pkgdown) # compile your R package to a website 4 | 5 | pkgdown::build_site() 6 | 7 | # generate description file with your info (need to set your info in advanve) 8 | usethis::use_description() 9 | 10 | # generate readme file, the contents control front page of pkgdown website 11 | usethis::use_readme_md() 12 | 13 | # create a vignette (.Rmd) document that gets compiled and displayed on pkdown website 14 | usethis::use_vignette("recognition", title="Walkthrough to build a Recognition memory experiment") 15 | 16 | pkgdown::template_navbar() # generate yml for controlling navbar 17 | 18 | render_folder_to_docs("slides") 19 | 20 | usethis::use_logo("xtra/logo.png") 21 | 22 | usethis::use_news_md() 23 | 24 | usethis::use_pkgdown() 25 | 26 | usethis::use_package("htmltools") 27 | 28 | -------------------------------------------------------------------------------- /R/basic_html.R: -------------------------------------------------------------------------------- 1 | # author: Matt Crump 2 | #' compile with minimal html template 3 | #' 4 | #' @param css string, paths to css files 5 | #' 6 | #' @return compiled html document 7 | #' @export 8 | #' 9 | #' @description Useful for creating external htmls in jspsych 10 | #' 11 | #' @examples 12 | #' 13 | #' 14 | basic_html <- function(...){ 15 | 16 | template <- system.file("rmarkdown/basic_template.html",package="jspsychr") 17 | 18 | rmarkdown::html_document( 19 | template = template, 20 | ... 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /R/helpers.R: -------------------------------------------------------------------------------- 1 | # file: helpers.R 2 | # author: Danielle Navarro 3 | 4 | 5 | #' Refer to a resource file 6 | #' 7 | #' @param file path 8 | #' @export 9 | resource <- function(file) { 10 | file.path("resources", file) 11 | } 12 | 13 | 14 | #' Specify js code directly 15 | #' 16 | #' @param x the code as a string 17 | #' @export 18 | unquote <- function(x) { 19 | class(x) <- "json" 20 | x 21 | } 22 | 23 | 24 | get_timestamp <- function() { 25 | tsp <- as.character(Sys.time()) 26 | tsp <- gsub("[ :]", "-", tsp) 27 | return(tsp) 28 | } 29 | 30 | get_alphanumeric <- function(n = 5) { 31 | x <- c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r", 32 | "s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9") 33 | r <- sample(x, size = n, replace = TRUE) 34 | r <- paste(r, collapse = "") 35 | return(r) 36 | } 37 | -------------------------------------------------------------------------------- /R/html_stimulus.R: -------------------------------------------------------------------------------- 1 | # file: html_stimulus.R 2 | # author: Matt Crump 3 | 4 | #' Write html stimulus description from dataframe 5 | #' 6 | #' @param df data.frame containing stimulus information and css codes in columns 7 | #' @param html_content character column name containing html content to be placed between html element tags 8 | #' @param html_element character the html element tag to use 9 | #' @param column_names vector of column names containing css attribute definitions 10 | #' @param css vector of names containing valid css attribute names 11 | #' @param id character to set the id of the html element, defaults to "my_stim" 12 | #' 13 | #' @return vector of html code defining each stimulus 14 | #' @export 15 | #' 16 | #' @examples 17 | #' 18 | #' # define a data frame with stimulus info 19 | #' stroop_stim <- data.frame(stimulus = length(16), 20 | #' word = rep(c("red","green","blue","yellow"), each=4), 21 | #' color = rep(c("red","green","blue","yellow"), 4), 22 | #' response = rep(c("r","g","b","y"), 4), 23 | #' id = "stroop_stim", 24 | #' fontsize = "16pt") 25 | #' 26 | #' head(stroop_stim) 27 | #' 28 | #' # create html stimulus definition 29 | #' html_stimulus(df = stroop_stim, 30 | #' html_content = "word", 31 | #' html_element = "p", 32 | #' column_names = c("color","fontsize"), 33 | #' css = c("color", "font-size"), 34 | #' id = "id" 35 | #' ) 36 | #' 37 | #' # use in a pipe to add stimulus definition to stimuli column 38 | #' library(dplyr) 39 | #' stroop_stim <- data.frame(stimulus = length(16), 40 | #' word = rep(c("red","green","blue","yellow"), each=4), 41 | #' color = rep(c("red","green","blue","yellow"), 4), 42 | #' response = rep(c("r","g","b","y"), 4), 43 | #' id = "stroop_stim", 44 | #' fontsize = "16pt") %>% 45 | #' mutate(stimulus = html_stimulus(df = ., 46 | #' html_content = "word", 47 | #' html_element = "p", 48 | #' column_names = c("color","fontsize"), 49 | #' css = c("color", "font-size"), 50 | #' id = "id")) 51 | #' head(stroop_stim) 52 | #' 53 | #' 54 | html_stimulus <- function(df, html_content, html_element, column_names, css=NULL, id="my_stim"){ 55 | 56 | # assign ids 57 | if(!is.null(df$id)){ 58 | write_id <- paste("id = '", df[,id],"'", sep="")} 59 | else{ 60 | write_id <- paste("id = '", id,"'", sep="") 61 | } 62 | 63 | 64 | # if css is NULL assume column_names are valid css attributes 65 | if(is.null(css)) css <- column_names 66 | 67 | # write style definitions for each css attribute 68 | css_df <- data.frame(row.names=1:dim(df)[1]) 69 | for(i in 1:length(column_names)){ 70 | css_df[,i] <- paste(css[i],": ", df[,column_names[i]], ";", sep="") 71 | } 72 | 73 | # paste together in one style definition 74 | css_df <- tidyr::unite(css_df, col="style", sep=" ") 75 | write_style <- paste("style = '",css_df$style,"'",sep="") 76 | 77 | #write the html element definition 78 | write_html <- paste("<",html_element," ", 79 | write_id, " ", 80 | write_style,">", 81 | df[,html_content], 82 | "", sep="") 83 | 84 | return(write_html) 85 | 86 | } 87 | -------------------------------------------------------------------------------- /R/run_locally.R: -------------------------------------------------------------------------------- 1 | # file: run_locally.R 2 | # author: Danielle Navarro 3 | # modifications: Matt Crump 4 | # change xprmntr to jspsychr to avoid future conflict 5 | # added options to run in browser vs viewer, and report port 6 | 7 | #' Run a jspsych experiment 8 | #' 9 | #' @param path path 10 | #' @param show_in string, "viewer" to show in viewer, or "browser" to show in browser 11 | #' @param jspsychr_host host defaults to 127.0.0.1 12 | #' @param jspsychr_port port defaults to 8000 13 | #' @export 14 | run_locally <- function(path = ".", 15 | show_in = "viewer", 16 | jspsychr_host = "127.0.0.1", 17 | jspsychr_port = 8000) { 18 | 19 | pr <- plumber::plumber$new() 20 | 21 | static_site <- file.path(path, "experiment") 22 | data_folder <- file.path(path, "data") 23 | static_router <- plumber::PlumberStatic$new(static_site) 24 | 25 | pr$mount("/", static_router) 26 | pr$handle("POST", "/submit", function(req, res){ 27 | 28 | dat <- jsonlite::fromJSON(req$postBody) 29 | dat <- readr::read_csv(dat$filedata) 30 | tsp <- get_timestamp() 31 | file_id <- paste("data", get_timestamp(), get_alphanumeric(10), sep = "_") 32 | dat$file_id <- file_id 33 | dat <- dat[, c(ncol(dat), 1:ncol(dat)-1), drop = FALSE] 34 | readr::write_csv(dat, file.path(data_folder, paste0(file_id, ".csv"))) 35 | }) 36 | 37 | # add message, and options to display in viewer or browser 38 | message(paste("Point the browser to http://",jspsychr_host,":",jspsychr_port, sep="")) 39 | 40 | if(show_in == "viewer"){ 41 | viewer <- getOption("viewer") 42 | viewer(paste("http://",jspsychr_host,":",jspsychr_port, sep="")) 43 | } 44 | if(show_in == "browser") utils::browseURL(paste("http://",jspsychr_host,":",jspsychr_port, sep="")) 45 | # 46 | 47 | pr$run(swagger = FALSE, host=jspsychr_host, port= jspsychr_port) 48 | 49 | } 50 | -------------------------------------------------------------------------------- /R/stimulus_df_to_json.R: -------------------------------------------------------------------------------- 1 | # author: Matt Crump 2 | 3 | #' Convert stimulus dataframe to json object 4 | #' 5 | #' @param df dataframe containins stimulus column with html for each stimulus, and additional columns for data codes 6 | #' @param stimulus character name of the stimulus column 7 | #' @param data character vector names of columns to include as data codes 8 | #' @param pretty logical true = pretty format, false=not pretty 9 | #' @return string a json object definition that can supply jsPsych with stimulus information 10 | #' @export 11 | #' 12 | #' @examples 13 | #' 14 | #' # create a stimulus dataframe 15 | #' library(dplyr) 16 | #' stroop_stim <- data.frame(stimulus = length(16), 17 | #' word = rep(c("red","green","blue","yellow"), each=4), 18 | #' color = rep(c("red","green","blue","yellow"), 4), 19 | #' response = rep(c("r","g","b","y"), 4), 20 | #' id = "stroop_stim", 21 | #' fontsize = "16pt") %>% 22 | #' mutate(stimulus = html_stimulus(df = ., 23 | #' html_content = "word", 24 | #' html_element = "p", 25 | #' column_names = c("color","fontsize"), 26 | #' css = c("color", "font-size"), 27 | #' id = "id")) 28 | #' head(stroop_stim) 29 | #' 30 | #' # convert to json 31 | #' stimulus_df_to_json(stroop_stim,"stimulus",c("word","color","response")) 32 | #' 33 | stimulus_df_to_json <- function(df,stimulus, data, pretty=TRUE){ 34 | temp_list <- list() 35 | for(i in 1:dim(df)[1]){ 36 | temp_list[[i]] <- list(stimulus = df[i,stimulus], 37 | data = as.list(df[i,data])) 38 | } 39 | return(jsonlite::toJSON(temp_list, auto_unbox = TRUE, pretty=pretty)) 40 | } 41 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /R/write_to_script.R: -------------------------------------------------------------------------------- 1 | # author: Matt Crump 2 | #' Write json to js script 3 | #' 4 | #' @param json_object string a json object 5 | #' @param var_name character default=NULL, set name to declare json object as a variable 6 | #' 7 | #' @return string printed to the html as a 8 | #' @export 9 | #' 10 | #' @description To be used in a knitr code chunk with results="asis" 11 | #' 12 | #' @examples 13 | #' 14 | #' 15 | write_to_script <- function(json_object,var_name=NULL){ 16 | if(is.null(var_name)){ 17 | return(cat("")) 18 | }else{ 19 | return(cat("")) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jspsychr 2 | 3 | [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://www.tidyverse.org/lifecycle/#experimental) 4 | 5 | This is an R markdown template and functions for writing and running jspsych experiments using R studio. 6 | 7 | - [jspsych](https://www.jspsych.org) is javascript library for web-based behavioral experiments written by Josh De Leeuw. 8 | 9 | - If you are interested in other approaches to build jspsych experiments, also check out Danielle Navarro's [xprmntr](https://github.com/djnavarro/xprmntr), and [jaysire](https://github.com/djnavarro/jaysire) 10 | 11 | - jspsychr developed as a forked offshoot of the original xprmntr package 12 | 13 | ## Install 14 | 15 | ``` 16 | # install.packages("devtools") 17 | devtools::install_github("CrumpLab/jspsychr") 18 | ``` 19 | 20 |
21 |
22 | 23 |

Overview

24 | 25 | 26 | 27 |
28 |
29 | 30 |

Examples

31 | 32 | Read the getting started article (above) for an overview of how `jspsychr` works, and/or head over to the examples repo to see some examples, https://github.com/CrumpLab/jspsychrexamples 33 | 34 |

Contributors

35 | 36 | Matt Crump {jspsychr}, Danielle Navarro {code to run experiments locally with plumber, and to save data from a local session}; Josh De Leeuw {the jspsych javascript library} 37 | 38 |
39 |
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | destination: docs 2 | 3 | url: https://crumplab.github.io/jspsychr 4 | 5 | template: 6 | opengraph: 7 | img: logo.png 8 | -------------------------------------------------------------------------------- /docs/articles/expo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/docs/articles/expo.png -------------------------------------------------------------------------------- /docs/docsearch.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | 3 | // register a handler to move the focus to the search bar 4 | // upon pressing shift + "/" (i.e. "?") 5 | $(document).on('keydown', function(e) { 6 | if (e.shiftKey && e.keyCode == 191) { 7 | e.preventDefault(); 8 | $("#search-input").focus(); 9 | } 10 | }); 11 | 12 | $(document).ready(function() { 13 | // do keyword highlighting 14 | /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ 15 | var mark = function() { 16 | 17 | var referrer = document.URL ; 18 | var paramKey = "q" ; 19 | 20 | if (referrer.indexOf("?") !== -1) { 21 | var qs = referrer.substr(referrer.indexOf('?') + 1); 22 | var qs_noanchor = qs.split('#')[0]; 23 | var qsa = qs_noanchor.split('&'); 24 | var keyword = ""; 25 | 26 | for (var i = 0; i < qsa.length; i++) { 27 | var currentParam = qsa[i].split('='); 28 | 29 | if (currentParam.length !== 2) { 30 | continue; 31 | } 32 | 33 | if (currentParam[0] == paramKey) { 34 | keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); 35 | } 36 | } 37 | 38 | if (keyword !== "") { 39 | $(".contents").unmark({ 40 | done: function() { 41 | $(".contents").mark(keyword); 42 | } 43 | }); 44 | } 45 | } 46 | }; 47 | 48 | mark(); 49 | }); 50 | }); 51 | 52 | /* Search term highlighting ------------------------------*/ 53 | 54 | function matchedWords(hit) { 55 | var words = []; 56 | 57 | var hierarchy = hit._highlightResult.hierarchy; 58 | // loop to fetch from lvl0, lvl1, etc. 59 | for (var idx in hierarchy) { 60 | words = words.concat(hierarchy[idx].matchedWords); 61 | } 62 | 63 | var content = hit._highlightResult.content; 64 | if (content) { 65 | words = words.concat(content.matchedWords); 66 | } 67 | 68 | // return unique words 69 | var words_uniq = [...new Set(words)]; 70 | return words_uniq; 71 | } 72 | 73 | function updateHitURL(hit) { 74 | 75 | var words = matchedWords(hit); 76 | var url = ""; 77 | 78 | if (hit.anchor) { 79 | url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; 80 | } else { 81 | url = hit.url + '?q=' + escape(words.join(" ")); 82 | } 83 | 84 | return url; 85 | } 86 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/docs/logo.png -------------------------------------------------------------------------------- /docs/pkgdown.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer */ 2 | 3 | /** 4 | * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ 5 | * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css 6 | * 7 | * .Site -> body > .container 8 | * .Site-content -> body > .container .row 9 | * .footer -> footer 10 | * 11 | * Key idea seems to be to ensure that .container and __all its parents__ 12 | * have height set to 100% 13 | * 14 | */ 15 | 16 | html, body { 17 | height: 100%; 18 | } 19 | 20 | body > .container { 21 | display: flex; 22 | height: 100%; 23 | flex-direction: column; 24 | } 25 | 26 | body > .container .row { 27 | flex: 1 0 auto; 28 | } 29 | 30 | footer { 31 | margin-top: 45px; 32 | padding: 35px 0 36px; 33 | border-top: 1px solid #e5e5e5; 34 | color: #666; 35 | display: flex; 36 | flex-shrink: 0; 37 | } 38 | footer p { 39 | margin-bottom: 0; 40 | } 41 | footer div { 42 | flex: 1; 43 | } 44 | footer .pkgdown { 45 | text-align: right; 46 | } 47 | footer p { 48 | margin-bottom: 0; 49 | } 50 | 51 | img.icon { 52 | float: right; 53 | } 54 | 55 | img { 56 | max-width: 100%; 57 | } 58 | 59 | /* Fix bug in bootstrap (only seen in firefox) */ 60 | summary { 61 | display: list-item; 62 | } 63 | 64 | /* Typographic tweaking ---------------------------------*/ 65 | 66 | .contents .page-header { 67 | margin-top: calc(-60px + 1em); 68 | } 69 | 70 | /* Section anchors ---------------------------------*/ 71 | 72 | a.anchor { 73 | margin-left: -30px; 74 | display:inline-block; 75 | width: 30px; 76 | height: 30px; 77 | visibility: hidden; 78 | 79 | background-image: url(./link.svg); 80 | background-repeat: no-repeat; 81 | background-size: 20px 20px; 82 | background-position: center center; 83 | } 84 | 85 | .hasAnchor:hover a.anchor { 86 | visibility: visible; 87 | } 88 | 89 | @media (max-width: 767px) { 90 | .hasAnchor:hover a.anchor { 91 | visibility: hidden; 92 | } 93 | } 94 | 95 | 96 | /* Fixes for fixed navbar --------------------------*/ 97 | 98 | .contents h1, .contents h2, .contents h3, .contents h4 { 99 | padding-top: 60px; 100 | margin-top: -40px; 101 | } 102 | 103 | /* Sidebar --------------------------*/ 104 | 105 | #sidebar { 106 | margin-top: 30px; 107 | position: -webkit-sticky; 108 | position: sticky; 109 | top: 70px; 110 | } 111 | #sidebar h2 { 112 | font-size: 1.5em; 113 | margin-top: 1em; 114 | } 115 | 116 | #sidebar h2:first-child { 117 | margin-top: 0; 118 | } 119 | 120 | #sidebar .list-unstyled li { 121 | margin-bottom: 0.5em; 122 | } 123 | 124 | .orcid { 125 | height: 16px; 126 | /* margins are required by official ORCID trademark and display guidelines */ 127 | margin-left:4px; 128 | margin-right:4px; 129 | vertical-align: middle; 130 | } 131 | 132 | /* Reference index & topics ----------------------------------------------- */ 133 | 134 | .ref-index th {font-weight: normal;} 135 | 136 | .ref-index td {vertical-align: top;} 137 | .ref-index .icon {width: 40px;} 138 | .ref-index .alias {width: 40%;} 139 | .ref-index-icons .alias {width: calc(40% - 40px);} 140 | .ref-index .title {width: 60%;} 141 | 142 | .ref-arguments th {text-align: right; padding-right: 10px;} 143 | .ref-arguments th, .ref-arguments td {vertical-align: top;} 144 | .ref-arguments .name {width: 20%;} 145 | .ref-arguments .desc {width: 80%;} 146 | 147 | /* Nice scrolling for wide elements --------------------------------------- */ 148 | 149 | table { 150 | display: block; 151 | overflow: auto; 152 | } 153 | 154 | /* Syntax highlighting ---------------------------------------------------- */ 155 | 156 | pre { 157 | word-wrap: normal; 158 | word-break: normal; 159 | border: 1px solid #eee; 160 | } 161 | 162 | pre, code { 163 | background-color: #f8f8f8; 164 | color: #333; 165 | } 166 | 167 | pre code { 168 | overflow: auto; 169 | word-wrap: normal; 170 | white-space: pre; 171 | } 172 | 173 | pre .img { 174 | margin: 5px 0; 175 | } 176 | 177 | pre .img img { 178 | background-color: #fff; 179 | display: block; 180 | height: auto; 181 | } 182 | 183 | code a, pre a { 184 | color: #375f84; 185 | } 186 | 187 | a.sourceLine:hover { 188 | text-decoration: none; 189 | } 190 | 191 | .fl {color: #1514b5;} 192 | .fu {color: #000000;} /* function */ 193 | .ch,.st {color: #036a07;} /* string */ 194 | .kw {color: #264D66;} /* keyword */ 195 | .co {color: #888888;} /* comment */ 196 | 197 | .message { color: black; font-weight: bolder;} 198 | .error { color: orange; font-weight: bolder;} 199 | .warning { color: #6A0366; font-weight: bolder;} 200 | 201 | /* Clipboard --------------------------*/ 202 | 203 | .hasCopyButton { 204 | position: relative; 205 | } 206 | 207 | .btn-copy-ex { 208 | position: absolute; 209 | right: 0; 210 | top: 0; 211 | visibility: hidden; 212 | } 213 | 214 | .hasCopyButton:hover button.btn-copy-ex { 215 | visibility: visible; 216 | } 217 | 218 | /* headroom.js ------------------------ */ 219 | 220 | .headroom { 221 | will-change: transform; 222 | transition: transform 200ms linear; 223 | } 224 | .headroom--pinned { 225 | transform: translateY(0%); 226 | } 227 | .headroom--unpinned { 228 | transform: translateY(-100%); 229 | } 230 | 231 | /* mark.js ----------------------------*/ 232 | 233 | mark { 234 | background-color: rgba(255, 255, 51, 0.5); 235 | border-bottom: 2px solid rgba(255, 153, 51, 0.3); 236 | padding: 1px; 237 | } 238 | 239 | /* vertical spacing after htmlwidgets */ 240 | .html-widget { 241 | margin-bottom: 10px; 242 | } 243 | 244 | /* fontawesome ------------------------ */ 245 | 246 | .fab { 247 | font-family: "Font Awesome 5 Brands" !important; 248 | } 249 | 250 | /* don't display links in code chunks when printing */ 251 | /* source: https://stackoverflow.com/a/10781533 */ 252 | @media print { 253 | code a:link:after, code a:visited:after { 254 | content: ""; 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('.navbar-fixed-top').headroom(); 6 | 7 | $('body').css('padding-top', $('.navbar').height() + 10); 8 | $(window).resize(function(){ 9 | $('body').css('padding-top', $('.navbar').height() + 10); 10 | }); 11 | 12 | $('body').scrollspy({ 13 | target: '#sidebar', 14 | offset: 60 15 | }); 16 | 17 | $('[data-toggle="tooltip"]').tooltip(); 18 | 19 | var cur_path = paths(location.pathname); 20 | var links = $("#navbar ul li a"); 21 | var max_length = -1; 22 | var pos = -1; 23 | for (var i = 0; i < links.length; i++) { 24 | if (links[i].getAttribute("href") === "#") 25 | continue; 26 | // Ignore external links 27 | if (links[i].host !== location.host) 28 | continue; 29 | 30 | var nav_path = paths(links[i].pathname); 31 | 32 | var length = prefix_length(nav_path, cur_path); 33 | if (length > max_length) { 34 | max_length = length; 35 | pos = i; 36 | } 37 | } 38 | 39 | // Add class to parent
  • , and enclosing
  • if in dropdown 40 | if (pos >= 0) { 41 | var menu_anchor = $(links[pos]); 42 | menu_anchor.parent().addClass("active"); 43 | menu_anchor.closest("li.dropdown").addClass("active"); 44 | } 45 | }); 46 | 47 | function paths(pathname) { 48 | var pieces = pathname.split("/"); 49 | pieces.shift(); // always starts with / 50 | 51 | var end = pieces[pieces.length - 1]; 52 | if (end === "index.html" || end === "") 53 | pieces.pop(); 54 | return(pieces); 55 | } 56 | 57 | // Returns -1 if not found 58 | function prefix_length(needle, haystack) { 59 | if (needle.length > haystack.length) 60 | return(-1); 61 | 62 | // Special case for length-0 haystack, since for loop won't run 63 | if (haystack.length === 0) { 64 | return(needle.length === 0 ? 0 : -1); 65 | } 66 | 67 | for (var i = 0; i < haystack.length; i++) { 68 | if (needle[i] != haystack[i]) 69 | return(i); 70 | } 71 | 72 | return(haystack.length); 73 | } 74 | 75 | /* Clipboard --------------------------*/ 76 | 77 | function changeTooltipMessage(element, msg) { 78 | var tooltipOriginalTitle=element.getAttribute('data-original-title'); 79 | element.setAttribute('data-original-title', msg); 80 | $(element).tooltip('show'); 81 | element.setAttribute('data-original-title', tooltipOriginalTitle); 82 | } 83 | 84 | if(ClipboardJS.isSupported()) { 85 | $(document).ready(function() { 86 | var copyButton = ""; 87 | 88 | $(".examples, div.sourceCode").addClass("hasCopyButton"); 89 | 90 | // Insert copy buttons: 91 | $(copyButton).prependTo(".hasCopyButton"); 92 | 93 | // Initialize tooltips: 94 | $('.btn-copy-ex').tooltip({container: 'body'}); 95 | 96 | // Initialize clipboard: 97 | var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { 98 | text: function(trigger) { 99 | return trigger.parentNode.textContent; 100 | } 101 | }); 102 | 103 | clipboardBtnCopies.on('success', function(e) { 104 | changeTooltipMessage(e.trigger, 'Copied!'); 105 | e.clearSelection(); 106 | }); 107 | 108 | clipboardBtnCopies.on('error', function() { 109 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 110 | }); 111 | }); 112 | } 113 | })(window.jQuery || window.$) 114 | -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: 2.7.3 2 | pkgdown: 1.4.1 3 | pkgdown_sha: ~ 4 | articles: 5 | closerlook: closerlook.html 6 | jspsychr: jspsychr.html 7 | recognition: recognition.html 8 | urls: 9 | reference: https://crumplab.github.io/jspsychr/reference 10 | article: https://crumplab.github.io/jspsychr/articles 11 | 12 | -------------------------------------------------------------------------------- /docs/reference/figures/expo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/docs/reference/figures/expo.png -------------------------------------------------------------------------------- /docs/reference/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/docs/reference/figures/logo.png -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | https://crumplab.github.io/jspsychr/index.html 5 | 6 | 7 | https://crumplab.github.io/jspsychr/reference/html_stimulus.html 8 | 9 | 10 | https://crumplab.github.io/jspsychr/reference/pipe.html 11 | 12 | 13 | https://crumplab.github.io/jspsychr/reference/resource.html 14 | 15 | 16 | https://crumplab.github.io/jspsychr/reference/run_locally.html 17 | 18 | 19 | https://crumplab.github.io/jspsychr/reference/stimulus_df_to_json.html 20 | 21 | 22 | https://crumplab.github.io/jspsychr/reference/unquote.html 23 | 24 | 25 | https://crumplab.github.io/jspsychr/reference/write_to_script.html 26 | 27 | 28 | https://crumplab.github.io/jspsychr/articles/closerlook.html 29 | 30 | 31 | https://crumplab.github.io/jspsychr/articles/jspsychr.html 32 | 33 | 34 | https://crumplab.github.io/jspsychr/articles/recognition.html 35 | 36 | 37 | -------------------------------------------------------------------------------- /inst/rmarkdown/basic_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $for(author-meta)$ 8 | 9 | $endfor$ 10 | $if(date-meta)$ 11 | 12 | $endif$ 13 | $if(description-meta)$ 14 | 15 | $endif$ 16 | $if(title-prefix)$$title-prefix$ – $endif$$pagetitle$ 17 | $for(css)$ 18 | 19 | $endfor$ 20 | $for(header-includes)$ 21 | $header-includes$ 22 | $endfor$ 23 | 24 | 25 | $for(include-before)$ 26 | $include-before$ 27 | $endfor$ 28 | $body$ 29 | $for(include-after)$ 30 | $include-after$ 31 | $endfor$ 32 | 33 | 34 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/index.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Experiment Name" 3 | author: "Your Name" 4 | output: 5 | html_document: 6 | mathjax: null 7 | highlight: null 8 | theme: null 9 | css: jspsych-6-2/css/jspsych.css 10 | --- 11 | 12 | 13 | ```{r setup, include=FALSE} 14 | knitr::opts_chunk$set(echo = FALSE, message=FALSE, warning=FALSE) 15 | # load the plugin scripts in plugins.html which is included in the header. 16 | ``` 17 | 18 | ```{r} 19 | # load jspsych and plugin scripts 20 | # note: this is an r code chunk 21 | library(htmltools) 22 | tagList( 23 | tags$script(src='jspsych-6-2/jspsych.js'), 24 | tags$script(src='jspsych-6-2/plugins/jspsych-html-keyboard-response.js'), 25 | tags$script(src='jspsychr/jspsychr.js') 26 | ) 27 | ``` 28 | 29 | ```{r, results="asis"} 30 | # Define stimuli in R, output as script 31 | # note: this is an r code chunk, with results = "asis" 32 | library(jspsychr) 33 | library(dplyr) 34 | # create dataframe to define stimuli 35 | stroop_stim <- data.frame( stimulus = length(16), 36 | word = rep(c("red","green","blue","yellow"), each=4), 37 | color = rep(c("red","green","blue","yellow"), 4), 38 | response = rep(c("r","g","b","y"), 4), 39 | stim_type = length(16), 40 | id = "stroop_stim", 41 | fontsize = "60pt") %>% 42 | mutate(stim_type = as.numeric(word==color)) %>% 43 | mutate(stim_type = recode(stim_type, `1` = "congruent", `0` = "incongruent")) 44 | 45 | # write html definitions to the stimulus column 46 | # note this could be added as a pipe to the above, setting df=. 47 | stroop_stim$stimulus <- html_stimulus(df = stroop_stim, 48 | html_content = "word", 49 | html_element = "p", 50 | column_names = c("color","fontsize"), 51 | css = c("color", "font-size"), 52 | id = "id") 53 | 54 | # create json object from dataframe 55 | stimulus_json <- stimulus_df_to_json(df = stroop_stim, 56 | stimulus = "stimulus", 57 | data = c("word","color","response","stim_type")) 58 | 59 | # write json object to script 60 | write_to_script(stimulus_json,"test_stimuli") 61 | ``` 62 | 63 | 64 | ```{js} 65 | /* Note this is a js (javascript) code chunk 66 | 67 | /* experiment parameters */ 68 | var reps_per_trial_type = 1; 69 | 70 | /*set up welcome block*/ 71 | var welcome = { 72 | type: "html-keyboard-response", 73 | stimulus: "Welcome to the experiment. Press any key to begin." 74 | }; 75 | 76 | /*set up instructions block*/ 77 | var instructions = { 78 | type: "html-keyboard-response", 79 | stimulus: "

    In this task, you will see word in a color

    "+ 80 | "

    BLUE

    "+ 81 | "

    Press r, g, b, or y to identify the color, not the word

    "+ 82 | "

    E.g., press r for red in this example

    "+ 83 | "

    Press any key to begin.

    ", 84 | post_trial_gap: 1000 85 | }; 86 | 87 | /* defining test timeline */ 88 | var test = { 89 | timeline: [{ 90 | type: 'html-keyboard-response', 91 | choices: ["r","g","b","y"], 92 | trial_duration: 2000, 93 | response_ends_trial: true, 94 | stimulus: jsPsych.timelineVariable('stimulus'), 95 | data: jsPsych.timelineVariable('data'), 96 | on_finish: function(data){ 97 | var correct = false; 98 | if(data.response == 'r' && data.key_press == 82 && data.rt > -1){ 99 | correct = true; 100 | } else if(data.response == 'g' && data.key_press == 71 && data.rt > -1){ 101 | correct = true; 102 | } else if(data.response == 'b' && data.key_press == 66 && data.rt > -1){ 103 | correct = true; 104 | } else if(data.response == 'y' && data.key_press == 89 && data.rt > -1){ 105 | correct = true; 106 | } 107 | data.correct = correct; 108 | }, 109 | post_trial_gap: function() { 110 | return Math.floor(Math.random() * 1500) + 500; 111 | } 112 | }], 113 | timeline_variables: test_stimuli, 114 | sample: {type: 'fixed-repetitions', size: reps_per_trial_type} 115 | }; 116 | 117 | /*defining debriefing block*/ 118 | var debrief = { 119 | type: "html-keyboard-response", 120 | stimulus: function() { 121 | var congruent_rt = Math.round(jsPsych.data.get().filter({correct: true, stim_type: 'congruent'}).select('rt').mean()); 122 | var incongruent_rt = Math.round(jsPsych.data.get().filter({correct: true, stim_type: 'incongruent'}).select('rt').mean()); 123 | return "

    Your average response time for congruent trials was " + congruent_rt + "ms.

    "+ 124 | "

    Your average response time for incongruent trials was " + incongruent_rt + "ms.

    "+ 125 | "

    Press any key to complete the experiment. Thank you!

    "; 126 | } 127 | }; 128 | 129 | /*set up experiment structure*/ 130 | var timeline = []; 131 | timeline.push(welcome); 132 | timeline.push(instructions); 133 | timeline.push(test); 134 | timeline.push(debrief); 135 | 136 | /*start experiment*/ 137 | jsPsych.init({ 138 | timeline: timeline, 139 | on_finish: function() { 140 | jsPsych.data.displayData(); 141 | } 142 | }); 143 | ``` 144 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | $title$ 4 | 5 | 6 | 7 | $body$ 8 | 9 | 10 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/css/jspsych.css: -------------------------------------------------------------------------------- 1 | /* 2 | * CSS for jsPsych experiments. 3 | * 4 | * This stylesheet provides minimal styling to make jsPsych 5 | * experiments look polished without any additional styles. 6 | */ 7 | 8 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700); 9 | 10 | /* Container holding jsPsych content */ 11 | 12 | .jspsych-display-element { 13 | display: flex; 14 | flex-direction: column; 15 | overflow-y: auto; 16 | } 17 | 18 | .jspsych-display-element:focus { 19 | outline: none; 20 | } 21 | 22 | .jspsych-content-wrapper { 23 | display: flex; 24 | margin: auto; 25 | flex: 1 1 100%; 26 | width: 100%; 27 | } 28 | 29 | .jspsych-content { 30 | max-width: 95%; /* this is mainly an IE 10-11 fix */ 31 | text-align: center; 32 | margin: auto; /* this is for overflowing content */ 33 | } 34 | 35 | .jspsych-top { 36 | align-items: flex-start; 37 | } 38 | 39 | .jspsych-middle { 40 | align-items: center; 41 | } 42 | 43 | /* fonts and type */ 44 | 45 | .jspsych-display-element { 46 | font-family: 'Open Sans', 'Arial', sans-serif; 47 | font-size: 18px; 48 | line-height: 1.6em; 49 | } 50 | 51 | /* Form elements like input fields and buttons */ 52 | 53 | .jspsych-display-element input[type="text"] { 54 | font-family: 'Open Sans', 'Arial', sans-serif; 55 | font-size: 14px; 56 | } 57 | 58 | /* borrowing Bootstrap style for btn elements, but combining styles a bit */ 59 | .jspsych-btn { 60 | display: inline-block; 61 | padding: 6px 12px; 62 | margin: 0px; 63 | font-size: 14px; 64 | font-weight: 400; 65 | font-family: 'Open Sans', 'Arial', sans-serif; 66 | cursor: pointer; 67 | line-height: 1.4; 68 | text-align: center; 69 | white-space: nowrap; 70 | vertical-align: middle; 71 | background-image: none; 72 | border: 1px solid transparent; 73 | border-radius: 4px; 74 | color: #333; 75 | background-color: #fff; 76 | border-color: #ccc; 77 | } 78 | 79 | .jspsych-btn:hover { 80 | background-color: #ddd; 81 | border-color: #aaa; 82 | } 83 | 84 | .jspsych-btn:disabled { 85 | background-color: #eee; 86 | color: #aaa; 87 | border-color: #ccc; 88 | cursor: not-allowed; 89 | } 90 | 91 | /* jsPsych progress bar */ 92 | 93 | #jspsych-progressbar-container { 94 | color: #555; 95 | border-bottom: 1px solid #dedede; 96 | background-color: #f9f9f9; 97 | margin-bottom: 1em; 98 | text-align: center; 99 | padding: 8px 0px; 100 | width: 100%; 101 | line-height: 1em; 102 | } 103 | #jspsych-progressbar-container span { 104 | font-size: 14px; 105 | padding-right: 14px; 106 | } 107 | #jspsych-progressbar-outer { 108 | background-color: #eee; 109 | width: 50%; 110 | margin: auto; 111 | height: 14px; 112 | display: inline-block; 113 | vertical-align: middle; 114 | box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); 115 | } 116 | #jspsych-progressbar-inner { 117 | background-color: #aaa; 118 | width: 0%; 119 | height: 100%; 120 | } 121 | 122 | /* Control appearance of jsPsych.data.displayData() */ 123 | #jspsych-data-display { 124 | text-align: left; 125 | } 126 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/add-to-end-of-timeline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 32 | 33 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/conditional-and-loop-functions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 63 | 64 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/data-add-properties.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/data-as-function.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/data-from-timeline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/data-from-url.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |

    The URL variable should be logged to the console

    9 | 10 | 21 | 22 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/demo-flanker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Flanker Task 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 108 | 109 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/demo-simple-rt-task.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | My experiment 5 | 6 | 7 | 8 | 9 | 10 | 11 | 104 | 105 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/demos/demo_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 29 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/demos/demo_2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 43 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/demos/demo_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 58 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/display-element-to-embed-experiment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 |
    21 |

    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla.

    22 | 23 |

    Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur sodales ligula in libero. Sed dignissim lacinia nunc. Curabitur tortor. Pellentesque nibh. Aenean quam. In scelerisque sem at dolor. Maecenas mattis. Sed convallis tristique sem. Proin ut ligula vel nunc egestas porttitor. Morbi lectus risus, iaculis vel, suscipit quis, luctus non, massa.

    24 | 25 |

    Fusce ac turpis quis ligula lacinia aliquet. Mauris ipsum. Nulla metus metus, ullamcorper vel, tincidunt sed, euismod in, nibh. Quisque volutpat condimentum velit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nam nec ante. Sed lacinia, urna non tincidunt mattis, tortor neque adipiscing diam, a cursus ipsum ante quis turpis. Nulla facilisi. Ut fringilla. Suspendisse potenti. Nunc feugiat mi a tellus consequat imperdiet. Vestibulum sapien. Proin quam. Etiam ultrices.

    26 | 27 |

    Suspendisse in justo eu magna luctus suscipit. Sed lectus. Integer euismod lacus luctus magna. Quisque cursus, metus vitae pharetra auctor, sem massa mattis sem, at interdum magna augue eget diam. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum. Morbi in ipsum sit amet pede facilisis laoreet. Donec lacus nunc, viverra nec, blandit vel, egestas et, augue. Vestibulum tincidunt malesuada tellus.

    28 | 29 |

    Ut ultrices ultrices enim. Curabitur sit amet mauris. Morbi in dui quis est pulvinar ullamcorper. Nulla facilisi. Integer lacinia sollicitudin massa. Cras metus. Sed aliquet risus a tortor. Integer id quam. Morbi mi. Quisque nisl felis, venenatis tristique, dignissim in, ultrices sit amet, augue. Proin sodales libero eget ante. Nulla quam.

    30 | 31 | 32 | 33 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/end-active-node.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/end-experiment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/exclusions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/external_html/simple_consent.html: -------------------------------------------------------------------------------- 1 |

    This is a demo consent form. Click the checkbox below to indicate the you 2 | would like to participate in the experiment

    3 |

    I agree to take part in this study.

    4 | 5 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/1.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/10.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/11.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/12.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/2.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/3.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/4.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/5.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/6.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/7.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/8.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/9.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/of1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/of1.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/of2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/of2.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/of3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/of3.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/om1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/om1.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/om2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/om2.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/om3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/om3.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/yf1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/yf1.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/yf4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/yf4.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/yf5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/yf5.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/ym2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/ym2.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/ym3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/ym3.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/ym5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/age/ym5.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/backwardN.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/backwardN.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/blue.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/con1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/con1.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/con2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/con2.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/fixation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/fixation.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_1.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_2.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_3.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/happy_face_4.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/inc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/inc1.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/inc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/inc2.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/normalN.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/normalN.gif -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/orange.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/redX.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/redX.png -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/ribbon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/ribbon.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_1.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_2.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_3.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/img/sad_face_4.jpg -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-animation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-audio-button-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 45 | 46 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-audio-keyboard-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-audio-slider-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-call-function.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 32 | 33 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-categorize-animation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-categorize-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-categorize-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-cloze.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 41 | 42 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-free-sort.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 24 | 25 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-fullscreen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-html-button-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 46 | 47 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-html-keyboard-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-html-slider-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-image-button-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 48 | 49 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-image-keyboard-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-image-slider-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-instructions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 26 | 27 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-rdk.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 58 | 59 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-reconstruction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 43 | 44 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-resize.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 34 | 35 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-same-different-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-same-different-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-serial-reaction-time-mouse.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-serial-reaction-time.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-survey-html-form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-survey-likert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 42 | 43 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-survey-multi-choice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 40 | 41 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-survey-multi-select.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 42 | 43 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-survey-text.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 34 | 35 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-video-button-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 46 | 47 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-video-keyboard-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 43 | 44 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-video-slider-response.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 48 | 49 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-visual-search-circle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-vsl-animate-occlusion.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/jspsych-vsl-grid-scene.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 41 | 42 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/manual-preloading.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 14 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/pause-unpause.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 33 | 34 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/progress-bar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/hammer.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/hammer.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/sound.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/sound.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_blue.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_blue.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_green.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_green.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_joke.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_joke.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_red.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/speech_red.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/tone.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/sound/tone.mp3 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/timeline-variables-sampling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/timeline-variables.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/video/sample_video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/examples/video/sample_video.mp4 -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/license.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2018 Joshua R. de Leeuw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-animation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jsPsych plugin for showing animations and recording keyboard responses 3 | * Josh de Leeuw 4 | * 5 | * documentation: docs.jspsych.org 6 | */ 7 | 8 | jsPsych.plugins.animation = (function() { 9 | 10 | var plugin = {}; 11 | 12 | jsPsych.pluginAPI.registerPreload('animation', 'stimuli', 'image'); 13 | 14 | plugin.info = { 15 | name: 'animation', 16 | description: '', 17 | parameters: { 18 | stimuli: { 19 | type: jsPsych.plugins.parameterType.STRING, 20 | pretty_name: 'Stimuli', 21 | default: undefined, 22 | array: true, 23 | description: 'The images to be displayed.' 24 | }, 25 | frame_time: { 26 | type: jsPsych.plugins.parameterType.INT, 27 | pretty_name: 'Frame time', 28 | default: 250, 29 | description: 'Duration to display each image.' 30 | }, 31 | frame_isi: { 32 | type: jsPsych.plugins.parameterType.INT, 33 | pretty_name: 'Frame gap', 34 | default: 0, 35 | description: 'Length of gap to be shown between each image.' 36 | }, 37 | sequence_reps: { 38 | type: jsPsych.plugins.parameterType.INT, 39 | pretty_name: 'Sequence repetitions', 40 | default: 1, 41 | description: 'Number of times to show entire sequence.' 42 | }, 43 | choices: { 44 | type: jsPsych.plugins.parameterType.KEYCODE, 45 | pretty_name: 'Choices', 46 | default: jsPsych.ALL_KEYS, 47 | array: true, 48 | description: 'Keys subject uses to respond to stimuli.' 49 | }, 50 | prompt: { 51 | type: jsPsych.plugins.parameterType.STRING, 52 | pretty_name: 'Prompt', 53 | default: null, 54 | description: 'Any content here will be displayed below stimulus.' 55 | } 56 | } 57 | } 58 | 59 | plugin.trial = function(display_element, trial) { 60 | 61 | var interval_time = trial.frame_time + trial.frame_isi; 62 | var animate_frame = -1; 63 | var reps = 0; 64 | var startTime = performance.now(); 65 | var animation_sequence = []; 66 | var responses = []; 67 | var current_stim = ""; 68 | 69 | var animate_interval = setInterval(function() { 70 | var showImage = true; 71 | display_element.innerHTML = ''; // clear everything 72 | animate_frame++; 73 | if (animate_frame == trial.stimuli.length) { 74 | animate_frame = 0; 75 | reps++; 76 | if (reps >= trial.sequence_reps) { 77 | endTrial(); 78 | clearInterval(animate_interval); 79 | showImage = false; 80 | } 81 | } 82 | if (showImage) { 83 | show_next_frame(); 84 | } 85 | }, interval_time); 86 | 87 | function show_next_frame() { 88 | // show image 89 | display_element.innerHTML = ''; 90 | 91 | current_stim = trial.stimuli[animate_frame]; 92 | 93 | // record when image was shown 94 | animation_sequence.push({ 95 | "stimulus": trial.stimuli[animate_frame], 96 | "time": performance.now() - startTime 97 | }); 98 | 99 | if (trial.prompt !== null) { 100 | display_element.innerHTML += trial.prompt; 101 | } 102 | 103 | if (trial.frame_isi > 0) { 104 | jsPsych.pluginAPI.setTimeout(function() { 105 | display_element.querySelector('#jspsych-animation-image').style.visibility = 'hidden'; 106 | current_stim = 'blank'; 107 | // record when blank image was shown 108 | animation_sequence.push({ 109 | "stimulus": 'blank', 110 | "time": performance.now() - startTime 111 | }); 112 | }, trial.frame_time); 113 | } 114 | } 115 | 116 | var after_response = function(info) { 117 | 118 | responses.push({ 119 | key_press: info.key, 120 | rt: info.rt, 121 | stimulus: current_stim 122 | }); 123 | 124 | // after a valid response, the stimulus will have the CSS class 'responded' 125 | // which can be used to provide visual feedback that a response was recorded 126 | display_element.querySelector('#jspsych-animation-image').className += ' responded'; 127 | } 128 | 129 | // hold the jspsych response listener object in memory 130 | // so that we can turn off the response collection when 131 | // the trial ends 132 | var response_listener = jsPsych.pluginAPI.getKeyboardResponse({ 133 | callback_function: after_response, 134 | valid_responses: trial.choices, 135 | rt_method: 'performance', 136 | persist: true, 137 | allow_held_key: false 138 | }); 139 | 140 | function endTrial() { 141 | 142 | jsPsych.pluginAPI.cancelKeyboardResponse(response_listener); 143 | 144 | var trial_data = { 145 | "animation_sequence": JSON.stringify(animation_sequence), 146 | "responses": JSON.stringify(responses) 147 | }; 148 | 149 | jsPsych.finishTrial(trial_data); 150 | } 151 | }; 152 | 153 | return plugin; 154 | })(); 155 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-audio-keyboard-response.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-audio-keyboard-response 3 | * Josh de Leeuw 4 | * 5 | * plugin for playing an audio file and getting a keyboard response 6 | * 7 | * documentation: docs.jspsych.org 8 | * 9 | **/ 10 | 11 | jsPsych.plugins["audio-keyboard-response"] = (function() { 12 | 13 | var plugin = {}; 14 | 15 | jsPsych.pluginAPI.registerPreload('audio-keyboard-response', 'stimulus', 'audio'); 16 | 17 | plugin.info = { 18 | name: 'audio-keyboard-response', 19 | description: '', 20 | parameters: { 21 | stimulus: { 22 | type: jsPsych.plugins.parameterType.AUDIO, 23 | pretty_name: 'Stimulus', 24 | default: undefined, 25 | description: 'The audio to be played.' 26 | }, 27 | choices: { 28 | type: jsPsych.plugins.parameterType.KEYCODE, 29 | pretty_name: 'Choices', 30 | array: true, 31 | default: jsPsych.ALL_KEYS, 32 | description: 'The keys the subject is allowed to press to respond to the stimulus.' 33 | }, 34 | prompt: { 35 | type: jsPsych.plugins.parameterType.STRING, 36 | pretty_name: 'Prompt', 37 | default: null, 38 | description: 'Any content here will be displayed below the stimulus.' 39 | }, 40 | trial_duration: { 41 | type: jsPsych.plugins.parameterType.INT, 42 | pretty_name: 'Trial duration', 43 | default: null, 44 | description: 'The maximum duration to wait for a response.' 45 | }, 46 | response_ends_trial: { 47 | type: jsPsych.plugins.parameterType.BOOL, 48 | pretty_name: 'Response ends trial', 49 | default: true, 50 | description: 'If true, the trial will end when user makes a response.' 51 | }, 52 | trial_ends_after_audio: { 53 | type: jsPsych.plugins.parameterType.BOOL, 54 | pretty_name: 'Trial ends after audio', 55 | default: false, 56 | description: 'If true, then the trial will end as soon as the audio file finishes playing.' 57 | }, 58 | } 59 | } 60 | 61 | plugin.trial = function(display_element, trial) { 62 | 63 | // setup stimulus 64 | var context = jsPsych.pluginAPI.audioContext(); 65 | if(context !== null){ 66 | var source = context.createBufferSource(); 67 | source.buffer = jsPsych.pluginAPI.getAudioBuffer(trial.stimulus); 68 | source.connect(context.destination); 69 | } else { 70 | var audio = jsPsych.pluginAPI.getAudioBuffer(trial.stimulus); 71 | audio.currentTime = 0; 72 | } 73 | 74 | // set up end event if trial needs it 75 | 76 | if(trial.trial_ends_after_audio){ 77 | if(context !== null){ 78 | source.onended = function() { 79 | end_trial(); 80 | } 81 | } else { 82 | audio.addEventListener('ended', end_trial); 83 | } 84 | } 85 | 86 | // show prompt if there is one 87 | if (trial.prompt !== null) { 88 | display_element.innerHTML = trial.prompt; 89 | } 90 | 91 | // store response 92 | var response = { 93 | rt: null, 94 | key: null 95 | }; 96 | 97 | // function to end trial when it is time 98 | function end_trial() { 99 | 100 | // kill any remaining setTimeout handlers 101 | jsPsych.pluginAPI.clearAllTimeouts(); 102 | 103 | // stop the audio file if it is playing 104 | // remove end event listeners if they exist 105 | if(context !== null){ 106 | source.stop(); 107 | source.onended = function() { } 108 | } else { 109 | audio.pause(); 110 | audio.removeEventListener('ended', end_trial); 111 | } 112 | 113 | // kill keyboard listeners 114 | jsPsych.pluginAPI.cancelAllKeyboardResponses(); 115 | 116 | // gather the data to store for the trial 117 | if(context !== null && response.rt !== null){ 118 | response.rt = Math.round(response.rt * 1000); 119 | } 120 | var trial_data = { 121 | "rt": response.rt, 122 | "stimulus": trial.stimulus, 123 | "key_press": response.key 124 | }; 125 | 126 | // clear the display 127 | display_element.innerHTML = ''; 128 | 129 | // move on to the next trial 130 | jsPsych.finishTrial(trial_data); 131 | }; 132 | 133 | // function to handle responses by the subject 134 | var after_response = function(info) { 135 | 136 | // only record the first response 137 | if (response.key == null) { 138 | response = info; 139 | } 140 | 141 | if (trial.response_ends_trial) { 142 | end_trial(); 143 | } 144 | }; 145 | 146 | // start audio 147 | if(context !== null){ 148 | startTime = context.currentTime; 149 | source.start(startTime); 150 | } else { 151 | audio.play(); 152 | } 153 | 154 | // start the response listener 155 | if(context !== null) { 156 | var keyboardListener = jsPsych.pluginAPI.getKeyboardResponse({ 157 | callback_function: after_response, 158 | valid_responses: trial.choices, 159 | rt_method: 'audio', 160 | persist: false, 161 | allow_held_key: false, 162 | audio_context: context, 163 | audio_context_start_time: startTime 164 | }); 165 | } else { 166 | var keyboardListener = jsPsych.pluginAPI.getKeyboardResponse({ 167 | callback_function: after_response, 168 | valid_responses: trial.choices, 169 | rt_method: 'performance', 170 | persist: false, 171 | allow_held_key: false 172 | }); 173 | } 174 | 175 | // end trial if time limit is set 176 | if (trial.trial_duration !== null) { 177 | jsPsych.pluginAPI.setTimeout(function() { 178 | end_trial(); 179 | }, trial.trial_duration); 180 | } 181 | 182 | }; 183 | 184 | return plugin; 185 | })(); 186 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-call-function.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-call-function 3 | * plugin for calling an arbitrary function during a jspsych experiment 4 | * Josh de Leeuw 5 | * 6 | * documentation: docs.jspsych.org 7 | * 8 | **/ 9 | 10 | jsPsych.plugins['call-function'] = (function() { 11 | 12 | var plugin = {}; 13 | 14 | plugin.info = { 15 | name: 'call-function', 16 | description: '', 17 | parameters: { 18 | func: { 19 | type: jsPsych.plugins.parameterType.FUNCTION, 20 | pretty_name: 'Function', 21 | default: undefined, 22 | description: 'Function to call' 23 | }, 24 | async: { 25 | type: jsPsych.plugins.parameterType.BOOL, 26 | pretty_name: 'Asynchronous', 27 | default: false, 28 | description: 'Is the function call asynchronous?' 29 | } 30 | } 31 | } 32 | 33 | plugin.trial = function(display_element, trial) { 34 | trial.post_trial_gap = 0; 35 | var return_val; 36 | 37 | if(trial.async){ 38 | var done = function(data){ 39 | return_val = data; 40 | end_trial(); 41 | } 42 | trial.func(done); 43 | } else { 44 | return_val = trial.func(); 45 | end_trial(); 46 | } 47 | 48 | function end_trial(){ 49 | var trial_data = { 50 | value: return_val 51 | }; 52 | 53 | jsPsych.finishTrial(trial_data); 54 | } 55 | }; 56 | 57 | return plugin; 58 | })(); 59 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-cloze.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-cloze 3 | * Philipp Sprengholz 4 | * 5 | * Plugin for displaying a cloze test and checking participants answers against a correct solution. 6 | * 7 | * documentation: docs.jspsych.org 8 | **/ 9 | 10 | jsPsych.plugins['cloze'] = (function () { 11 | 12 | var plugin = {}; 13 | 14 | plugin.info = { 15 | name: 'cloze', 16 | description: '', 17 | parameters: { 18 | text: { 19 | type: jsPsych.plugins.parameterType.STRING, 20 | pretty_name: 'Cloze text', 21 | default: undefined, 22 | description: 'The cloze text to be displayed. Blanks are indicated by %% signs and automatically replaced by input fields. If there is a correct answer you want the system to check against, it must be typed between the two percentage signs (i.e. %solution%).' 23 | }, 24 | button_text: { 25 | type: jsPsych.plugins.parameterType.STRING, 26 | pretty_name: 'Button text', 27 | default: 'OK', 28 | description: 'Text of the button participants have to press for finishing the cloze test.' 29 | }, 30 | check_answers: { 31 | type: jsPsych.plugins.parameterType.BOOL, 32 | pretty_name: 'Check answers', 33 | default: false, 34 | description: 'Boolean value indicating if the answers given by participants should be compared against a correct solution given in the text (between % signs) after the button was clicked.' 35 | }, 36 | mistake_fn: { 37 | type: jsPsych.plugins.parameterType.FUNCTION, 38 | pretty_name: 'Mistake function', 39 | default: function () {}, 40 | description: 'Function called if check_answers is set to TRUE and there is a difference between the participants answers and the correct solution provided in the text.' 41 | } 42 | } 43 | }; 44 | 45 | plugin.trial = function (display_element, trial) { 46 | 47 | var html = '
    '; 48 | var elements = trial.text.split('%'); 49 | var solutions = []; 50 | 51 | for (i=0; i'; 61 | } 62 | } 63 | html += '
    '; 64 | 65 | display_element.innerHTML = html; 66 | 67 | var check = function() { 68 | 69 | var answers = []; 70 | var answers_correct = true; 71 | 72 | for (i=0; i'; 108 | display_element.querySelector('#finish_cloze_button').addEventListener('click', check); 109 | }; 110 | 111 | return plugin; 112 | })(); -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-external-html.js: -------------------------------------------------------------------------------- 1 | /** (July 2012, Erik Weitnauer) 2 | The html-plugin will load and display an external html pages. To proceed to the next, the 3 | user might either press a button on the page or a specific key. Afterwards, the page get hidden and 4 | the plugin will wait of a specified time before it proceeds. 5 | 6 | documentation: docs.jspsych.org 7 | */ 8 | 9 | jsPsych.plugins['external-html'] = (function() { 10 | 11 | var plugin = {}; 12 | 13 | plugin.info = { 14 | name: 'external-html', 15 | description: '', 16 | parameters: { 17 | url: { 18 | type: jsPsych.plugins.parameterType.STRING, 19 | pretty_name: 'URL', 20 | default: undefined, 21 | description: 'The url of the external html page' 22 | }, 23 | cont_key: { 24 | type: jsPsych.plugins.parameterType.KEYCODE, 25 | pretty_name: 'Continue key', 26 | default: null, 27 | description: 'The key to continue to the next page.' 28 | }, 29 | cont_btn: { 30 | type: jsPsych.plugins.parameterType.STRING, 31 | pretty_name: 'Continue button', 32 | default: null, 33 | description: 'The button to continue to the next page.' 34 | }, 35 | check_fn: { 36 | type: jsPsych.plugins.parameterType.FUNCTION, 37 | pretty_name: 'Check function', 38 | default: function() { return true; }, 39 | description: '' 40 | }, 41 | force_refresh: { 42 | type: jsPsych.plugins.parameterType.BOOL, 43 | pretty_name: 'Force refresh', 44 | default: false, 45 | description: 'Refresh page.' 46 | }, 47 | // if execute_Script == true, then all javascript code on the external page 48 | // will be executed in the plugin site within your jsPsych test 49 | execute_script: { 50 | type: jsPsych.plugins.parameterType.BOOL, 51 | pretty_name: 'Execute scripts', 52 | default: false, 53 | description: 'If true, JS scripts on the external html file will be executed.' 54 | } 55 | } 56 | } 57 | 58 | plugin.trial = function(display_element, trial) { 59 | 60 | var url = trial.url; 61 | if (trial.force_refresh) { 62 | url = trial.url + "?t=" + performance.now(); 63 | } 64 | 65 | load(display_element, url, function() { 66 | var t0 = performance.now(); 67 | var finish = function() { 68 | if (trial.check_fn && !trial.check_fn(display_element)) { return }; 69 | if (trial.cont_key) { display_element.removeEventListener('keydown', key_listener); } 70 | var trial_data = { 71 | rt: performance.now() - t0, 72 | url: trial.url 73 | }; 74 | display_element.innerHTML = ''; 75 | jsPsych.finishTrial(trial_data); 76 | }; 77 | 78 | // by default, scripts on the external page are not executed with XMLHttpRequest(). 79 | // To activate their content through DOM manipulation, we need to relocate all script tags 80 | if (trial.execute_script) { 81 | for (const scriptElement of display_element.getElementsByTagName("script")) { 82 | const relocatedScript = document.createElement("script"); 83 | relocatedScript.text = scriptElement.text; 84 | scriptElement.parentNode.replaceChild(relocatedScript, scriptElement); 85 | }; 86 | } 87 | 88 | if (trial.cont_btn) { display_element.querySelector('#'+trial.cont_btn).addEventListener('click', finish); } 89 | if (trial.cont_key) { 90 | var key_listener = function(e) { 91 | if (e.which == trial.cont_key) finish(); 92 | }; 93 | display_element.addEventListener('keydown', key_listener); 94 | } 95 | }); 96 | }; 97 | 98 | // helper to load via XMLHttpRequest 99 | function load(element, file, callback){ 100 | var xmlhttp = new XMLHttpRequest(); 101 | xmlhttp.open("GET", file, true); 102 | xmlhttp.onload = function(){ 103 | if(xmlhttp.status == 200 || xmlhttp.status == 0){ //Check if loaded 104 | element.innerHTML = xmlhttp.responseText; 105 | callback(); 106 | } 107 | } 108 | xmlhttp.send(); 109 | } 110 | 111 | return plugin; 112 | })(); 113 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-fullscreen.js: -------------------------------------------------------------------------------- 1 | /* jspsych-fullscreen.js 2 | * Josh de Leeuw 3 | * 4 | * toggle fullscreen mode in the browser 5 | * 6 | */ 7 | 8 | jsPsych.plugins.fullscreen = (function() { 9 | 10 | var plugin = {}; 11 | 12 | plugin.info = { 13 | name: 'fullscreen', 14 | description: '', 15 | parameters: { 16 | fullscreen_mode: { 17 | type: jsPsych.plugins.parameterType.BOOL, 18 | pretty_name: 'Fullscreen mode', 19 | default: true, 20 | array: false, 21 | description: 'If true, experiment will enter fullscreen mode. If false, the browser will exit fullscreen mode.' 22 | }, 23 | message: { 24 | type: jsPsych.plugins.parameterType.STRING, 25 | pretty_name: 'Message', 26 | default: '

    The experiment will switch to full screen mode when you press the button below

    ', 27 | array: false, 28 | description: 'HTML content to display above the button to enter fullscreen mode.' 29 | }, 30 | button_label: { 31 | type: jsPsych.plugins.parameterType.STRING, 32 | pretty_name: 'Button label', 33 | default: 'Continue', 34 | array: false, 35 | description: 'The text that appears on the button to enter fullscreen.' 36 | }, 37 | delay_after: { 38 | type: jsPsych.plugins.parameterType.INT, 39 | pretty_name: 'Delay after', 40 | default: 1000, 41 | array: false, 42 | description: 'The length of time to delay after entering fullscreen mode before ending the trial.' 43 | }, 44 | } 45 | } 46 | 47 | plugin.trial = function(display_element, trial) { 48 | 49 | // check if keys are allowed in fullscreen mode 50 | var keyboardNotAllowed = typeof Element !== 'undefined' && 'ALLOW_KEYBOARD_INPUT' in Element; 51 | if (keyboardNotAllowed) { 52 | // This is Safari, and keyboard events will be disabled. Don't allow fullscreen here. 53 | // do something else? 54 | endTrial(); 55 | } else { 56 | if(trial.fullscreen_mode){ 57 | display_element.innerHTML = trial.message + ''; 58 | var listener = display_element.querySelector('#jspsych-fullscreen-btn').addEventListener('click', function() { 59 | var element = document.documentElement; 60 | if (element.requestFullscreen) { 61 | element.requestFullscreen(); 62 | } else if (element.mozRequestFullScreen) { 63 | element.mozRequestFullScreen(); 64 | } else if (element.webkitRequestFullscreen) { 65 | element.webkitRequestFullscreen(); 66 | } else if (element.msRequestFullscreen) { 67 | element.msRequestFullscreen(); 68 | } 69 | endTrial(); 70 | }); 71 | } else { 72 | if (document.exitFullscreen) { 73 | document.exitFullscreen(); 74 | } else if (document.msExitFullscreen) { 75 | document.msExitFullscreen(); 76 | } else if (document.mozCancelFullScreen) { 77 | document.mozCancelFullScreen(); 78 | } else if (document.webkitExitFullscreen) { 79 | document.webkitExitFullscreen(); 80 | } 81 | endTrial(); 82 | } 83 | } 84 | 85 | function endTrial() { 86 | 87 | display_element.innerHTML = ''; 88 | 89 | jsPsych.pluginAPI.setTimeout(function(){ 90 | 91 | var trial_data = { 92 | success: !keyboardNotAllowed 93 | }; 94 | 95 | jsPsych.finishTrial(trial_data); 96 | 97 | }, trial.delay_after); 98 | 99 | } 100 | 101 | }; 102 | 103 | return plugin; 104 | })(); 105 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-html-keyboard-response.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-html-keyboard-response 3 | * Josh de Leeuw 4 | * 5 | * plugin for displaying a stimulus and getting a keyboard response 6 | * 7 | * documentation: docs.jspsych.org 8 | * 9 | **/ 10 | 11 | 12 | jsPsych.plugins["html-keyboard-response"] = (function() { 13 | 14 | var plugin = {}; 15 | 16 | plugin.info = { 17 | name: 'html-keyboard-response', 18 | description: '', 19 | parameters: { 20 | stimulus: { 21 | type: jsPsych.plugins.parameterType.HTML_STRING, 22 | pretty_name: 'Stimulus', 23 | default: undefined, 24 | description: 'The HTML string to be displayed' 25 | }, 26 | choices: { 27 | type: jsPsych.plugins.parameterType.KEYCODE, 28 | array: true, 29 | pretty_name: 'Choices', 30 | default: jsPsych.ALL_KEYS, 31 | description: 'The keys the subject is allowed to press to respond to the stimulus.' 32 | }, 33 | prompt: { 34 | type: jsPsych.plugins.parameterType.STRING, 35 | pretty_name: 'Prompt', 36 | default: null, 37 | description: 'Any content here will be displayed below the stimulus.' 38 | }, 39 | stimulus_duration: { 40 | type: jsPsych.plugins.parameterType.INT, 41 | pretty_name: 'Stimulus duration', 42 | default: null, 43 | description: 'How long to hide the stimulus.' 44 | }, 45 | trial_duration: { 46 | type: jsPsych.plugins.parameterType.INT, 47 | pretty_name: 'Trial duration', 48 | default: null, 49 | description: 'How long to show trial before it ends.' 50 | }, 51 | response_ends_trial: { 52 | type: jsPsych.plugins.parameterType.BOOL, 53 | pretty_name: 'Response ends trial', 54 | default: true, 55 | description: 'If true, trial will end when subject makes a response.' 56 | }, 57 | 58 | } 59 | } 60 | 61 | plugin.trial = function(display_element, trial) { 62 | 63 | var new_html = '
    '+trial.stimulus+'
    '; 64 | 65 | // add prompt 66 | if(trial.prompt !== null){ 67 | new_html += trial.prompt; 68 | } 69 | 70 | // draw 71 | display_element.innerHTML = new_html; 72 | 73 | // store response 74 | var response = { 75 | rt: null, 76 | key: null 77 | }; 78 | 79 | // function to end trial when it is time 80 | var end_trial = function() { 81 | 82 | // kill any remaining setTimeout handlers 83 | jsPsych.pluginAPI.clearAllTimeouts(); 84 | 85 | // kill keyboard listeners 86 | if (typeof keyboardListener !== 'undefined') { 87 | jsPsych.pluginAPI.cancelKeyboardResponse(keyboardListener); 88 | } 89 | 90 | // gather the data to store for the trial 91 | var trial_data = { 92 | "rt": response.rt, 93 | "stimulus": trial.stimulus, 94 | "key_press": response.key 95 | }; 96 | 97 | // clear the display 98 | display_element.innerHTML = ''; 99 | 100 | // move on to the next trial 101 | jsPsych.finishTrial(trial_data); 102 | }; 103 | 104 | // function to handle responses by the subject 105 | var after_response = function(info) { 106 | 107 | // after a valid response, the stimulus will have the CSS class 'responded' 108 | // which can be used to provide visual feedback that a response was recorded 109 | display_element.querySelector('#jspsych-html-keyboard-response-stimulus').className += ' responded'; 110 | 111 | // only record the first response 112 | if (response.key == null) { 113 | response = info; 114 | } 115 | 116 | if (trial.response_ends_trial) { 117 | end_trial(); 118 | } 119 | }; 120 | 121 | // start the response listener 122 | if (trial.choices != jsPsych.NO_KEYS) { 123 | var keyboardListener = jsPsych.pluginAPI.getKeyboardResponse({ 124 | callback_function: after_response, 125 | valid_responses: trial.choices, 126 | rt_method: 'performance', 127 | persist: false, 128 | allow_held_key: false 129 | }); 130 | } 131 | 132 | // hide stimulus if stimulus_duration is set 133 | if (trial.stimulus_duration !== null) { 134 | jsPsych.pluginAPI.setTimeout(function() { 135 | display_element.querySelector('#jspsych-html-keyboard-response-stimulus').style.visibility = 'hidden'; 136 | }, trial.stimulus_duration); 137 | } 138 | 139 | // end trial if trial_duration is set 140 | if (trial.trial_duration !== null) { 141 | jsPsych.pluginAPI.setTimeout(function() { 142 | end_trial(); 143 | }, trial.trial_duration); 144 | } 145 | 146 | }; 147 | 148 | return plugin; 149 | })(); 150 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-reconstruction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-reconstruction 3 | * a jspsych plugin for a reconstruction task where the subject recreates 4 | * a stimulus from memory 5 | * 6 | * Josh de Leeuw 7 | * 8 | * documentation: docs.jspsych.org 9 | * 10 | */ 11 | 12 | 13 | jsPsych.plugins['reconstruction'] = (function() { 14 | 15 | var plugin = {}; 16 | 17 | plugin.info = { 18 | name: 'reconstruction', 19 | description: '', 20 | parameters: { 21 | stim_function: { 22 | type: jsPsych.plugins.parameterType.FUNCTION, 23 | pretty_name: 'Stimulus function', 24 | default: undefined, 25 | description: 'A function with a single parameter that returns an HTML-formatted string representing the stimulus.' 26 | }, 27 | starting_value: { 28 | type: jsPsych.plugins.parameterType.FLOAT, 29 | pretty_name: 'Starting value', 30 | default: 0.5, 31 | description: 'The starting value of the stimulus parameter.' 32 | }, 33 | step_size: { 34 | type: jsPsych.plugins.parameterType.FLOAT, 35 | pretty_name: 'Step size', 36 | default: 0.05, 37 | description: 'The change in the stimulus parameter caused by pressing one of the modification keys.' 38 | }, 39 | key_increase: { 40 | type: jsPsych.plugins.parameterType.KEYCODE, 41 | pretty_name: 'Key increase', 42 | default: 'h', 43 | description: 'The key to press for increasing the parameter value.' 44 | }, 45 | key_decrease: { 46 | type: jsPsych.plugins.parameterType.KEYCODE, 47 | pretty_name: 'Key decrease', 48 | default: 'g', 49 | description: 'The key to press for decreasing the parameter value.' 50 | }, 51 | button_label: { 52 | type: jsPsych.plugins.parameterType.STRING, 53 | pretty_name: 'Button label', 54 | default: 'Continue', 55 | description: 'The text that appears on the button to finish the trial.' 56 | } 57 | } 58 | } 59 | 60 | plugin.trial = function(display_element, trial) { 61 | 62 | // current param level 63 | var param = trial.starting_value; 64 | 65 | // set-up key listeners 66 | var after_response = function(info) { 67 | 68 | //console.log('fire'); 69 | 70 | var key_i = (typeof trial.key_increase == 'string') ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_increase) : trial.key_increase; 71 | var key_d = (typeof trial.key_decrease == 'string') ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.key_decrease) : trial.key_decrease; 72 | 73 | // get new param value 74 | if (info.key == key_i) { 75 | param = param + trial.step_size; 76 | } else if (info.key == key_d) { 77 | param = param - trial.step_size; 78 | } 79 | param = Math.max(Math.min(1, param), 0); 80 | 81 | // refresh the display 82 | draw(param); 83 | } 84 | 85 | // listen for responses 86 | var key_listener = jsPsych.pluginAPI.getKeyboardResponse({ 87 | callback_function: after_response, 88 | valid_responses: [trial.key_increase, trial.key_decrease], 89 | rt_method: 'performance', 90 | persist: true, 91 | allow_held_key: true 92 | }); 93 | // draw first iteration 94 | draw(param); 95 | 96 | function draw(param) { 97 | 98 | //console.log(param); 99 | 100 | display_element.innerHTML = '
    '+trial.stim_function(param)+'
    '; 101 | 102 | // add submit button 103 | display_element.innerHTML += ''; 104 | 105 | display_element.querySelector('#jspsych-reconstruction-next').addEventListener('click', endTrial); 106 | } 107 | 108 | function endTrial() { 109 | // measure response time 110 | var endTime =performance.now(); 111 | var response_time = endTime - startTime; 112 | 113 | // clear keyboard response 114 | jsPsych.pluginAPI.cancelKeyboardResponse(key_listener); 115 | 116 | // save data 117 | var trial_data = { 118 | "rt": response_time, 119 | "final_value": param, 120 | "start_value": trial.starting_value 121 | }; 122 | 123 | display_element.innerHTML = ''; 124 | 125 | // next trial 126 | jsPsych.finishTrial(trial_data); 127 | } 128 | 129 | var startTime = performance.now(); 130 | 131 | }; 132 | 133 | return plugin; 134 | })(); 135 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-same-different-html.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-same-different 3 | * Josh de Leeuw 4 | * 5 | * plugin for showing two stimuli sequentially and getting a same / different judgment 6 | * 7 | * documentation: docs.jspsych.org 8 | * 9 | */ 10 | 11 | jsPsych.plugins['same-different-html'] = (function() { 12 | 13 | var plugin = {}; 14 | 15 | plugin.info = { 16 | name: 'same-different-html', 17 | description: '', 18 | parameters: { 19 | stimuli: { 20 | type: jsPsych.plugins.parameterType.HTML_STRING, 21 | pretty_name: 'Stimuli', 22 | default: undefined, 23 | array: true, 24 | description: 'The HTML content to be displayed.' 25 | }, 26 | answer: { 27 | type: jsPsych.plugins.parameterType.SELECT, 28 | pretty_name: 'Answer', 29 | options: ['same', 'different'], 30 | default: 75, 31 | description: 'Either "same" or "different".' 32 | }, 33 | same_key: { 34 | type: jsPsych.plugins.parameterType.KEYCODE, 35 | pretty_name: 'Same key', 36 | default: 'Q', 37 | description: '' 38 | }, 39 | different_key: { 40 | type: jsPsych.plugins.parameterType.KEYCODE, 41 | pretty_name: 'Different key', 42 | default: 'P', 43 | description: 'The key that subjects should press to indicate that the two stimuli are the same.' 44 | }, 45 | first_stim_duration: { 46 | type: jsPsych.plugins.parameterType.INT, 47 | pretty_name: 'First stimulus duration', 48 | default: 1000, 49 | description: 'How long to show the first stimulus for in milliseconds.' 50 | }, 51 | gap_duration: { 52 | type: jsPsych.plugins.parameterType.INT, 53 | pretty_name: 'Gap duration', 54 | default: 500, 55 | description: 'How long to show a blank screen in between the two stimuli.' 56 | }, 57 | second_stim_duration: { 58 | type: jsPsych.plugins.parameterType.INT, 59 | pretty_name: 'Second stimulus duration', 60 | default: 1000, 61 | description: 'How long to show the second stimulus for in milliseconds.' 62 | }, 63 | prompt: { 64 | type: jsPsych.plugins.parameterType.STRING, 65 | pretty_name: 'Prompt', 66 | default: null, 67 | description: 'Any content here will be displayed below the stimulus.' 68 | } 69 | } 70 | } 71 | 72 | plugin.trial = function(display_element, trial) { 73 | 74 | display_element.innerHTML = '
    '+trial.stimuli[0]+'
    '; 75 | 76 | var first_stim_info; 77 | if (trial.first_stim_duration > 0) { 78 | jsPsych.pluginAPI.setTimeout(function() { 79 | showBlankScreen(); 80 | }, trial.first_stim_duration); 81 | } else { 82 | function afterKeyboardResponse(info) { 83 | first_stim_info = info; 84 | showBlankScreen(); 85 | } 86 | jsPsych.pluginAPI.getKeyboardResponse({ 87 | callback_function: afterKeyboardResponse, 88 | valid_responses: trial.advance_key, 89 | rt_method: 'performance', 90 | persist: false, 91 | allow_held_key: false 92 | }); 93 | } 94 | 95 | function showBlankScreen() { 96 | display_element.innerHTML = ''; 97 | 98 | jsPsych.pluginAPI.setTimeout(function() { 99 | showSecondStim(); 100 | }, trial.gap_duration); 101 | } 102 | 103 | function showSecondStim() { 104 | 105 | var html = '
    '+trial.stimuli[1]+'
    '; 106 | //show prompt here 107 | if (trial.prompt !== null) { 108 | html += trial.prompt; 109 | } 110 | display_element.innerHTML = html; 111 | 112 | if (trial.second_stim_duration > 0) { 113 | jsPsych.pluginAPI.setTimeout(function() { 114 | display_element.querySelector('.jspsych-same-different-stimulus').style.visibility = 'hidden'; 115 | }, trial.second_stim_duration); 116 | } 117 | 118 | 119 | 120 | var after_response = function(info) { 121 | 122 | // kill any remaining setTimeout handlers 123 | jsPsych.pluginAPI.clearAllTimeouts(); 124 | 125 | var correct = false; 126 | 127 | var skey = typeof trial.same_key == 'string' ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.same_key) : trial.same_key; 128 | var dkey = typeof trial.different_key == 'string' ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.different_key) : trial.different_key; 129 | 130 | if (info.key == skey && trial.answer == 'same') { 131 | correct = true; 132 | } 133 | 134 | if (info.key == dkey && trial.answer == 'different') { 135 | correct = true; 136 | } 137 | 138 | var trial_data = { 139 | "rt": info.rt, 140 | "answer": trial.answer, 141 | "correct": correct, 142 | "stimulus": JSON.stringify([trial.stimuli[0], trial.stimuli[1]]), 143 | "key_press": info.key 144 | }; 145 | if (first_stim_info) { 146 | trial_data["rt_stim1"] = first_stim_info.rt; 147 | trial_data["key_press_stim1"] = first_stim_info.key; 148 | } 149 | 150 | display_element.innerHTML = ''; 151 | 152 | jsPsych.finishTrial(trial_data); 153 | } 154 | 155 | jsPsych.pluginAPI.getKeyboardResponse({ 156 | callback_function: after_response, 157 | valid_responses: [trial.same_key, trial.different_key], 158 | rt_method: 'performance', 159 | persist: false, 160 | allow_held_key: false 161 | }); 162 | 163 | } 164 | 165 | }; 166 | 167 | return plugin; 168 | })(); 169 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-same-different-image.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-same-different 3 | * Josh de Leeuw 4 | * 5 | * plugin for showing two stimuli sequentially and getting a same / different judgment 6 | * 7 | * documentation: docs.jspsych.org 8 | * 9 | */ 10 | 11 | jsPsych.plugins['same-different-image'] = (function() { 12 | 13 | var plugin = {}; 14 | 15 | jsPsych.pluginAPI.registerPreload('same-different-image', 'stimuli', 'image') 16 | 17 | plugin.info = { 18 | name: 'same-different-image', 19 | description: '', 20 | parameters: { 21 | stimuli: { 22 | type: jsPsych.plugins.parameterType.IMAGE, 23 | pretty_name: 'Stimuli', 24 | default: undefined, 25 | array: true, 26 | description: 'The images to be displayed.' 27 | }, 28 | answer: { 29 | type: jsPsych.plugins.parameterType.SELECT, 30 | pretty_name: 'Answer', 31 | options: ['same', 'different'], 32 | default: 75, 33 | description: 'Either "same" or "different".' 34 | }, 35 | same_key: { 36 | type: jsPsych.plugins.parameterType.KEYCODE, 37 | pretty_name: 'Same key', 38 | default: 'Q', 39 | description: '' 40 | }, 41 | different_key: { 42 | type: jsPsych.plugins.parameterType.KEYCODE, 43 | pretty_name: 'Different key', 44 | default: 'P', 45 | description: 'The key that subjects should press to indicate that the two stimuli are the same.' 46 | }, 47 | first_stim_duration: { 48 | type: jsPsych.plugins.parameterType.INT, 49 | pretty_name: 'First stimulus duration', 50 | default: 1000, 51 | description: 'How long to show the first stimulus for in milliseconds.' 52 | }, 53 | gap_duration: { 54 | type: jsPsych.plugins.parameterType.INT, 55 | pretty_name: 'Gap duration', 56 | default: 500, 57 | description: 'How long to show a blank screen in between the two stimuli.' 58 | }, 59 | second_stim_duration: { 60 | type: jsPsych.plugins.parameterType.INT, 61 | pretty_name: 'Second stimulus duration', 62 | default: 1000, 63 | description: 'How long to show the second stimulus for in milliseconds.' 64 | }, 65 | prompt: { 66 | type: jsPsych.plugins.parameterType.STRING, 67 | pretty_name: 'Prompt', 68 | default: null, 69 | description: 'Any content here will be displayed below the stimulus.' 70 | } 71 | } 72 | } 73 | 74 | plugin.trial = function(display_element, trial) { 75 | 76 | display_element.innerHTML = ''; 77 | 78 | var first_stim_info; 79 | if (trial.first_stim_duration > 0) { 80 | jsPsych.pluginAPI.setTimeout(function() { 81 | showBlankScreen(); 82 | }, trial.first_stim_duration); 83 | } else { 84 | function afterKeyboardResponse(info) { 85 | first_stim_info = info; 86 | showBlankScreen(); 87 | } 88 | jsPsych.pluginAPI.getKeyboardResponse({ 89 | callback_function: afterKeyboardResponse, 90 | valid_responses: trial.advance_key, 91 | rt_method: 'performance', 92 | persist: false, 93 | allow_held_key: false 94 | }); 95 | } 96 | 97 | function showBlankScreen() { 98 | display_element.innerHTML = ''; 99 | 100 | jsPsych.pluginAPI.setTimeout(function() { 101 | showSecondStim(); 102 | }, trial.gap_duration); 103 | } 104 | 105 | function showSecondStim() { 106 | 107 | var html = ''; 108 | //show prompt 109 | if (trial.prompt !== null) { 110 | html += trial.prompt; 111 | } 112 | 113 | display_element.innerHTML = html; 114 | 115 | if (trial.second_stim_duration > 0) { 116 | jsPsych.pluginAPI.setTimeout(function() { 117 | display_element.querySelector('.jspsych-same-different-stimulus').style.visibility = 'hidden'; 118 | }, trial.second_stim_duration); 119 | } 120 | 121 | var after_response = function(info) { 122 | 123 | // kill any remaining setTimeout handlers 124 | jsPsych.pluginAPI.clearAllTimeouts(); 125 | 126 | var correct = false; 127 | 128 | var skey = typeof trial.same_key == 'string' ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.same_key) : trial.same_key; 129 | var dkey = typeof trial.different_key == 'string' ? jsPsych.pluginAPI.convertKeyCharacterToKeyCode(trial.different_key) : trial.different_key; 130 | 131 | if (info.key == skey && trial.answer == 'same') { 132 | correct = true; 133 | } 134 | 135 | if (info.key == dkey && trial.answer == 'different') { 136 | correct = true; 137 | } 138 | 139 | var trial_data = { 140 | "rt": info.rt, 141 | "answer": trial.answer, 142 | "correct": correct, 143 | "stimulus": JSON.stringify([trial.stimuli[0], trial.stimuli[1]]), 144 | "key_press": info.key 145 | }; 146 | if (first_stim_info) { 147 | trial_data["rt_stim1"] = first_stim_info.rt; 148 | trial_data["key_press_stim1"] = first_stim_info.key; 149 | } 150 | 151 | display_element.innerHTML = ''; 152 | 153 | jsPsych.finishTrial(trial_data); 154 | } 155 | 156 | jsPsych.pluginAPI.getKeyboardResponse({ 157 | callback_function: after_response, 158 | valid_responses: [trial.same_key, trial.different_key], 159 | rt_method: 'performance', 160 | persist: false, 161 | allow_held_key: false 162 | }); 163 | 164 | } 165 | 166 | }; 167 | 168 | return plugin; 169 | })(); 170 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-survey-html-form.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jspsych-survey-html-form 3 | * a jspsych plugin for free html forms 4 | * 5 | * Jan Simson 6 | * 7 | * documentation: docs.jspsych.org 8 | * 9 | */ 10 | 11 | jsPsych.plugins['survey-html-form'] = (function() { 12 | 13 | var plugin = {}; 14 | 15 | plugin.info = { 16 | name: 'survey-html-form', 17 | description: '', 18 | parameters: { 19 | html: { 20 | type: jsPsych.plugins.parameterType.HTML_STRING, 21 | pretty_name: 'HTML', 22 | default: null, 23 | description: 'HTML formatted string containing all the input elements to display. Every element has to have its own distinctive name attribute. The
    tag must not be included and is generated by the plugin.' 24 | }, 25 | preamble: { 26 | type: jsPsych.plugins.parameterType.STRING, 27 | pretty_name: 'Preamble', 28 | default: null, 29 | description: 'HTML formatted string to display at the top of the page above all the questions.' 30 | }, 31 | button_label: { 32 | type: jsPsych.plugins.parameterType.STRING, 33 | pretty_name: 'Button label', 34 | default: 'Continue', 35 | description: 'The text that appears on the button to finish the trial.' 36 | }, 37 | dataAsArray: { 38 | type: jsPsych.plugins.parameterType.BOOLEAN, 39 | pretty_name: 'Data As Array', 40 | default: false, 41 | description: 'Retrieve the data as an array e.g. [{name: "INPUT_NAME", value: "INPUT_VALUE"}, ...] instead of an object e.g. {INPUT_NAME: INPUT_VALUE, ...}.' 42 | } 43 | } 44 | } 45 | 46 | plugin.trial = function(display_element, trial) { 47 | 48 | var html = ''; 49 | // show preamble text 50 | if(trial.preamble !== null){ 51 | html += '
    '+trial.preamble+'
    '; 52 | } 53 | // start form 54 | html += '' 55 | 56 | // add form HTML / input elements 57 | html += trial.html; 58 | 59 | // add submit button 60 | html += ''; 61 | 62 | html += '
    ' 63 | display_element.innerHTML = html; 64 | 65 | display_element.querySelector('#jspsych-survey-html-form').addEventListener('submit', function(event) { 66 | // don't submit form 67 | event.preventDefault(); 68 | 69 | // measure response time 70 | var endTime = performance.now(); 71 | var response_time = endTime - startTime; 72 | 73 | var question_data = serializeArray(this); 74 | 75 | if (!trial.dataAsArray) { 76 | question_data = objectifyForm(question_data); 77 | } 78 | 79 | // save data 80 | var trialdata = { 81 | "rt": response_time, 82 | "responses": JSON.stringify(question_data) 83 | }; 84 | 85 | display_element.innerHTML = ''; 86 | 87 | // next trial 88 | jsPsych.finishTrial(trialdata); 89 | }); 90 | 91 | var startTime = performance.now(); 92 | }; 93 | 94 | /*! 95 | * Serialize all form data into an array 96 | * (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com 97 | * @param {Node} form The form to serialize 98 | * @return {String} The serialized form data 99 | */ 100 | var serializeArray = function (form) { 101 | // Setup our serialized data 102 | var serialized = []; 103 | 104 | // Loop through each field in the form 105 | for (var i = 0; i < form.elements.length; i++) { 106 | var field = form.elements[i]; 107 | 108 | // Don't serialize fields without a name, submits, buttons, file and reset inputs, and disabled fields 109 | if (!field.name || field.disabled || field.type === 'file' || field.type === 'reset' || field.type === 'submit' || field.type === 'button') continue; 110 | 111 | // If a multi-select, get all selections 112 | if (field.type === 'select-multiple') { 113 | for (var n = 0; n < field.options.length; n++) { 114 | if (!field.options[n].selected) continue; 115 | serialized.push({ 116 | name: field.name, 117 | value: field.options[n].value 118 | }); 119 | } 120 | } 121 | 122 | // Convert field data to a query string 123 | else if ((field.type !== 'checkbox' && field.type !== 'radio') || field.checked) { 124 | serialized.push({ 125 | name: field.name, 126 | value: field.value 127 | }); 128 | } 129 | } 130 | 131 | return serialized; 132 | }; 133 | 134 | // from https://stackoverflow.com/questions/1184624/convert-form-data-to-javascript-object-with-jquery 135 | function objectifyForm(formArray) {//serialize data function 136 | var returnArray = {}; 137 | for (var i = 0; i < formArray.length; i++){ 138 | returnArray[formArray[i]['name']] = formArray[i]['value']; 139 | } 140 | return returnArray; 141 | } 142 | 143 | return plugin; 144 | })(); 145 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/jspsych-vsl-grid-scene.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jsPsych plugin for showing scenes that mimic the experiments described in 3 | * 4 | * Fiser, J., & Aslin, R. N. (2001). Unsupervised statistical learning of 5 | * higher-order spatial structures from visual scenes. Psychological science, 6 | * 12(6), 499-504. 7 | * 8 | * Josh de Leeuw 9 | * 10 | * documentation: docs.jspsych.org 11 | * 12 | */ 13 | 14 | jsPsych.plugins['vsl-grid-scene'] = (function() { 15 | 16 | var plugin = {}; 17 | 18 | jsPsych.pluginAPI.registerPreload('vsl-grid-scene', 'stimuli', 'image'); 19 | 20 | plugin.info = { 21 | name: 'vsl-grid-scene', 22 | description: '', 23 | parameters: { 24 | stimuli: { 25 | type: jsPsych.plugins.parameterType.IMAGE, 26 | pretty_name: 'Stimuli', 27 | array: true, 28 | default: undefined, 29 | description: 'An array that defines a grid.' 30 | }, 31 | image_size: { 32 | type: jsPsych.plugins.parameterType.INT, 33 | pretty_name: 'Image size', 34 | array: true, 35 | default: [100,100], 36 | description: 'Array specifying the width and height of the images to show.' 37 | }, 38 | trial_duration: { 39 | type: jsPsych.plugins.parameterType.INT, 40 | pretty_name: 'Trial duration', 41 | default: 2000, 42 | description: 'How long to show the stimulus for in milliseconds.' 43 | } 44 | } 45 | } 46 | 47 | plugin.trial = function(display_element, trial) { 48 | 49 | display_element.innerHTML = plugin.generate_stimulus(trial.stimuli, trial.image_size); 50 | 51 | jsPsych.pluginAPI.setTimeout(function() { 52 | endTrial(); 53 | }, trial.trial_duration); 54 | 55 | function endTrial() { 56 | 57 | display_element.innerHTML = ''; 58 | 59 | var trial_data = { 60 | "stimulus": JSON.stringify(trial.stimuli) 61 | }; 62 | 63 | jsPsych.finishTrial(trial_data); 64 | } 65 | }; 66 | 67 | plugin.generate_stimulus = function(pattern, image_size) { 68 | var nrows = pattern.length; 69 | var ncols = pattern[0].length; 70 | 71 | // create blank element to hold code that we generate 72 | var html = '
    '; 73 | 74 | // create table 75 | html += ''; 77 | 78 | for (var row = 0; row < nrows; row++) { 79 | html += ''; 80 | 81 | for (var col = 0; col < ncols; col++) { 82 | html += ''; 91 | } 92 | html += ''; 93 | } 94 | 95 | html += '
    '+ 84 | '
    '; 85 | if (pattern[row][col] !== 0) { 86 | html += ''; 88 | } 89 | html += '
    '; 90 | html += '
    '; 96 | html += '
    '; 97 | 98 | return html; 99 | 100 | }; 101 | 102 | return plugin; 103 | })(); 104 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsych-6-2/plugins/template/jspsych-plugin-template.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Example plugin template 3 | */ 4 | 5 | jsPsych.plugins["PLUGIN-NAME"] = (function() { 6 | 7 | var plugin = {}; 8 | 9 | plugin.info = { 10 | name: "PLUGIN-NAME", 11 | parameters: { 12 | parameter_name: { 13 | type: jsPsych.plugins.parameterType.INT, // BOOL, STRING, INT, FLOAT, FUNCTION, KEYCODE, SELECT, HTML_STRING, IMAGE, AUDIO, VIDEO, OBJECT, COMPLEX 14 | default: undefined 15 | }, 16 | parameter_name: { 17 | type: jsPsych.plugins.parameterType.IMAGE, 18 | default: undefined 19 | } 20 | } 21 | } 22 | 23 | plugin.trial = function(display_element, trial) { 24 | 25 | // data saving 26 | var trial_data = { 27 | parameter_name: 'parameter value' 28 | }; 29 | 30 | // end trial 31 | jsPsych.finishTrial(trial_data); 32 | }; 33 | 34 | return plugin; 35 | })(); 36 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/experiment/jspsychr/jspsychr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * xprmntr.js - > jspsychr.js 3 | * Danielle Navarro 4 | * modified to not conflict with xprmntr : Matt Crump 5 | **/ 6 | 7 | var jspsychr = {}; 8 | jspsychr.save_locally = function() { 9 | var data = jsPsych.data.get().csv(); 10 | var file = "jspsychr_local_name"; 11 | var xhr = new XMLHttpRequest(); 12 | xhr.open('POST', 'submit'); 13 | xhr.setRequestHeader('Content-Type', 'application/json'); 14 | xhr.send(JSON.stringify({filename: file, filedata: data})); 15 | }; 16 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/run.R: -------------------------------------------------------------------------------- 1 | # Run the experiment locally in a web-browser, using plumber 2 | # After the experiment is complete, the data should be stored in the data folder 3 | # when finished, "stop" the server that will be be started by this code 4 | 5 | library(jspsychr) 6 | 7 | # NOTE: about file paths 8 | # Experiment_1 is the assumed name of the parent folder containing the jspsychR template 9 | # Change this to the name of your folder 10 | # The assumption is your folder is inside an R project, which controls the default working directory 11 | 12 | # compiles the experiment file into html 13 | rmarkdown::render("Experiment_1/experiment/index.Rmd", "html_document") 14 | 15 | # runs the html in your browswer 16 | run_locally(path="Experiment_1", 17 | show_in = "browser", 18 | jspsychr_host = "127.0.0.1", 19 | jspsychr_port = 8000) 20 | 21 | 22 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/skeleton/skeleton.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Experiment description" 3 | author: "your name" 4 | date: "8/16/2019" 5 | output: html_document 6 | --- 7 | 8 | ```{r setup, include=FALSE} 9 | knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE) 10 | ``` 11 | 12 | Use this Rmd file to describe your experiment for yourself and other people. 13 | 14 | Use the index.Rmd in the experiment folder to write the script to run the experiment. 15 | 16 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr/template.yaml: -------------------------------------------------------------------------------- 1 | name: jspsychr 2 | description: > 3 | A basic template wrapper for jsPsych 4 | create_dir: TRUE 5 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr_basic_html/skeleton/skeleton.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "title" 3 | author: "Author" 4 | output: 5 | jspsychr::basic_html: 6 | css: NULL 7 | self_contained: yes 8 | theme: null 9 | toc: no 10 | cold_folding: no 11 | --- 12 | 13 | ```{r setup, include=FALSE} 14 | knitr::opts_chunk$set(echo = TRUE) 15 | ``` 16 | -------------------------------------------------------------------------------- /inst/rmarkdown/templates/jspsychr_basic_html/template.yaml: -------------------------------------------------------------------------------- 1 | name: jspsychr_basic_html 2 | description: > 3 | A basic html for jspsychr 4 | create_dir: FALSE 5 | -------------------------------------------------------------------------------- /jsPsychR.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /man/basic_html.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/basic_html.R 3 | \name{basic_html} 4 | \alias{basic_html} 5 | \title{compile with minimal html template} 6 | \usage{ 7 | basic_html(...) 8 | } 9 | \arguments{ 10 | \item{css}{string, paths to css files} 11 | } 12 | \value{ 13 | compiled html document 14 | } 15 | \description{ 16 | Useful for creating external htmls in jspsych 17 | } 18 | \examples{ 19 | 20 | 21 | } 22 | -------------------------------------------------------------------------------- /man/figures/expo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/man/figures/expo.png -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/man/figures/logo.png -------------------------------------------------------------------------------- /man/html_stimulus.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/html_stimulus.R 3 | \name{html_stimulus} 4 | \alias{html_stimulus} 5 | \title{Write html stimulus description from dataframe} 6 | \usage{ 7 | html_stimulus( 8 | df, 9 | html_content, 10 | html_element, 11 | column_names, 12 | css = NULL, 13 | id = "my_stim" 14 | ) 15 | } 16 | \arguments{ 17 | \item{df}{data.frame containing stimulus information and css codes in columns} 18 | 19 | \item{html_content}{character column name containing html content to be placed between html element tags} 20 | 21 | \item{html_element}{character the html element tag to use} 22 | 23 | \item{column_names}{vector of column names containing css attribute definitions} 24 | 25 | \item{css}{vector of names containing valid css attribute names} 26 | 27 | \item{id}{character to set the id of the html element, defaults to "my_stim"} 28 | } 29 | \value{ 30 | vector of html code defining each stimulus 31 | } 32 | \description{ 33 | Write html stimulus description from dataframe 34 | } 35 | \examples{ 36 | 37 | # define a data frame with stimulus info 38 | stroop_stim <- data.frame(stimulus = length(16), 39 | word = rep(c("red","green","blue","yellow"), each=4), 40 | color = rep(c("red","green","blue","yellow"), 4), 41 | response = rep(c("r","g","b","y"), 4), 42 | id = "stroop_stim", 43 | fontsize = "16pt") 44 | 45 | head(stroop_stim) 46 | 47 | # create html stimulus definition 48 | html_stimulus(df = stroop_stim, 49 | html_content = "word", 50 | html_element = "p", 51 | column_names = c("color","fontsize"), 52 | css = c("color", "font-size"), 53 | id = "id" 54 | ) 55 | 56 | # use in a pipe to add stimulus definition to stimuli column 57 | library(dplyr) 58 | stroop_stim <- data.frame(stimulus = length(16), 59 | word = rep(c("red","green","blue","yellow"), each=4), 60 | color = rep(c("red","green","blue","yellow"), 4), 61 | response = rep(c("r","g","b","y"), 4), 62 | id = "stroop_stim", 63 | fontsize = "16pt") \%>\% 64 | mutate(stimulus = html_stimulus(df = ., 65 | html_content = "word", 66 | html_element = "p", 67 | column_names = c("color","fontsize"), 68 | css = c("color", "font-size"), 69 | id = "id")) 70 | head(stroop_stim) 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/resource.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{resource} 4 | \alias{resource} 5 | \title{Refer to a resource file} 6 | \usage{ 7 | resource(file) 8 | } 9 | \arguments{ 10 | \item{file}{path} 11 | } 12 | \description{ 13 | Refer to a resource file 14 | } 15 | -------------------------------------------------------------------------------- /man/run_locally.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/run_locally.R 3 | \name{run_locally} 4 | \alias{run_locally} 5 | \title{Run a jspsych experiment} 6 | \usage{ 7 | run_locally( 8 | path = ".", 9 | show_in = "viewer", 10 | jspsychr_host = "127.0.0.1", 11 | jspsychr_port = 8000 12 | ) 13 | } 14 | \arguments{ 15 | \item{path}{path} 16 | 17 | \item{show_in}{string, "viewer" to show in viewer, or "browser" to show in browser} 18 | 19 | \item{jspsychr_host}{host defaults to 127.0.0.1} 20 | 21 | \item{jspsychr_port}{port defaults to 8000} 22 | } 23 | \description{ 24 | Run a jspsych experiment 25 | } 26 | -------------------------------------------------------------------------------- /man/stimulus_df_to_json.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/stimulus_df_to_json.R 3 | \name{stimulus_df_to_json} 4 | \alias{stimulus_df_to_json} 5 | \title{Convert stimulus dataframe to json object} 6 | \usage{ 7 | stimulus_df_to_json(df, stimulus, data, pretty = TRUE) 8 | } 9 | \arguments{ 10 | \item{df}{dataframe containins stimulus column with html for each stimulus, and additional columns for data codes} 11 | 12 | \item{stimulus}{character name of the stimulus column} 13 | 14 | \item{data}{character vector names of columns to include as data codes} 15 | 16 | \item{pretty}{logical true = pretty format, false=not pretty} 17 | } 18 | \value{ 19 | string a json object definition that can supply jsPsych with stimulus information 20 | } 21 | \description{ 22 | Convert stimulus dataframe to json object 23 | } 24 | \examples{ 25 | 26 | # create a stimulus dataframe 27 | library(dplyr) 28 | stroop_stim <- data.frame(stimulus = length(16), 29 | word = rep(c("red","green","blue","yellow"), each=4), 30 | color = rep(c("red","green","blue","yellow"), 4), 31 | response = rep(c("r","g","b","y"), 4), 32 | id = "stroop_stim", 33 | fontsize = "16pt") \%>\% 34 | mutate(stimulus = html_stimulus(df = ., 35 | html_content = "word", 36 | html_element = "p", 37 | column_names = c("color","fontsize"), 38 | css = c("color", "font-size"), 39 | id = "id")) 40 | head(stroop_stim) 41 | 42 | # convert to json 43 | stimulus_df_to_json(stroop_stim,"stimulus",c("word","color","response")) 44 | 45 | } 46 | -------------------------------------------------------------------------------- /man/unquote.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helpers.R 3 | \name{unquote} 4 | \alias{unquote} 5 | \title{Specify js code directly} 6 | \usage{ 7 | unquote(x) 8 | } 9 | \arguments{ 10 | \item{x}{the code as a string} 11 | } 12 | \description{ 13 | Specify js code directly 14 | } 15 | -------------------------------------------------------------------------------- /man/write_to_script.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/write_to_script.R 3 | \name{write_to_script} 4 | \alias{write_to_script} 5 | \title{Write json to js script} 6 | \usage{ 7 | write_to_script(json_object, var_name = NULL) 8 | } 9 | \arguments{ 10 | \item{json_object}{string a json object} 11 | 12 | \item{var_name}{character default=NULL, set name to declare json object as a variable} 13 | } 14 | \value{ 15 | string printed to the html as a 16 | } 17 | \description{ 18 | To be used in a knitr code chunk with results="asis" 19 | } 20 | \examples{ 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/expo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/vignettes/expo.png -------------------------------------------------------------------------------- /xtra/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CrumpLab/jspsychr/369cf2dede2c82976d51ac3a8f260c81439f049a/xtra/logo.png --------------------------------------------------------------------------------