1+ /*9/9/25: 3 ways of referencing the time points in a video timeline:
2+
3+ 1) floating point: this is the literal time value (no mark created)
4+ 2) decimal: this is the mark's number in an array of anonymous marks
5+ 3) symbolic: currently, only single (1 byte) alphabetic characters: a-zA-Z
6+
7+ The main question is whether the named marks are only in a hash map or are also in
8+
9+ */
110/*9/7/25: Need to seriously simplyfy the timeline positioning/rendering logic. Right now, «
211there is an issue for when the timeline is wider than the window, and the time marker is at
312the end. It seems that the timeline is positioned so that only a couple preview frames are
@@ -240,7 +249,8 @@ let clusters;
240249let cluster_times = [ ] ;
241250let cluster_time_marks ;
242251
243- let marks = [ ] ;
252+ let sym_marks = [ ] ;
253+ let pos_marks = [ ] ;
244254//let mark_times
245255
246256let min_time_wid = 0 ;
@@ -415,7 +425,14 @@ const await_seek = (tm)=>{//«
415425} ; //»
416426
417427const handle_tab = k => { //«
418- let m = find_next_of_arr ( k , cur_mark , marks ) ;
428+
429+ let all_marks = pos_marks . concat ( sym_marks ) ;
430+ all_marks = all_marks . sort ( ( a , b ) => {
431+ if ( a . _time < b . _time ) return - 1 ;
432+ return 1 ;
433+ } ) ;
434+ // let m = find_next_of_arr(k, cur_mark, sym_marks);
435+ let m = find_next_of_arr ( k , cur_mark , all_marks ) ;
419436 if ( ! m ) return ;
420437 if ( cur_mark ) {
421438 cur_mark . _off ( ) ;
@@ -469,7 +486,9 @@ const try_delete = async()=>{//«
469486 is_waiting = true ;
470487// await cur_mark._on();
471488 await seek_to_time ( cur_mark . _time ) ;
472- if ( await wdg . popyesno ( `Delete marker: '${ cur_mark . _id } '?` ) ) {
489+ let use_id = cur_mark . _id ;
490+ if ( isNum ( use_id ) ) use_id ++ ;
491+ if ( await wdg . popyesno ( `Delete marker: '${ use_id } '?` ) ) {
473492 cur_mark . _delIt ( ) ;
474493 }
475494 is_waiting = false ;
@@ -926,7 +945,7 @@ const get_render_slices = (arr, errarg) => {//«
926945const err = errarg || wdg . poperr ;
927946
928947let hash = { } ;
929- for ( let m of marks ) {
948+ for ( let m of sym_marks ) {
930949 hash [ m . _id ] = m ;
931950}
932951
@@ -994,8 +1013,8 @@ cwarn("No output");
9941013 is_waiting = false ;
9951014} ; //»
9961015
997- const scroll_elem = ( elem , tm , x_off ) => { //«
998- let offset = get_timeline_offset ( tm ) ;
1016+ const scroll_elem = ( elem , tm , x_off , bounds_start_arg ) => { //«
1017+ let offset = get_timeline_offset ( tm , bounds_start_arg ) ;
9991018 if ( offset < - 10 || offset > Main . _w + 10 ) elem . _dis = "none" ;
10001019 else {
10011020 elem . _dis = "" ;
@@ -1130,7 +1149,7 @@ const handle_await_arrow_up=(k)=>{//«
11301149 cur_set_images = new SetTimelineImages ( ) ;
11311150 }
11321151 let gotto = vid . currentTime + total_scroll ;
1133- if ( gotto > viddur ) gotto = viddur - 0.001 ;
1152+ if ( gotto > viddur ) gotto = viddur - 0.0001 ;
11341153 else if ( gotto < 0 ) gotto = 0 ;
11351154 vid . currentTime = gotto ;
11361155 tmdiv . innerHTML = get_main_time_str ( gotto ) ;
@@ -1358,15 +1377,22 @@ The video stays at the end.
13581377const seek_to_end = async ( ) => { //«
13591378 timeline . _xLoc = Main . _w - timeline . _width - GRID_W_HALF ;
13601379 align_timeline ( ) ;
1361- await seek_to_time ( viddur - 0.001 , true ) ;
1380+ // await seek_to_time(viddur-0.001, true);
1381+ seek_to_time ( viddur - 0.0001 , true ) ;
13621382 draw_ruler ( { addLast :true } ) ;
13631383} ; //»
13641384const center_to_curtime = ( ) => { //«
13651385 center_to_time ( vid . currentTime ) ;
13661386} ; //»
1367- const get_timeline_offset = tm => { //«
1368- let bounds = get_visual_time_bounds ( ) ;
1369- let tmoff = tm - bounds . start ;
1387+ const get_timeline_offset = ( tm , bounds_start_arg ) => { //«
1388+ let tmoff ;
1389+ if ( isNum ( bounds_start_arg ) ) {
1390+ tmoff = tm - bounds_start_arg ;
1391+ }
1392+ else {
1393+ let bounds = get_visual_time_bounds ( ) ;
1394+ tmoff = tm - bounds . start ;
1395+ }
13701396 let peroff = tmoff / viddur ;
13711397 return peroff * timeline . _width ;
13721398} ; //»
@@ -1799,20 +1825,67 @@ check_timeline_right_edge_for_underflow_and_center_to_time(vid.currentTime);
17991825} ; //»
18001826
18011827const scroll_marks = ( ) => { //«
1802- for ( let m of marks ) {
1803- scroll_elem ( m , m . _time , MARK_X_OFF ) ;
1828+ // let bounds = get_visual_time_bounds();
1829+ let bounds_start = get_visual_time_bounds ( ) . start ;
1830+ let all_marks = pos_marks . concat ( sym_marks ) ;
1831+ for ( let m of all_marks ) {
1832+ // scroll_elem(m, m._time, MARK_X_OFF);
1833+ scroll_elem ( m , m . _time , MARK_X_OFF , bounds_start ) ;
18041834 }
18051835} ; //»
18061836const seek_to_timeline_start = async ( ) => { //«
18071837 await await_seek ( get_visual_time_bounds ( ) . start ) ;
18081838} ; //»
1839+ const try_seek_mark = async ( if_popin ) => { //«
1840+ is_waiting = true ;
1841+ let rv ;
1842+ if ( if_popin ) rv = await wdg . popin ( `Seek to mark?` ) ;
1843+ // else rv = await wdg.popkey(`Seek to sym mark?`, {alpha: true});
1844+ else rv = await wdg . popkey ( `Seek to mark?` , { alpha : true , digit : true } ) ;
1845+ if ( rv ) {
1846+ let gotit = false ;
1847+ if ( isNum ( rv ) ) {
1848+ rv = String . fromCharCode ( rv ) ;
1849+ }
1850+ if ( rv . match ( / ^ [ a - z A - Z ] $ / ) ) {
1851+ for ( let mrk of sym_marks ) {
1852+ if ( mrk . _id == rv ) {
1853+ if ( cur_mark ) cur_mark . _off ( ) ;
1854+ gotit = true ;
1855+ mrk . _on ( ) ;
1856+ break ;
1857+ }
1858+ }
1859+ }
1860+ else if ( rv . match ( / ^ \d + $ / ) ) {
1861+ let id = parseInt ( rv ) - 1 ;
1862+ for ( let mrk of pos_marks ) {
1863+ if ( mrk . _id == id ) {
1864+ if ( cur_mark ) cur_mark . _off ( ) ;
1865+ gotit = true ;
1866+ mrk . _on ( ) ;
1867+ break ;
1868+ }
1869+ }
1870+ }
1871+ else {
1872+ wdg . poperr ( `Invalid mark id: ${ rv } ` ) ;
1873+ gotit = true ;
1874+ }
1875+ if ( ! gotit ) {
1876+ wdg . popup ( `The mark does not exist: '${ rv } '` ) ;
1877+ }
1878+ }
1879+ is_waiting = false ;
1880+ } ; //»
1881+ /*
18091882const try_seek_mark=async()=>{//«
18101883 is_waiting = true;
1811- let rv = await wdg . popkey ( `Seek to marker ?` , { alpha : true } ) ;
1884+ let rv = await wdg.popkey(`Seek to sym mark ?`, {alpha: true});
18121885 if (rv) {
18131886 rv = String.fromCharCode(rv);
18141887 let nogo=false;
1815- for ( let mrk of marks ) {
1888+ for (let mrk of sym_marks ){
18161889 if (mrk._id == rv){
18171890 if (cur_mark) cur_mark._off();
18181891 mrk._on();
@@ -1822,14 +1895,20 @@ const try_seek_mark=async()=>{//«
18221895 }
18231896 is_waiting = false;
18241897};//»
1825- const try_create_mark = async ( ) => { //«
1898+ */
1899+ const try_create_mark = async ( if_sym ) => { //«
1900+ if ( ! if_sym ) {
1901+ if ( cur_mark ) cur_mark . _off ( ) ;
1902+ create_mark ( vid . currentTime ) ;
1903+ return ;
1904+ }
18261905 is_waiting = true ;
18271906 let rv = await wdg . popkey ( `New marker id?` , { alpha : true } ) ;
18281907//log(rv);
18291908 if ( rv ) {
18301909 rv = String . fromCharCode ( rv ) ;
18311910 let nogo = false ;
1832- for ( let mrk of marks ) {
1911+ for ( let mrk of sym_marks ) {
18331912 if ( mrk . _id == rv ) {
18341913 nogo = true ;
18351914 wdg . poperr ( `Another mark with id '${ rv } ' exists!` ) ;
@@ -1843,29 +1922,45 @@ const try_create_mark=async()=>{//«
18431922 }
18441923 is_waiting = false ;
18451924} ; //»
1925+ const renumber_pos_marks = ( ) => {
1926+ for ( let i = 0 ; i < pos_marks . length ; i ++ ) {
1927+ let m = pos_marks [ i ] ;
1928+ m . _id = i ;
1929+ m . innerHTML = i + 1 ;
1930+ }
1931+ }
18461932const create_mark = ( usetime , id , if_auto ) => { //«
18471933 let tm = usetime || vid . currentTime ;
1848- for ( let m of marks ) {
1934+ let all_marks = pos_marks . concat ( sym_marks ) ;
1935+ // for (let m of sym_marks){
1936+ for ( let m of all_marks ) {
18491937 let diff = Math . abs ( m . _time - tm ) ;
18501938 if ( diff < MARK_DIFF_THRESH ) {
18511939 wdg . poperr ( `Another mark is too close (${ diff } < ${ MARK_DIFF_THRESH } )` ) ;
18521940 return ;
18531941 }
18541942 }
1943+ let mark_pos ;
1944+ if ( ! id ) {
1945+ id = 0 ;
1946+ for ( let m of pos_marks ) {
1947+ //cwarn(tm, m._time);
1948+ if ( tm < m . _time ) {
1949+ break ;
1950+ }
1951+ id ++ ;
1952+ }
1953+ //log("ID",id);
1954+ }
18551955 let mrk = mkdv ( ) ;
18561956 mrk . _pos = "absolute" ;
1857- // mrk._tcol="#000";
1858- // mrk.innerHTML='v';
1859- mrk . innerHTML = id ;
1957+ mrk . innerHTML = id ;
1958+ mrk . _id = id ;
18601959 mrk . _fs = MARK_SZ ;
18611960 mrk . _y = MARK_Y ;
1862- // mrk._fw=900;
18631961 mrk . setAttribute ( "name" , "marker" ) ;
18641962 mrk . _z = 100 ;
18651963 mrk . _time = tm ;
1866- mrk . _id = id ;
1867- //log(mrk);
1868- // mrk._tcol=MARK_OFF_COL;
18691964 mrk . _off = ( ) => {
18701965 mrk . _tcol = MARK_OFF_COL ;
18711966 mrk . _fw = "" ;
@@ -1879,34 +1974,51 @@ const create_mark=(usetime, id, if_auto)=>{//«
18791974 center_to_curtime ( ) ;
18801975 scroll_marks ( ) ;
18811976 scroll_cluster_marks ( ) ;
1882- stat ( `Current mark: '${ id } ' (${ tm . toFixed ( 3 ) } s)` ) ;
1977+ if ( isNum ( id ) ) stat ( `Pos mark: #${ mrk . _id + 1 } (${ tm . toFixed ( 3 ) } s)` ) ;
1978+ else stat ( `Sym mark: '${ mrk . _id } ' (${ tm . toFixed ( 3 ) } s)` ) ;
18831979 } ;
18841980 mrk . _delIt = ( ) => {
1885- remove_elem ( mrk , marks ) ;
1981+ if ( isNum ( id ) ) {
1982+ remove_elem ( mrk , pos_marks ) ;
1983+ renumber_pos_marks ( ) ;
1984+ }
1985+ else {
1986+ remove_elem ( mrk , sym_marks ) ;
1987+ }
1988+ if ( isNum ( id ) ) stat ( `Deleted: #${ mrk . _id + 1 } ` ) ;
1989+ else stat ( `Deleted: '${ mrk . _id } '` ) ;
18861990 mrk . _del ( ) ;
1887- if ( marks . length ) marks [ 0 ] . _on ( ) ;
1991+ cur_mark = null ;
18881992 } ;
18891993 if ( cur_mark ) cur_mark . _off ( ) ;
18901994 mrk . _maybeScroll = ( ) => {
18911995 check_scroll ( mrk ) ;
18921996 }
18931997 if ( if_auto ) mrk . _off ( ) ;
18941998 else mrk . _on ( ) ;
1895-
18961999 timeline . _add ( mrk ) ;
1897- marks . push ( mrk ) ;
1898- marks = marks . sort ( ( a , b ) => {
1899- if ( a . _time < b . _time ) return - 1 ;
1900- return 1 ;
1901- } ) ;
2000+
2001+ if ( isNum ( id ) ) {
2002+ pos_marks . splice ( id , 0 , mrk ) ;
2003+ renumber_pos_marks ( ) ;
2004+ }
2005+ else {
2006+ sym_marks . push ( mrk ) ;
2007+ sym_marks = sym_marks . sort ( ( a , b ) => {
2008+ if ( a . _time < b . _time ) return - 1 ;
2009+ return 1 ;
2010+ } ) ;
2011+ }
2012+
19022013 scroll_marks ( ) ;
19032014 scroll_cluster_marks ( ) ;
19042015} ; //»
19052016
19062017const scroll_cluster_marks = ( ) => { //«
19072018 if ( cluster_marks_div . _dis == "none" ) return ;
2019+ let bounds_start = get_visual_time_bounds ( ) . start ;
19082020 for ( let i = 0 ; i < cluster_times . length ; i ++ ) {
1909- scroll_elem ( cluster_time_marks [ i ] , cluster_times [ i ] , MARK_X_OFF ) ;
2021+ scroll_elem ( cluster_time_marks [ i ] , cluster_times [ i ] , MARK_X_OFF , bounds_start ) ;
19102022 }
19112023} ; //»
19122024const add_cluster_time_marks = ( ) => { //«
@@ -2160,13 +2272,6 @@ this.onkeydown=(e,k)=>{//«
21602272 let { start, end} = get_visual_time_bounds ( ) ;
21612273 seek_to_time ( ( start + end ) / 2 ) ;
21622274 }
2163- else if ( k == "m_S" ) {
2164- if ( cluster_marks_div . _dis == "none" ) {
2165- cluster_marks_div . _dis = "" ;
2166- scroll_cluster_marks ( ) ;
2167- }
2168- else cluster_marks_div . _dis = "none" ;
2169- }
21702275 else if ( k == "s_C" ) {
21712276 try_save ( ) ;
21722277 }
@@ -2178,18 +2283,30 @@ this.onkeydown=(e,k)=>{//«
21782283 }
21792284 else {
21802285 vid . pause ( ) ;
2181- //update_all();
2182- // cur_set_images = new SetTimelineImages();
2183- //draw_ruler();
21842286 vid . ontimeupdate = null ;
21852287 }
21862288 }
21872289 else if ( k == "m_" ) {
21882290 try_create_mark ( ) ;
21892291 }
2292+ else if ( k == "m_S" ) {
2293+ try_create_mark ( true ) ;
2294+ }
21902295 else if ( k == "`_" ) {
21912296 try_seek_mark ( ) ;
21922297 }
2298+ else if ( k == "`_S" ) {
2299+ try_seek_mark ( true ) ;
2300+ }
2301+ /*
2302+ else if (k=="m_S"){
2303+ if (cluster_marks_div._dis=="none") {
2304+ cluster_marks_div._dis="";
2305+ scroll_cluster_marks();
2306+ }
2307+ else cluster_marks_div._dis="none";
2308+ }
2309+ */
21932310 else if ( k == "f_" ) {
21942311 fit_timeline_to_window ( ) ;
21952312 }
0 commit comments