channel.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. import BaseClass from './baseClass'
  2. import util from './utils/util'
  3. /**
  4. * [Channel 弹幕轨道控制]
  5. * @type {Class}
  6. */
  7. class Channel extends BaseClass {
  8. constructor (danmu) {
  9. super()
  10. this.setLogger('channel')
  11. this.danmu = danmu
  12. this.reset()
  13. let self = this
  14. util.on(this.danmu, 'bullet_remove', r => {
  15. self.removeBullet(r.bullet)
  16. }, 'destroy')
  17. this.direction = danmu.direction
  18. util.on(this.danmu, 'changeDirection', direction => {
  19. self.direction = direction
  20. }, 'destroy')
  21. this.containerPos = this.danmu.container.getBoundingClientRect()
  22. this.containerWidth = this.containerPos.width
  23. this.containerHeight = this.containerPos.height
  24. this.containerLeft = this.containerPos.left
  25. this.containerRight = this.containerPos.right
  26. util.on(this.danmu, 'channel_resize', () => {
  27. self.containerPos = self.danmu.container.getBoundingClientRect()
  28. if (self.resizing) {
  29. return
  30. }
  31. self.containerWidth = self.containerPos.width
  32. self.containerHeight = self.containerPos.height
  33. self.containerLeft = self.containerPos.left
  34. self.containerRight = self.containerPos.right
  35. self.resize(true)
  36. }, 'destroy')
  37. }
  38. destroy () {
  39. this.logger.info('destroy')
  40. clearTimeout(this.resizeTimer)
  41. clearTimeout(this.resetTimer)
  42. this.channels = []
  43. for (let k in this) {
  44. delete this[k]
  45. }
  46. }
  47. resize (isFullscreen = false) {
  48. this.logger.info('resize')
  49. let container = this.danmu.container
  50. let self = this
  51. if (self.resizing) {
  52. return
  53. }
  54. self.resizing = true
  55. this.resizeTimer = setTimeout(function () {
  56. let isDanmuPause = self.danmu.bulletBtn.main.status === 'paused'
  57. if (self.danmu.bulletBtn.main.data) {
  58. self.danmu.bulletBtn.main.data.forEach(item => {
  59. if (item.bookChannelId) {
  60. delete item['bookChannelId']
  61. self.logger.info('resize导致' + item.id + '号优先弹幕预定取消')
  62. }
  63. })
  64. }
  65. self.logger.info('resize导致所有轨道恢复正常使用')
  66. let size = container.getBoundingClientRect()
  67. self.width = size.width
  68. self.height = size.height
  69. if (self.danmu.config.area && self.danmu.config.area.start >= 0 && self.danmu.config.area.end >= self.danmu.config.area.start) {
  70. if(self.direction === 'b2t') {
  71. self.width = self.width * (self.danmu.config.area.end - self.danmu.config.area.start)
  72. } else {
  73. self.height = self.height * (self.danmu.config.area.end - self.danmu.config.area.start)
  74. }
  75. }
  76. self.container = container
  77. let fontSize = self.danmu.config.channelSize || (/mobile/ig.test(navigator.userAgent) ? 10 : 12)
  78. let channelSize
  79. if(self.direction === 'b2t') {
  80. channelSize = Math.floor(self.width / fontSize)
  81. } else {
  82. channelSize = Math.floor(self.height / fontSize)
  83. }
  84. let channels = []
  85. for (let i = 0; i < channelSize; i++) {
  86. channels[i] = {
  87. id: i,
  88. queue: {
  89. scroll: [],
  90. top: [],
  91. bottom: []
  92. },
  93. operating: {
  94. scroll: false,
  95. top: false,
  96. bottom: false
  97. },
  98. bookId: {}
  99. }
  100. }
  101. if (self.channels && self.channels.length <= channels.length) {
  102. for (let i = 0; i < self.channels.length; i++) {
  103. channels[i] = {
  104. id: i,
  105. queue: {
  106. scroll: [],
  107. top: [],
  108. bottom: []
  109. },
  110. operating: {
  111. scroll: false,
  112. top: false,
  113. bottom: false
  114. },
  115. bookId: {}
  116. };
  117. ['scroll', 'top'].forEach(key => {
  118. self.channels[i].queue[key].forEach(item => {
  119. if (item.el) {
  120. channels[i].queue[key].push(item)
  121. if(!item.resized) {
  122. item.pauseMove(self.containerPos, isFullscreen)
  123. if (item.danmu.bulletBtn.main.status !== 'paused') {
  124. item.startMove(self.containerPos)
  125. }
  126. item.resized = true
  127. }
  128. }
  129. })
  130. })
  131. self.channels[i].queue['bottom'].forEach(item => {
  132. if (item.el) {
  133. channels[i + channels.length - self.channels.length].queue['bottom'].push(item)
  134. if(item.channel_id[0] + item.channel_id[1] - 1 === i) {
  135. let channel_id = [].concat(item.channel_id)
  136. item.channel_id = [channel_id[0] - self.channels.length + channels.length, channel_id[1]]
  137. item.top = item.channel_id[0] * fontSize
  138. if (self.danmu.config.area && self.danmu.config.area.start) {
  139. item.top += self.containerHeight * self.danmu.config.area.start
  140. }
  141. item.topInit()
  142. }
  143. if(!item.resized) {
  144. item.pauseMove(self.containerPos, isFullscreen)
  145. if (item.danmu.bulletBtn.main.status !== 'paused') {
  146. item.startMove(self.containerPos)
  147. }
  148. item.resized = true
  149. }
  150. }
  151. })
  152. }
  153. for (let i = 0; i < channels.length; i++) {
  154. ['scroll', 'top', 'bottom'].forEach(key => {
  155. channels[i].queue[key].forEach(item => {
  156. // console.log('resized 重置:' + item)
  157. item.resized = false
  158. })
  159. })
  160. }
  161. self.channels = channels
  162. if(self.direction === 'b2t') {
  163. self.channelWidth = fontSize
  164. } else {
  165. self.channelHeight = fontSize
  166. }
  167. } else if (self.channels && self.channels.length > channels.length) {
  168. for (let i = 0; i < channels.length; i++) {
  169. channels[i] = {
  170. id: i,
  171. queue: {
  172. scroll: [],
  173. top: [],
  174. bottom: []
  175. },
  176. operating: {
  177. scroll: false,
  178. top: false,
  179. bottom: false
  180. },
  181. bookId: {}
  182. };
  183. ['scroll', 'top', 'bottom'].forEach(key => {
  184. if (key === 'top' && i > Math.floor(channels.length / 2)) {
  185. } else if (key === 'bottom' && i <= Math.floor(channels.length / 2)) {
  186. } else {
  187. let num = key === 'bottom' ? i - channels.length + self.channels.length : i
  188. self.channels[num].queue[key].forEach((item, index) => {
  189. if (item.el) {
  190. channels[i].queue[key].push(item)
  191. if(key === 'bottom') {
  192. if(item.channel_id[0] + item.channel_id[1] - 1 === num) {
  193. let channel_id = [].concat(item.channel_id)
  194. item.channel_id = [channel_id[0] - self.channels.length + channels.length, channel_id[1]]
  195. item.top = item.channel_id[0] * fontSize
  196. if (self.danmu.config.area && self.danmu.config.area.start) {
  197. item.top += self.containerHeight * self.danmu.config.area.start
  198. }
  199. item.topInit()
  200. }
  201. }
  202. item.pauseMove(self.containerPos, isFullscreen)
  203. if (item.danmu.bulletBtn.main.status !== 'paused') {
  204. item.startMove(self.containerPos)
  205. }
  206. if(!item.resized) {
  207. item.resized = true
  208. }
  209. }
  210. self.channels[num].queue[key].splice(index, 1)
  211. })
  212. }
  213. })
  214. }
  215. // for (let i = channels.length; i < self.channels.length; i++) {
  216. // ['scroll', 'top', 'bottom'].forEach(key => {
  217. // self.channels[i].queue[key].forEach(item => {
  218. // item.pauseMove(self.containerPos)
  219. // item.remove()
  220. // })
  221. // })
  222. // }
  223. for (let i = 0; i < channels.length; i++) {
  224. ['scroll', 'top', 'bottom'].forEach(key => {
  225. channels[i].queue[key].forEach(item => {
  226. // console.log('resized 重置:' + item)
  227. item.resized = false
  228. })
  229. })
  230. }
  231. self.channels = channels
  232. if(self.direction === 'b2t') {
  233. self.channelWidth = fontSize
  234. } else {
  235. self.channelHeight = fontSize
  236. }
  237. }
  238. self.resizing = false
  239. }, 10)
  240. }
  241. addBullet (bullet) {
  242. // this.logger.info(`addBullet ${bullet.options.txt || '[DOM Element]'}`)
  243. let self = this
  244. let danmu = this.danmu
  245. let channels = this.channels
  246. let channelHeight, channelWidth, occupy
  247. if(self.direction === 'b2t') {
  248. channelWidth = this.channelWidth
  249. occupy = Math.ceil(bullet.width / channelWidth)
  250. } else {
  251. channelHeight = this.channelHeight
  252. occupy = Math.ceil(bullet.height / channelHeight)
  253. }
  254. if (occupy > channels.length) {
  255. return {
  256. result: false,
  257. message: `exceed channels.length, occupy=${occupy},channelsSize=${channels.length}`
  258. }
  259. } else {
  260. let flag = true, channel, pos = -1
  261. for (let i = 0, max = channels.length; i < max; i++) {
  262. if (channels[i].queue[bullet.mode].some(item => item.id === bullet.id)) {
  263. return {
  264. result: false,
  265. message: `exsited, channelOrder=${i},danmu_id=${bullet.id}`
  266. }
  267. }
  268. }
  269. if(bullet.mode === 'scroll') {
  270. for (let i = 0, max = channels.length - occupy; i <= max; i++) {
  271. flag = true
  272. for (let j = i; j < i + occupy; j++) {
  273. channel = channels[j]
  274. if (channel.operating.scroll) {
  275. flag = false
  276. break
  277. }
  278. if ((channel.bookId.scroll || bullet.prior) && (channel.bookId.scroll !== bullet.id)) {
  279. flag = false
  280. break
  281. }
  282. channel.operating.scroll = true
  283. let curBullet = channel.queue.scroll[0]
  284. if (curBullet) {
  285. let curBulletPos = curBullet.el.getBoundingClientRect()
  286. if(self.direction === 'b2t') {
  287. if (curBulletPos.bottom > self.containerPos.bottom) {
  288. flag = false
  289. channel.operating.scroll = false
  290. break
  291. }
  292. } else {
  293. if (curBulletPos.right > self.containerPos.right) {
  294. flag = false
  295. channel.operating.scroll = false
  296. break
  297. }
  298. }
  299. // Vcur * t + Scur已走 - Widthcur = Vnew * t
  300. // t = (Scur已走 - Widthcur) / (Vnew - Vcur)
  301. // Vnew * t < Widthplayer
  302. let curS, curV, curT, newS, newV, newT
  303. if(self.direction === 'b2t') {
  304. curS = curBulletPos.top - self.containerPos.top + curBulletPos.height
  305. curV = (self.containerPos.height + curBulletPos.height) / curBullet.duration
  306. curT = curS / curV
  307. newS = self.containerPos.height
  308. newV = (self.containerPos.height + bullet.height) / bullet.duration
  309. } else {
  310. curS = curBulletPos.left - self.containerPos.left + curBulletPos.width
  311. curV = (self.containerPos.width + curBulletPos.width) / curBullet.duration
  312. curT = curS / curV
  313. newS = self.containerPos.width
  314. newV = (self.containerPos.width + bullet.width) / bullet.duration
  315. }
  316. newT = newS / newV
  317. if (!danmu.config.bOffset) {
  318. danmu.config.bOffset = 0
  319. }
  320. if (curV < newV && curT + danmu.config.bOffset > newT) {
  321. flag = false
  322. channel.operating.scroll = false
  323. break
  324. }
  325. }
  326. channel.operating.scroll = false
  327. }
  328. if (flag) {
  329. pos = i
  330. break
  331. }
  332. }
  333. } else if (bullet.mode === 'top') {
  334. for (let i = 0, max = channels.length - occupy; i <= max; i++) {
  335. flag = true
  336. for (let j = i; j < i + occupy; j++) {
  337. if(j > Math.floor(channels.length / 2)) {
  338. flag = false
  339. break
  340. }
  341. channel = channels[j]
  342. if (channel.operating[bullet.mode]) {
  343. flag = false
  344. break
  345. }
  346. if ((channel.bookId[bullet.mode] || bullet.prior) && (channel.bookId[bullet.mode] !== bullet.id)) {
  347. flag = false
  348. break
  349. }
  350. channel.operating[bullet.mode] = true
  351. if (channel.queue[bullet.mode].length > 0) {
  352. flag = false
  353. channel.operating[bullet.mode] = false
  354. break
  355. }
  356. channel.operating[bullet.mode] = false
  357. }
  358. if (flag) {
  359. pos = i
  360. break
  361. }
  362. }
  363. } else if (bullet.mode === 'bottom') {
  364. for (let i = channels.length - occupy; i >= 0; i--) {
  365. flag = true
  366. for (let j = i; j < i + occupy; j++) {
  367. if(j <= Math.floor(channels.length / 2)) {
  368. flag = false
  369. break
  370. }
  371. channel = channels[j]
  372. if (channel.operating[bullet.mode]) {
  373. flag = false
  374. break
  375. }
  376. if ((channel.bookId[bullet.mode] || bullet.prior) && (channel.bookId[bullet.mode] !== bullet.id)) {
  377. flag = false
  378. break
  379. }
  380. channel.operating[bullet.mode] = true
  381. if (channel.queue[bullet.mode].length > 0) {
  382. flag = false
  383. channel.operating[bullet.mode] = false
  384. break
  385. }
  386. channel.operating[bullet.mode] = false
  387. }
  388. if (flag) {
  389. pos = i
  390. break
  391. }
  392. }
  393. }
  394. if (pos !== -1) {
  395. for (let i = pos, max = pos + occupy; i < max; i++) {
  396. channel = channels[i]
  397. channel.operating[bullet.mode] = true
  398. channel.queue[bullet.mode].unshift(bullet)
  399. if (bullet.prior) {
  400. delete channel.bookId[bullet.mode]
  401. self.logger.info(i + '号轨道恢复正常使用')
  402. }
  403. channel.operating[bullet.mode] = false
  404. }
  405. if (bullet.prior) {
  406. self.logger.info(bullet.id + '号优先弹幕运行完毕')
  407. delete bullet['bookChannelId']
  408. if(danmu.player) {
  409. let dataList = danmu.bulletBtn.main.data
  410. dataList.some(function (item) {
  411. if (item.id === bullet.id) {
  412. delete item['bookChannelId']
  413. return true
  414. } else {
  415. return false
  416. }
  417. })
  418. }
  419. }
  420. bullet.channel_id = [pos, occupy]
  421. if(self.direction === 'b2t') {
  422. bullet.top = pos * channelWidth
  423. if (self.danmu.config.area && self.danmu.config.area.start) {
  424. bullet.top += self.containerWidth * self.danmu.config.area.start
  425. }
  426. } else {
  427. bullet.top = pos * channelHeight
  428. if (self.danmu.config.area && self.danmu.config.area.start) {
  429. bullet.top += self.containerHeight * self.danmu.config.area.start
  430. }
  431. }
  432. return {
  433. result: bullet,
  434. message: 'success'
  435. }
  436. } else {
  437. if (bullet.options.realTime) {
  438. // 找到应该被删的 danmu
  439. let start = 0
  440. let deleteIndex = -1
  441. let deleteItem = null
  442. self.danmu.bulletBtn.main.queue.forEach((item, index) => {
  443. if (item.el && item.el.getBoundingClientRect().right > self.containerPos.right && item.start >= start) {
  444. start = item.start
  445. deleteIndex = index
  446. deleteItem = item
  447. }
  448. })
  449. if (deleteItem) {
  450. // deleteItem.remove()
  451. // self.removeBullet(deleteItem)
  452. // self.danmu.bulletBtn.main.queue.splice(deleteIndex, 1)
  453. bullet.channel_id = deleteItem.channel_id
  454. for (let i = deleteItem.channel_id[0], max = deleteItem.channel_id[0] + deleteItem.channel_id[1]; i < max; i++) {
  455. channel = channels[i]
  456. channel.operating[bullet.mode] = true
  457. channel.queue[bullet.mode].unshift(bullet)
  458. if (bullet.prior) {
  459. delete channel.bookId[bullet.mode]
  460. }
  461. channel.operating[bullet.mode] = false
  462. }
  463. bullet.top = deleteItem.top
  464. if (self.danmu.config.area && self.danmu.config.area.start) {
  465. bullet.top += self.containerHeight * self.danmu.config.area.start
  466. }
  467. return {
  468. result: bullet,
  469. message: 'success'
  470. }
  471. }
  472. }
  473. if (bullet.prior) {
  474. if (!bullet.bookChannelId) {
  475. pos = -1
  476. for (let i = 0, max = channels.length - occupy; i <= max; i++) {
  477. flag = true
  478. for (let j = i; j < i + occupy; j++) {
  479. if (channels[j].bookId[bullet.mode]) {
  480. flag = false
  481. break
  482. }
  483. }
  484. if (flag) {
  485. pos = i
  486. break
  487. }
  488. }
  489. if (pos !== -1) {
  490. for (let j = pos; j < pos + occupy; j++) {
  491. channels[j].bookId[bullet.mode] = bullet.id
  492. self.logger.info(j + '号轨道被' + bullet.id + '号优先弹幕预定')
  493. }
  494. let nextAddTime = 2
  495. if(danmu.player) {
  496. let dataList = danmu.bulletBtn.main.data
  497. dataList.some(function (item) {
  498. if (item.id === bullet.id) {
  499. self.logger.info(bullet.id + '号优先弹幕将于' + nextAddTime + '秒后再次请求注册')
  500. item.start += nextAddTime * 1000
  501. item.bookChannelId = [pos, occupy]
  502. self.logger.info(`${bullet.id}号优先弹幕预定了${pos}~${pos + occupy - 1}号轨道`)
  503. return true
  504. } else {
  505. return false
  506. }
  507. })
  508. }
  509. }
  510. } else {
  511. let nextAddTime = 2
  512. if(danmu.player) {
  513. let dataList = danmu.bulletBtn.main.data
  514. dataList.some(function (item) {
  515. if (item.id === bullet.id) {
  516. self.logger.info(bullet.id + '号优先弹幕将于' + nextAddTime + '秒后再次请求注册')
  517. item.start += nextAddTime * 1000
  518. return true
  519. } else {
  520. return false
  521. }
  522. })
  523. }
  524. }
  525. }
  526. return {
  527. result: false,
  528. message: 'no surplus will right'
  529. }
  530. }
  531. }
  532. }
  533. removeBullet (bullet) {
  534. this.logger.info(`removeBullet ${bullet.options.txt || '[DOM Element]'}`)
  535. // console.log('removeBullet')
  536. let channels = this.channels
  537. let channelId = bullet.channel_id
  538. let channel
  539. for (let i = channelId[0], max = channelId[0] + channelId[1]; i < max; i++) {
  540. channel = channels[i]
  541. if (channel) {
  542. channel.operating[bullet.mode] = true
  543. let i = -1
  544. channel.queue[bullet.mode].some((item, index) => {
  545. if (item.id === bullet.id) {
  546. i = index
  547. return true
  548. } else {
  549. return false
  550. }
  551. })
  552. if (i > -1) {
  553. channel.queue[bullet.mode].splice(i, 1)
  554. }
  555. channel.operating[bullet.mode] = false
  556. }
  557. }
  558. if(bullet.options.loop) {
  559. this.danmu.bulletBtn.main.playedData.push(bullet.options)
  560. }
  561. }
  562. resetArea () {
  563. this.logger.info('resetArea')
  564. // console.log('resetArea')
  565. let container = this.danmu.container
  566. let self = this
  567. let size = container.getBoundingClientRect()
  568. self.width = size.width
  569. self.height = size.height
  570. if (self.danmu.config.area && self.danmu.config.area.start >= 0 && self.danmu.config.area.end >= self.danmu.config.area.start) {
  571. if(self.direction === 'b2t') {
  572. self.width = self.width * (self.danmu.config.area.end - self.danmu.config.area.start)
  573. } else {
  574. self.height = self.height * (self.danmu.config.area.end - self.danmu.config.area.start)
  575. }
  576. }
  577. self.container = container
  578. let fontSize =self.danmu.config.channelSize || (/mobile/ig.test(navigator.userAgent) ? 10 : 12)
  579. let channelSize
  580. if(self.direction === 'b2t') {
  581. channelSize = Math.floor(self.width / fontSize)
  582. } else {
  583. channelSize = Math.floor(self.height / fontSize)
  584. }
  585. let channels = []
  586. for (let i = 0; i < channelSize; i++) {
  587. channels[i] = {
  588. id: i,
  589. queue: {
  590. scroll: [],
  591. top: [],
  592. bottom: []
  593. },
  594. operating: {
  595. scroll: false,
  596. top: false,
  597. bottom: false
  598. },
  599. bookId: {}
  600. }
  601. }
  602. if (self.channels && self.channels.length <= channels.length) {
  603. for (let i = 0; i < self.channels.length; i++) {
  604. channels[i] = {
  605. id: i,
  606. queue: {
  607. scroll: [],
  608. top: [],
  609. bottom: []
  610. },
  611. operating: {
  612. scroll: false,
  613. top: false,
  614. bottom: false
  615. },
  616. bookId: {}
  617. };
  618. ['scroll', 'top'].forEach(key => {
  619. self.channels[i].queue[key].forEach(item => {
  620. if (item.el) {
  621. channels[i].queue[key].push(item)
  622. if(!item.resized) {
  623. item.pauseMove(self.containerPos, false)
  624. item.startMove(self.containerPos)
  625. item.resized = true
  626. }
  627. }
  628. })
  629. })
  630. self.channels[i].queue['bottom'].forEach(item => {
  631. if (item.el) {
  632. channels[i + channels.length - self.channels.length].queue['bottom'].push(item)
  633. if(item.channel_id[0] + item.channel_id[1] - 1 === i) {
  634. let channel_id = [].concat(item.channel_id)
  635. item.channel_id = [channel_id[0] - self.channels.length + channels.length, channel_id[1]]
  636. item.top = item.channel_id[0] * fontSize
  637. if (self.danmu.config.area && self.danmu.config.area.start) {
  638. item.top += self.containerHeight * self.danmu.config.area.start
  639. }
  640. item.topInit()
  641. }
  642. if(!item.resized) {
  643. item.pauseMove(self.containerPos, false)
  644. item.startMove(self.containerPos)
  645. item.resized = true
  646. }
  647. }
  648. })
  649. }
  650. for (let i = 0; i < channels.length; i++) {
  651. ['scroll', 'top', 'bottom'].forEach(key => {
  652. channels[i].queue[key].forEach(item => {
  653. // console.log('resized 重置:' + item)
  654. item.resized = false
  655. })
  656. })
  657. }
  658. self.channels = channels
  659. if(self.direction === 'b2t') {
  660. self.channelWidth = fontSize
  661. } else {
  662. self.channelHeight = fontSize
  663. }
  664. } else if (self.channels && self.channels.length > channels.length) {
  665. for (let i = 0; i < channels.length; i++) {
  666. channels[i] = {
  667. id: i,
  668. queue: {
  669. scroll: [],
  670. top: [],
  671. bottom: []
  672. },
  673. operating: {
  674. scroll: false,
  675. top: false,
  676. bottom: false
  677. },
  678. bookId: {}
  679. };
  680. ['scroll', 'top', 'bottom'].forEach(key => {
  681. if (key === 'top' && i > Math.floor(channels.length / 2)) {
  682. } else if (key === 'bottom' && i <= Math.floor(channels.length / 2)) {
  683. } else {
  684. let num = key === 'bottom' ? i - channels.length + self.channels.length : i
  685. self.channels[num].queue[key].forEach((item, index) => {
  686. if (item.el) {
  687. channels[i].queue[key].push(item)
  688. if(key === 'bottom') {
  689. if(item.channel_id[0] + item.channel_id[1] - 1 === num) {
  690. let channel_id = [].concat(item.channel_id)
  691. item.channel_id = [channel_id[0] - self.channels.length + channels.length, channel_id[1]]
  692. item.top = item.channel_id[0] * fontSize
  693. if (self.danmu.config.area && self.danmu.config.area.start) {
  694. item.top += self.containerHeight * self.danmu.config.area.start
  695. }
  696. item.topInit()
  697. }
  698. }
  699. if(!item.resized) {
  700. item.pauseMove(self.containerPos, false)
  701. item.startMove(self.containerPos)
  702. item.resized = true
  703. }
  704. }
  705. self.channels[num].queue[key].splice(index, 1)
  706. })
  707. }
  708. })
  709. }
  710. // for (let i = channels.length; i < self.channels.length; i++) {
  711. // ['scroll', 'top', 'bottom'].forEach(key => {
  712. // self.channels[i].queue[key].forEach(item => {
  713. // item.pauseMove(self.containerPos)
  714. // item.remove()
  715. // })
  716. // })
  717. // }
  718. for (let i = 0; i < channels.length; i++) {
  719. ['scroll', 'top', 'bottom'].forEach(key => {
  720. channels[i].queue[key].forEach(item => {
  721. // console.log('resized 重置:' + item)
  722. item.resized = false
  723. })
  724. })
  725. }
  726. self.channels = channels
  727. if(self.direction === 'b2t') {
  728. self.channelWidth = fontSize
  729. } else {
  730. self.channelHeight = fontSize
  731. }
  732. }
  733. }
  734. reset () {
  735. this.logger.info('reset')
  736. let container = this.danmu.container
  737. let self = this
  738. if (self.danmu.bulletBtn && self.danmu.bulletBtn.main) {
  739. self.danmu.bulletBtn.main.queue.forEach(item => {
  740. item.pauseMove(self.containerPos)
  741. item.remove()
  742. })
  743. }
  744. if (self.channels && self.channels.length > 0) {
  745. ['scroll', 'top', 'bottom'].forEach(key => {
  746. for (let i = 0; i < self.channels.length; i++) {
  747. self.channels[i].queue[key].forEach(item => {
  748. item.pauseMove(self.containerPos)
  749. item.remove()
  750. })
  751. }
  752. })
  753. }
  754. this.resetTimer = setTimeout(function () {
  755. let size = container.getBoundingClientRect()
  756. self.width = size.width
  757. self.height = size.height
  758. if (self.danmu.config.area && self.danmu.config.area.start >= 0 && self.danmu.config.area.end >= self.danmu.config.area.start) {
  759. if(self.direction === 'b2t') {
  760. self.width = self.width * (self.danmu.config.area.end - self.danmu.config.area.start)
  761. } else {
  762. self.height = self.height * (self.danmu.config.area.end - self.danmu.config.area.start)
  763. }
  764. }
  765. self.container = container
  766. let fontSize = self.danmu.config.channelSize || (/mobile/ig.test(navigator.userAgent) ? 10 : 12)
  767. let channelSize
  768. if(self.direction === 'b2t') {
  769. channelSize = Math.floor(self.width / fontSize)
  770. } else {
  771. channelSize = Math.floor(self.height / fontSize)
  772. }
  773. let channels = []
  774. for (let i = 0; i < channelSize; i++) {
  775. channels[i] = {
  776. id: i,
  777. queue: {
  778. scroll: [],
  779. top: [],
  780. bottom: []
  781. },
  782. operating: {
  783. scroll: false,
  784. top: false,
  785. bottom: false
  786. },
  787. bookId: {}
  788. }
  789. }
  790. self.channels = channels
  791. if(self.direction === 'b2t') {
  792. self.channelWidth = fontSize
  793. } else {
  794. self.channelHeight = fontSize
  795. }
  796. }, 200)
  797. }
  798. resetWithCb (cb, main) {
  799. this.logger.info('resetWithCb')
  800. let container = this.danmu.container
  801. let self = this
  802. if (self.channels && self.channels.length > 0) {
  803. ['scroll', 'top', 'bottom'].forEach(key => {
  804. for (let i = 0; i < self.channels.length; i++) {
  805. self.channels[i].queue[key].forEach(item => {
  806. item.pauseMove(self.containerPos)
  807. item.remove()
  808. })
  809. }
  810. })
  811. }
  812. let size = container.getBoundingClientRect()
  813. self.width = size.width
  814. self.height = size.height
  815. if (self.danmu.config.area && self.danmu.config.area.start >= 0 && self.danmu.config.area.end >= self.danmu.config.area.start) {
  816. if(self.direction === 'b2t') {
  817. self.width = self.width * (self.danmu.config.area.end - self.danmu.config.area.start)
  818. } else {
  819. self.height = self.height * (self.danmu.config.area.end - self.danmu.config.area.start)
  820. }
  821. }
  822. self.container = container
  823. let fontSize = self.danmu.config.channelSize || (/mobile/ig.test(navigator.userAgent) ? 10 : 12)
  824. let channelSize
  825. if(self.direction === 'b2t') {
  826. channelSize = Math.floor(self.width / fontSize)
  827. } else {
  828. channelSize = Math.floor(self.height / fontSize)
  829. }
  830. let channels = []
  831. for (let i = 0; i < channelSize; i++) {
  832. channels[i] = {
  833. id: i,
  834. queue: {
  835. scroll: [],
  836. top: [],
  837. bottom: []
  838. },
  839. operating: {
  840. scroll: false,
  841. top: false,
  842. bottom: false
  843. },
  844. bookId: {}
  845. }
  846. }
  847. self.channels = channels
  848. self.channelHeight = fontSize
  849. if (cb) {
  850. cb(true, main)
  851. }
  852. }
  853. }
  854. export default Channel