1
1
import { JsPsych , JsPsychPlugin , ParameterType , TrialType } from "jspsych" ;
2
2
3
+ import { inside_ellipse , make_arr , random_coordinate , shuffle } from "./utils" ;
4
+
3
5
const info = < const > {
4
6
name : "free-sort" ,
5
7
parameters : {
@@ -240,17 +242,15 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
240
242
for ( const x of make_arr ( 0 , trial . sort_area_width - trial . stim_width , num_rows ) ) {
241
243
for ( const y of make_arr ( 0 , trial . sort_area_height - trial . stim_height , num_rows ) ) {
242
244
if ( x > ( trial . sort_area_width - trial . stim_width ) * 0.5 ) {
243
- //r_coords.push({ x:x, y:y } )
244
245
r_coords . push ( {
245
246
x : x + trial . sort_area_width * ( 0.5 * trial . column_spread_factor ) ,
246
- y : y ,
247
+ y,
247
248
} ) ;
248
249
} else {
249
250
l_coords . push ( {
250
251
x : x - trial . sort_area_width * ( 0.5 * trial . column_spread_factor ) ,
251
- y : y ,
252
+ y,
252
253
} ) ;
253
- //l_coords.push({ x:x, y:y } )
254
254
}
255
255
}
256
256
}
@@ -267,7 +267,6 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
267
267
stimuli = shuffle ( stimuli ) ;
268
268
}
269
269
270
- let inside = [ ] ;
271
270
for ( let i = 0 ; i < stimuli . length ; i ++ ) {
272
271
var coords ;
273
272
if ( trial . stim_starts_inside ) {
@@ -312,21 +311,19 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
312
311
x : coords . x ,
313
312
y : coords . y ,
314
313
} ) ;
315
- if ( trial . stim_starts_inside ) {
316
- inside . push ( true ) ;
317
- } else {
318
- inside . push ( false ) ;
319
- }
320
314
}
315
+ const inside = stimuli . map ( ( ) => trial . stim_starts_inside ) ;
321
316
322
317
// moves within a trial
323
- let moves = [ ] ;
318
+ const moves = [ ] ;
324
319
325
320
// are objects currently inside
326
321
let cur_in = false ;
327
322
328
323
// draggable items
329
- const draggables = display_element . querySelectorAll ( ".jspsych-free-sort-draggable" ) ;
324
+ const draggables = Array . from (
325
+ display_element . querySelectorAll < HTMLImageElement > ( ".jspsych-free-sort-draggable" )
326
+ ) ;
330
327
331
328
// button (will show when all items are inside) and border (will change color)
332
329
const border : HTMLElement = display_element . querySelector ( "#jspsych-free-sort-border" ) ;
@@ -345,48 +342,13 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
345
342
trial . counter_text_finished ;
346
343
}
347
344
348
- let start_event_name = "mousedown" ;
349
- let move_event_name = "mousemove" ;
350
- let end_event_name = "mouseup" ;
351
- if ( typeof document . ontouchend !== "undefined" ) {
352
- // for touch devices
353
- start_event_name = "touchstart" ;
354
- move_event_name = "touchmove" ;
355
- end_event_name = "touchend" ;
356
- }
357
-
358
- for ( let i = 0 ; i < draggables . length ; i ++ ) {
359
- draggables [ i ] . addEventListener ( start_event_name , ( event : MouseEvent | TouchEvent ) => {
360
- let pageX : number ;
361
- let pageY : number ;
362
- if ( event instanceof MouseEvent ) {
363
- pageX = event . pageX ;
364
- pageY = event . pageY ;
365
- }
366
- //if (typeof document.ontouchend !== "undefined") {
367
- if ( event instanceof TouchEvent ) {
368
- // for touch devices
369
- event . preventDefault ( ) ;
370
- const touchObject = event . changedTouches [ 0 ] ;
371
- pageX = touchObject . pageX ;
372
- pageY = touchObject . pageY ;
373
- }
374
-
375
- let elem = event . currentTarget as HTMLImageElement ;
376
- let x = pageX - elem . offsetLeft ;
377
- let y = pageY - elem . offsetTop - window . scrollY ;
378
- elem . style . transform = "scale(" + trial . scale_factor + "," + trial . scale_factor + ")" ;
379
-
380
- let move_event = ( e ) => {
381
- let clientX = e . clientX ;
382
- let clientY = e . clientY ;
383
- if ( typeof document . ontouchend !== "undefined" ) {
384
- // for touch devices
385
- const touchObject = e . changedTouches [ 0 ] ;
386
- clientX = touchObject . clientX ;
387
- clientY = touchObject . clientY ;
388
- }
345
+ for ( const draggable of draggables ) {
346
+ draggable . addEventListener ( "pointerdown" , function ( { clientX : pageX , clientY : pageY } ) {
347
+ let x = pageX - this . offsetLeft ;
348
+ let y = pageY - this . offsetTop - window . scrollY ;
349
+ this . style . transform = "scale(" + trial . scale_factor + "," + trial . scale_factor + ")" ;
389
350
351
+ const on_pointer_move = ( { clientX, clientY } : PointerEvent ) => {
390
352
cur_in = inside_ellipse (
391
353
clientX - x ,
392
354
clientY - y ,
@@ -396,12 +358,12 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
396
358
trial . sort_area_height * 0.5 ,
397
359
trial . sort_area_shape == "square"
398
360
) ;
399
- elem . style . top =
361
+ this . style . top =
400
362
Math . min (
401
363
trial . sort_area_height - trial . stim_height * 0.5 ,
402
364
Math . max ( - trial . stim_height * 0.5 , clientY - y )
403
365
) + "px" ;
404
- elem . style . left =
366
+ this . style . left =
405
367
Math . min (
406
368
trial . sort_area_width * 1.5 - trial . stim_width ,
407
369
Math . max ( - trial . sort_area_width * 0.5 , clientX - x )
@@ -419,7 +381,7 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
419
381
}
420
382
421
383
// replace in overall array, grab index from item id
422
- var elem_number = parseInt ( elem . id . split ( "jspsych-free-sort-draggable-" ) [ 1 ] , 10 ) ;
384
+ var elem_number = parseInt ( this . id . split ( "jspsych-free-sort-draggable-" ) [ 1 ] , 10 ) ;
423
385
inside . splice ( elem_number , 1 , cur_in ) ;
424
386
425
387
// modify text and background if all items are inside
@@ -437,11 +399,11 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
437
399
get_counter_text ( inside . length - inside . filter ( Boolean ) . length ) ;
438
400
}
439
401
} ;
440
- document . addEventListener ( move_event_name , move_event ) ;
402
+ document . addEventListener ( "pointermove" , on_pointer_move ) ;
441
403
442
- var end_event = ( e ) => {
443
- document . removeEventListener ( move_event_name , move_event ) ;
444
- elem . style . transform = "scale(1, 1)" ;
404
+ const on_pointer_up = ( e ) => {
405
+ document . removeEventListener ( "pointermove" , on_pointer_move ) ;
406
+ this . style . transform = "scale(1, 1)" ;
445
407
if ( trial . change_border_background_color ) {
446
408
if ( inside . every ( Boolean ) ) {
447
409
border . style . background = trial . border_color_in ;
@@ -452,13 +414,13 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
452
414
}
453
415
}
454
416
moves . push ( {
455
- src : elem . dataset . src ,
456
- x : elem . offsetLeft ,
457
- y : elem . offsetTop ,
417
+ src : this . dataset . src ,
418
+ x : this . offsetLeft ,
419
+ y : this . offsetTop ,
458
420
} ) ;
459
- document . removeEventListener ( end_event_name , end_event ) ;
421
+ document . removeEventListener ( "pointerup" , on_pointer_up ) ;
460
422
} ;
461
- document . addEventListener ( end_event_name , end_event ) ;
423
+ document . addEventListener ( "pointerup" , on_pointer_up ) ;
462
424
} ) ;
463
425
}
464
426
@@ -507,56 +469,6 @@ class FreeSortPlugin implements JsPsychPlugin<Info> {
507
469
}
508
470
return text_out ;
509
471
}
510
-
511
- // helper functions
512
- function shuffle ( array ) {
513
- // define three variables
514
- let cur_idx = array . length ,
515
- tmp_val ,
516
- rand_idx ;
517
-
518
- // While there remain elements to shuffle...
519
- while ( 0 !== cur_idx ) {
520
- // Pick a remaining element...
521
- rand_idx = Math . floor ( Math . random ( ) * cur_idx ) ;
522
- cur_idx -= 1 ;
523
-
524
- // And swap it with the current element.
525
- tmp_val = array [ cur_idx ] ;
526
- array [ cur_idx ] = array [ rand_idx ] ;
527
- array [ rand_idx ] = tmp_val ;
528
- }
529
- return array ;
530
- }
531
-
532
- function make_arr ( startValue , stopValue , cardinality ) {
533
- const step = ( stopValue - startValue ) / ( cardinality - 1 ) ;
534
- let arr = [ ] ;
535
- for ( let i = 0 ; i < cardinality ; i ++ ) {
536
- arr . push ( startValue + step * i ) ;
537
- }
538
- return arr ;
539
- }
540
-
541
- function inside_ellipse ( x , y , x0 , y0 , rx , ry , square = false ) {
542
- const results = [ ] ;
543
- if ( square ) {
544
- return Math . abs ( x - x0 ) <= rx && Math . abs ( y - y0 ) <= ry ;
545
- } else {
546
- return (
547
- ( x - x0 ) * ( x - x0 ) * ( ry * ry ) + ( y - y0 ) * ( y - y0 ) * ( rx * rx ) <= rx * rx * ( ry * ry )
548
- ) ;
549
- }
550
- }
551
-
552
- function random_coordinate ( max_width , max_height ) {
553
- const rnd_x = Math . floor ( Math . random ( ) * ( max_width - 1 ) ) ;
554
- const rnd_y = Math . floor ( Math . random ( ) * ( max_height - 1 ) ) ;
555
- return {
556
- x : rnd_x ,
557
- y : rnd_y ,
558
- } ;
559
- }
560
472
}
561
473
}
562
474
0 commit comments