@@ -245,6 +245,12 @@ var CoreComment = (function () {
245245 this . cindex = - 1 ;
246246 this . motion = [ ] ;
247247 this . movable = true ;
248+ this . _alphaMotion = null ;
249+ /**
250+ * Absolute coordinates. Use absolute coordinates if true otherwise use percentages.
251+ * @type {boolean } use absolute coordinates or not (default true)
252+ */
253+ this . absolute = true ;
248254 /**
249255 * Alignment
250256 * @type {number } 0=tl, 2=bl, 1=tr, 3=br
@@ -310,6 +316,9 @@ var CoreComment = (function () {
310316 if ( init . hasOwnProperty ( "opacity" ) ) {
311317 this . _alpha = init [ "opacity" ] ;
312318 }
319+ if ( init . hasOwnProperty ( "alpha" ) ) {
320+ this . _alphaMotion = init [ "alpha" ] ;
321+ }
313322 if ( init . hasOwnProperty ( "font" ) ) {
314323 this . _font = init [ "font" ] ;
315324 }
@@ -322,6 +331,14 @@ var CoreComment = (function () {
322331 if ( init . hasOwnProperty ( "shadow" ) ) {
323332 this . _shadow = init [ "shadow" ] ;
324333 }
334+ if ( init . hasOwnProperty ( "position" ) ) {
335+ if ( init [ "position" ] === "relative" ) {
336+ this . absolute = false ;
337+ if ( this . mode < 7 ) {
338+ console . warn ( "Using relative position for CSA comment." ) ;
339+ }
340+ }
341+ }
325342 }
326343 /**
327344 * Initializes the DOM element (or canvas) backing the comment
@@ -369,10 +386,16 @@ var CoreComment = (function () {
369386 this . _x = this . parent . width - this . dom . offsetLeft - this . width ;
370387 }
371388 }
389+ if ( ! this . absolute ) {
390+ return this . _x / this . parent . width ;
391+ }
372392 return this . _x ;
373393 } ,
374394 set : function ( x ) {
375395 this . _x = x ;
396+ if ( ! this . absolute ) {
397+ this . _x *= this . parent . width ;
398+ }
376399 if ( this . align % 2 === 0 ) {
377400 this . dom . style . left = this . _x + "px" ;
378401 } else {
@@ -392,10 +415,16 @@ var CoreComment = (function () {
392415 this . _y = this . parent . height - this . dom . offsetTop - this . height ;
393416 }
394417 }
418+ if ( ! this . absolute ) {
419+ return this . _y / this . parent . height ;
420+ }
395421 return this . _y ;
396422 } ,
397423 set : function ( y ) {
398424 this . _y = y ;
425+ if ( ! this . absolute ) {
426+ this . _y *= this . parent . height ;
427+ }
399428 if ( this . align < 2 ) {
400429 this . dom . style . top = this . _y + "px" ;
401430 } else {
@@ -581,27 +610,44 @@ var CoreComment = (function () {
581610 this . _y = null ;
582611 } ;
583612
613+ /**
614+ * Executes a motion object
615+ * @param currentMotion - motion object
616+ * @private
617+ */
618+ CoreComment . prototype . _execMotion = function ( currentMotion , time ) {
619+ for ( var prop in currentMotion ) {
620+ if ( currentMotion . hasOwnProperty ( prop ) ) {
621+ var m = currentMotion [ prop ] ;
622+ this [ prop ] = m . easing ( Math . min ( Math . max ( time - m . delay , 0 ) , m . dur ) , m . from , m . to - m . from , m . dur ) ;
623+ }
624+ }
625+ } ;
626+
584627 /**
585628 * Update the comment's position depending on the applied motion
586629 * groups.
587630 */
588631 CoreComment . prototype . animate = function ( ) {
632+ if ( this . _alphaMotion ) {
633+ this . alpha = ( this . dur - this . ttl ) * ( this . _alphaMotion [ "to" ] - this . _alphaMotion [ "from" ] ) / this . dur + this . _alphaMotion [ "from" ] ;
634+ }
589635 if ( this . motion . length === 0 ) {
590636 return ;
591637 }
592- if ( this . dur - this . ttl > this . _motionEnd [ this . _curMotion ] ) {
638+ var ttl = Math . max ( this . ttl , 0 ) ;
639+ var time = ( this . dur - ttl ) - this . _motionStart [ this . _curMotion ] ;
640+ if ( this . dur - ttl > this . _motionEnd [ this . _curMotion ] ) {
641+ var oldMotion = this . motion [ this . _curMotion ] ;
642+ this . _execMotion ( oldMotion , time ) ;
593643 this . _curMotion ++ ;
594- this . animate ( ) ;
644+ if ( this . _curMotion >= this . motion . length ) {
645+ this . _curMotion = this . motion . length - 1 ;
646+ }
595647 return ;
596648 } else {
597649 var currentMotion = this . motion [ this . _curMotion ] ;
598- var time = ( this . dur - Math . max ( this . ttl , 0 ) ) - this . _motionStart [ this . _curMotion ] ;
599- for ( var prop in currentMotion ) {
600- if ( currentMotion . hasOwnProperty ( prop ) ) {
601- var m = currentMotion [ prop ] ;
602- this [ prop ] = m . easing ( Math . min ( Math . max ( time - m . delay , 0 ) , m . dur ) , m . from , m . to - m . from , m . dur ) ;
603- }
604- }
650+ this . _execMotion ( currentMotion , time ) ;
605651 }
606652 } ;
607653
@@ -636,6 +682,7 @@ var ScrollComment = (function (_super) {
636682 if ( typeof recycle === "undefined" ) { recycle = null ; }
637683 _super . prototype . init . call ( this , recycle ) ;
638684 this . x = this . parent . width ;
685+ this . absolute = true ;
639686 } ;
640687
641688 ScrollComment . prototype . update = function ( ) {
@@ -929,12 +976,6 @@ Licensed Under MIT License
929976 An alternative format comment parser
930977**/
931978function AcfunParser ( jsond ) {
932- function fillRGB ( string ) {
933- while ( string . length < 6 ) {
934- string = "0" + string ;
935- }
936- return string ;
937- }
938979 var list = [ ] ;
939980 try {
940981 var jsondt = JSON . parse ( jsond ) ;
@@ -948,12 +989,12 @@ function AcfunParser(jsond){
948989 var xc = jsondt [ i ] [ 'c' ] . split ( ',' ) ;
949990 if ( xc . length > 0 ) {
950991 data . stime = parseFloat ( xc [ 0 ] ) * 1000 ;
951- data . color = '#' + fillRGB ( parseInt ( xc [ 1 ] ) . toString ( 16 ) ) ;
992+ data . color = parseInt ( xc [ 1 ] )
952993 data . mode = parseInt ( xc [ 2 ] ) ;
953994 data . size = parseInt ( xc [ 3 ] ) ;
954995 data . hash = xc [ 4 ] ;
955996 data . date = parseInt ( xc [ 5 ] ) ;
956- data . position = "relative " ;
997+ data . position = "absolute " ;
957998 if ( data . mode != 7 ) {
958999 data . text = jsondt [ i ] . m . replace ( / ( \/ n | \\ n | \n | \r \n | \\ r ) / g, "\n" ) ;
9591000 data . text = data . text . replace ( / \r / g, "\n" ) ;
@@ -970,9 +1011,15 @@ function AcfunParser(jsond){
9701011 console . log ( '[Dbg] ' + data . text ) ;
9711012 continue ;
9721013 }
1014+ data . position = "relative" ;
9731015 data . text = x . n ; /*.replace(/\r/g,"\n");*/
9741016 data . text = data . text . replace ( / \ / g, "\u00a0" ) ;
9751017 console . log ( data . text ) ;
1018+ if ( x . a != null ) {
1019+ data . opacity = x . a ;
1020+ } else {
1021+ data . opacity = 1 ;
1022+ }
9761023 if ( x . p != null ) {
9771024 data . x = x . p . x / 1000 ; // relative position
9781025 data . y = x . p . y / 1000 ;
@@ -981,25 +1028,40 @@ function AcfunParser(jsond){
9811028 data . y = 0 ;
9821029 }
9831030 data . shadow = x . b ;
984- data . duration = 4000 ;
1031+ data . dur = 4000 ;
9851032 if ( x . l != null )
9861033 data . moveDelay = x . l * 1000 ;
9871034 if ( x . z != null && x . z . length > 0 ) {
9881035 data . movable = true ;
989- data . toX = x . z [ 0 ] . x / 1000 ;
990- data . toY = x . z [ 0 ] . y / 1000 ;
991- data . alphaTo = x . z [ 0 ] . t ;
992- data . colorTo = x . z [ 0 ] . c ;
993- data . moveDuration = x . z [ 0 ] . l != null ? ( x . z [ 0 ] . l * 1000 ) : 500 ;
994- data . duration = data . moveDelay + data . moveDuration ;
1036+ data . motion = [ ] ;
1037+ var moveDuration = 0 ;
1038+ var last = { x :data . x , y :data . y , alpha :data . opacity , color :data . color } ;
1039+ for ( var m = 0 ; m < x . z . length ; m ++ ) {
1040+ var dur = x . z [ m ] . l != null ? ( x . z [ m ] . l * 1000 ) : 500 ;
1041+ moveDuration += dur ;
1042+ var motion = {
1043+ x :{ from :last . x , to :x . z [ m ] . x / 1000 , dur : dur , delay : 0 } ,
1044+ y :{ from :last . y , to :x . z [ m ] . y / 1000 , dur : dur , delay : 0 }
1045+ } ;
1046+ last . x = motion . x . to ;
1047+ last . y = motion . y . to ;
1048+ if ( x . z [ m ] . t !== last . alpha ) {
1049+ motion . alpha = { from :last . alpha , to :x . z [ m ] . t , dur : dur , delay : 0 } ;
1050+ last . alpha = motion . alpha . to ;
1051+ }
1052+ if ( x . z [ m ] . c != null && x . z [ m ] . c !== last . color ) {
1053+ motion . color = { from :last . color , to :x . z [ m ] . c , dur : dur , delay : 0 } ;
1054+ last . color = motion . color . to ;
1055+ }
1056+ data . motion . push ( motion ) ;
1057+ }
1058+ data . dur = moveDuration + ( data . moveDelay ? data . moveDelay : 0 ) ;
9951059 }
9961060 if ( x . r != null && x . k != null ) {
9971061 data . rX = x . r ;
9981062 data . rY = x . k ;
9991063 }
1000- if ( x . a ) {
1001- data . alphaFrom = x . a ;
1002- }
1064+
10031065 }
10041066 list . push ( data ) ;
10051067 }
@@ -1013,32 +1075,36 @@ Licensed Under MIT License
10131075 Takes in an XMLDoc/LooseXMLDoc and parses that into a Generic Comment List
10141076**/
10151077function BilibiliParser ( xmlDoc , text , warn ) {
1016- //Format the bili output to be json-valid
10171078 function format ( string ) {
1079+ //Format the bili output to be json-valid
10181080 return string . replace ( / \t / , "\\t" ) ;
10191081 }
1082+
10201083 if ( xmlDoc !== null ) {
1021- var elems = xmlDoc . getElementsByTagName ( 'd' ) ;
1022- } else {
1023- if ( warn ) {
1024- if ( ! confirm ( "XML Parse Error. \n Allow tag soup parsing?\n[WARNING: This is unsafe.]" ) ) {
1025- return [ ] ;
1026- }
1027- } else {
1028- // clobber some potentially bad things
1029- text = text . replace ( new RegExp ( "</([^d])" , "g" ) , "</disabled $1" ) ;
1030- text = text . replace ( new RegExp ( "</(\S{2,})" , "g" ) , "</disabled $1" ) ;
1031- text = text . replace ( new RegExp ( "<([^d/]\W*?)" , "g" ) , "<disabled $1" ) ;
1032- text = text . replace ( new RegExp ( "<([^/ ]{2,}\W*?)" , "g" ) , "<disabled $1" ) ;
1033- console . log ( text ) ;
1034- }
1035- var tmp = document . createElement ( "div" ) ;
1036- tmp . innerHTML = text ;
1037- console . log ( tmp ) ;
1038- var elems = tmp . getElementsByTagName ( 'd' ) ;
1039- }
1084+ var elems = xmlDoc . getElementsByTagName ( 'd' ) ;
1085+ } else {
1086+ if ( ! document || ! document . createElement ) {
1087+ //Maybe we are in a restricted context
1088+ return [ ] ;
1089+ }
1090+ if ( warn ) {
1091+ if ( ! confirm ( "XML Parse Error. \n Allow tag soup parsing?\n[WARNING: This is unsafe.]" ) ) {
1092+ return [ ] ;
1093+ }
1094+ } else {
1095+ // clobber some potentially bad things
1096+ text = text . replace ( new RegExp ( "</([^d])" , "g" ) , "</disabled $1" ) ;
1097+ text = text . replace ( new RegExp ( "</(\S{2,})" , "g" ) , "</disabled $1" ) ;
1098+ text = text . replace ( new RegExp ( "<([^d/]\W*?)" , "g" ) , "<disabled $1" ) ;
1099+ text = text . replace ( new RegExp ( "<([^/ ]{2,}\W*?)" , "g" ) , "<disabled $1" ) ;
1100+ }
1101+ var tmp = document . createElement ( "div" ) ;
1102+ tmp . innerHTML = text ;
1103+ var elems = tmp . getElementsByTagName ( 'd' ) ;
1104+ }
1105+
10401106 var tlist = [ ] ;
1041- for ( var i = 0 ; i < elems . length ; i ++ ) {
1107+ for ( var i = 0 ; i < elems . length ; i ++ ) {
10421108 if ( elems [ i ] . getAttribute ( 'p' ) != null ) {
10431109 var opt = elems [ i ] . getAttribute ( 'p' ) . split ( ',' ) ;
10441110 if ( ! elems [ i ] . childNodes [ 0 ] )
@@ -1063,8 +1129,11 @@ function BilibiliParser(xmlDoc, text, warn){
10631129 try {
10641130 adv = JSON . parse ( format ( text ) ) ;
10651131 obj . shadow = true ;
1066- obj . x = parseInt ( adv [ 0 ] , 10 ) ;
1067- obj . y = parseInt ( adv [ 1 ] , 10 ) ;
1132+ obj . x = parseFloat ( adv [ 0 ] ) ;
1133+ obj . y = parseFloat ( adv [ 1 ] ) ;
1134+ if ( Math . floor ( obj . x ) < obj . x || Math . floor ( obj . y ) < obj . y ) {
1135+ obj . position = "relative" ;
1136+ }
10681137 obj . text = adv [ 4 ] . replace ( / ( \/ n | \\ n | \n | \r \n ) / g, "\n" ) ;
10691138 obj . rZ = 0 ;
10701139 obj . rY = 0 ;
@@ -1076,13 +1145,15 @@ function BilibiliParser(xmlDoc, text, warn){
10761145 obj . movable = false ;
10771146 if ( adv . length >= 11 ) {
10781147 obj . movable = true ;
1148+ var singleStepDur = 500 ;
10791149 var motion = {
1080- x :{ from : obj . x , to :parseInt ( adv [ 7 ] , 10 ) , dur :500 , delay :0 } ,
1081- y :{ from : obj . y , to :parseInt ( adv [ 8 ] , 10 ) , dur :500 , delay :0 } ,
1082- }
1150+ x :{ from : obj . x , to :parseFloat ( adv [ 7 ] ) , dur :singleStepDur , delay :0 } ,
1151+ y :{ from : obj . y , to :parseFloat ( adv [ 8 ] ) , dur :singleStepDur , delay :0 } ,
1152+ } ;
10831153 if ( adv [ 9 ] !== '' ) {
1084- motion . x . dur = parseInt ( adv [ 9 ] , 10 ) ;
1085- motion . y . dur = parseInt ( adv [ 9 ] , 10 ) ;
1154+ singleStepDur = parseInt ( adv [ 9 ] , 10 ) ;
1155+ motion . x . dur = singleStepDur ;
1156+ motion . y . dur = singleStepDur ;
10861157 }
10871158 if ( adv [ 10 ] !== '' ) {
10881159 motion . x . delay = parseInt ( adv [ 10 ] , 10 ) ;
@@ -1099,8 +1170,42 @@ function BilibiliParser(xmlDoc, text, warn){
10991170 if ( adv [ 12 ] != null ) {
11001171 obj . font = adv [ 12 ] ;
11011172 }
1173+ if ( adv . length > 14 ) {
1174+ // Support for Bilibili Advanced Paths
1175+ if ( obj . position === "relative" ) {
1176+ console . log ( "Cannot mix relative and absolute positioning" ) ;
1177+ obj . position = "absolute" ;
1178+ }
1179+ var path = adv [ 14 ] ;
1180+ var lastPoint = { x :motion . x . from , y :motion . y . from } ;
1181+ var pathMotion = [ ] ;
1182+ var regex = new RegExp ( "([a-zA-Z])\\s*(\\d+)[, ](\\d+)" , "g" ) ;
1183+ var counts = path . split ( / [ a - z A - Z ] / ) . length - 1 ;
1184+ var m = regex . exec ( path ) ;
1185+ while ( m !== null ) {
1186+ switch ( m [ 1 ] ) {
1187+ case "M" :{
1188+ lastPoint . x = parseInt ( m [ 2 ] , 10 ) ;
1189+ lastPoint . y = parseInt ( m [ 3 ] , 10 ) ;
1190+ } break ;
1191+ case "L" :{
1192+ pathMotion . push ( {
1193+ "x" :{ "from" :lastPoint . x , "to" :parseInt ( m [ 2 ] , 10 ) , "dur" : singleStepDur / counts , "delay" : 0 } ,
1194+ "y" :{ "from" :lastPoint . y , "to" :parseInt ( m [ 3 ] , 10 ) , "dur" : singleStepDur / counts , "delay" : 0 }
1195+ } ) ;
1196+ lastPoint . x = parseInt ( m [ 2 ] , 10 ) ;
1197+ lastPoint . y = parseInt ( m [ 3 ] , 10 ) ;
1198+ } break ;
1199+ }
1200+ m = regex . exec ( path ) ;
1201+ }
1202+ motion = null ;
1203+ obj . motion = pathMotion ;
1204+ }
1205+ }
1206+ if ( motion !== null ) {
1207+ obj . motion . push ( motion ) ;
11021208 }
1103- obj . motion . push ( motion ) ;
11041209 }
11051210 obj . dur = 2500 ;
11061211 if ( adv [ 3 ] < 12 ) {
@@ -1111,11 +1216,8 @@ function BilibiliParser(xmlDoc, text, warn){
11111216 var alphaFrom = parseFloat ( tmp [ 0 ] ) ;
11121217 var alphaTo = parseFloat ( tmp [ 1 ] ) ;
11131218 obj . opacity = alphaFrom ;
1114- var alphaObj = { from :alphaFrom , to :alphaTo , dur :obj . dur , delay :0 } ;
1115- if ( obj . motion . length > 0 ) {
1116- obj . motion [ 0 ] [ "alpha" ] = alphaObj ;
1117- } else {
1118- obj . motion . push ( { alpha :alphaObj } ) ;
1219+ if ( alphaFrom !== alphaTo ) {
1220+ obj . alpha = { from :alphaFrom , to :alphaTo }
11191221 }
11201222 }
11211223 } catch ( e ) {
@@ -1126,7 +1228,6 @@ function BilibiliParser(xmlDoc, text, warn){
11261228 obj . code = text ; //Code comments are special
11271229 }
11281230 }
1129- //Before we push
11301231 if ( obj . text != null )
11311232 obj . text = obj . text . replace ( / \u25a0 / g, "\u2588" ) ;
11321233 tlist . push ( obj ) ;
0 commit comments