You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
543 lines
17 KiB
543 lines
17 KiB
exports.ids = [1]; |
|
exports.modules = { |
|
|
|
/***/ 153: |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
// style-loader: Adds some css to the DOM by adding a <style> tag |
|
|
|
// load the styles |
|
var content = __webpack_require__(159); |
|
if(content.__esModule) content = content.default; |
|
if(typeof content === 'string') content = [[module.i, content, '']]; |
|
if(content.locals) module.exports = content.locals; |
|
// add CSS to SSR context |
|
var add = __webpack_require__(5).default |
|
module.exports.__inject__ = function (context) { |
|
add("07fbb799", content, true, context) |
|
}; |
|
|
|
/***/ }), |
|
|
|
/***/ 158: |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
__webpack_require__.r(__webpack_exports__); |
|
/* harmony import */ var _node_modules_vue_style_loader_index_js_ref_3_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_3_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_3_oneOf_1_2_node_modules_nuxt_components_dist_loader_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Barrage_vue_vue_type_style_index_0_id_c3f32de4_lang_css_scoped_true___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(153); |
|
/* harmony import */ var _node_modules_vue_style_loader_index_js_ref_3_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_3_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_3_oneOf_1_2_node_modules_nuxt_components_dist_loader_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Barrage_vue_vue_type_style_index_0_id_c3f32de4_lang_css_scoped_true___WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_ref_3_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_3_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_3_oneOf_1_2_node_modules_nuxt_components_dist_loader_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Barrage_vue_vue_type_style_index_0_id_c3f32de4_lang_css_scoped_true___WEBPACK_IMPORTED_MODULE_0__); |
|
/* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _node_modules_vue_style_loader_index_js_ref_3_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_3_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_3_oneOf_1_2_node_modules_nuxt_components_dist_loader_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Barrage_vue_vue_type_style_index_0_id_c3f32de4_lang_css_scoped_true___WEBPACK_IMPORTED_MODULE_0__) if(["default"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _node_modules_vue_style_loader_index_js_ref_3_oneOf_1_0_node_modules_css_loader_dist_cjs_js_ref_3_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_3_oneOf_1_2_node_modules_nuxt_components_dist_loader_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_Barrage_vue_vue_type_style_index_0_id_c3f32de4_lang_css_scoped_true___WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__)); |
|
|
|
|
|
/***/ }), |
|
|
|
/***/ 159: |
|
/***/ (function(module, exports, __webpack_require__) { |
|
|
|
// Imports |
|
var ___CSS_LOADER_API_IMPORT___ = __webpack_require__(4); |
|
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false); |
|
// Module |
|
___CSS_LOADER_EXPORT___.push([module.i, ".z_barrage-container[data-v-c3f32de4]{pointer-events:none}.z_container[data-v-c3f32de4]{width:100%;overflow:hidden}.z_barrage[data-v-c3f32de4]{position:absolute;top:0;left:0}", ""]); |
|
// Exports |
|
module.exports = ___CSS_LOADER_EXPORT___; |
|
|
|
|
|
/***/ }), |
|
|
|
/***/ 174: |
|
/***/ (function(module, __webpack_exports__, __webpack_require__) { |
|
|
|
"use strict"; |
|
// ESM COMPAT FLAG |
|
__webpack_require__.r(__webpack_exports__); |
|
|
|
// CONCATENATED MODULE: ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/@nuxt/components/dist/loader.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Barrage.vue?vue&type=template&id=c3f32de4&scoped=true& |
|
var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"z_barrage-container"},[_vm._ssrNode("<canvas"+(_vm._ssrAttr("width",_vm.containerWidth))+(_vm._ssrAttr("height",_vm.containerHeight))+" style=\"display: none\" data-v-c3f32de4></canvas> <div class=\"z_container\""+(_vm._ssrStyle(null,{ height: _vm.containerHeight / 2 + 'px' }, null))+" data-v-c3f32de4><canvas id=\"canvas\""+(_vm._ssrAttr("width",_vm.containerWidth))+(_vm._ssrAttr("height",_vm.containerHeight))+" class=\"z_barrage\""+(_vm._ssrStyle(null,{ |
|
width: _vm.containerWidth / 2 + 'px', |
|
height: _vm.containerHeight / 2 + 'px' |
|
}, null))+" data-v-c3f32de4></canvas></div>")])} |
|
var staticRenderFns = [] |
|
|
|
|
|
// CONCATENATED MODULE: ./src/components/Barrage.vue?vue&type=template&id=c3f32de4&scoped=true& |
|
|
|
// CONCATENATED MODULE: ./node_modules/babel-loader/lib??ref--2-0!./node_modules/@nuxt/components/dist/loader.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/Barrage.vue?vue&type=script&lang=js& |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// |
|
// import faceMap from '../../assets/emoji' |
|
let aniId, aniId1; |
|
/* harmony default export */ var Barragevue_type_script_lang_js_ = ({ |
|
name: 'Barrage', |
|
props: { |
|
barrageList: { |
|
type: Array, |
|
default: () => [] |
|
}, |
|
speed: { |
|
type: Number, |
|
default: 4 |
|
}, |
|
loop: { |
|
type: Boolean, |
|
default: true |
|
}, |
|
channels: { |
|
type: Number, |
|
default: 2 |
|
}, |
|
barrageHeight: { |
|
type: Number, |
|
default: 60 |
|
}, |
|
screenPercent: { |
|
type: Number, |
|
default: 0.3 |
|
}, |
|
borderColor: { |
|
type: String, |
|
default: '' |
|
}, |
|
background: { |
|
type: String, |
|
default: '' |
|
}, |
|
deviceType: { |
|
type: String, |
|
default: 'pc' |
|
}, |
|
linearGradient: { |
|
type: Object, |
|
default: () => { |
|
return { |
|
startColor: '', |
|
endColor: '' |
|
}; |
|
} |
|
} |
|
}, |
|
|
|
data() { |
|
return { |
|
newBarrageArray: [], |
|
// 新增弹幕之后的总弹幕 |
|
barrageArray: [], |
|
barrageQueue: [], |
|
containerWidth: 0, |
|
containerHeight: 0, |
|
channelsArray: [], |
|
barrageChannels: 1 |
|
}; |
|
}, |
|
|
|
watch: { |
|
barrageList(val) { |
|
if (val.length !== 0) { |
|
this.barrageQueue = JSON.parse(JSON.stringify(val)); |
|
this.newBarrageArray = JSON.parse(JSON.stringify(val)); |
|
this.initData(); |
|
window.cancelAnimationFrame(aniId); |
|
aniId = window.requestAnimationFrame(this.render); |
|
} |
|
} |
|
|
|
}, |
|
|
|
mounted() { |
|
this.containerWidth = this.deviceType === 'pc' ? 723 * 2 : document.body.clientWidth * 2; |
|
this.containerHeight = 365 * 2; // 设定总高度 |
|
|
|
this.barrageChannels = this.channels; // 总高度对应的轨道数 |
|
|
|
this.ctx = this.$refs.canvas.getContext('2d'); |
|
this.ctx1 = this.$refs.canvasContainer.getContext('2d'); |
|
this.barrageClickEvent(); |
|
}, |
|
|
|
methods: { |
|
/** |
|
* 数据初始化 |
|
*/ |
|
initData() { |
|
for (let i = 0; i < this.barrageQueue.length; i++) { |
|
// 此处处理只显示50个字符 |
|
let tagImg = null; |
|
let img = null; |
|
|
|
if (this.barrageQueue[i].icon) { |
|
img = new Image(); |
|
img.src = this.barrageQueue[i].icon; |
|
} |
|
|
|
if (this.barrageQueue[i].tagImage) { |
|
tagImg = new Image(); |
|
tagImg.src = this.barrageQueue[i].tagImage; |
|
} |
|
|
|
const content = this.dealStr(this.barrageQueue[i].content); |
|
this.barrageArray.push({ |
|
id: this.barrageQueue[i].id, |
|
content, |
|
x: this.containerWidth + this.barrageHeight, |
|
icon: img, |
|
tagImage: tagImg, |
|
width: this.ctx1.measureText(content).width * 3.6 + (this.barrageQueue[i].icon ? 60 : 0), |
|
color: this.barrageQueue[i].color || '#FFFFFF', |
|
bgColor: this.barrageQueue[i].bgColor || 'rgba(0,0,0,0.4)' |
|
}); |
|
} |
|
|
|
this.initChannel(); |
|
}, |
|
|
|
/** |
|
* 初始化轨道数据 |
|
*/ |
|
initChannel() { |
|
for (let i = 0; i < this.barrageChannels; i++) { |
|
const item = this.barrageArray.shift(); |
|
|
|
if (item) { |
|
this.channelsArray[i] = [item]; |
|
} else { |
|
this.channelsArray[i] = []; |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* 渲染 |
|
*/ |
|
render() { |
|
this.ctx.clearRect(0, 0, this.containerWidth, this.containerHeight); |
|
this.ctx.font = '36px Microsoft YaHei'; |
|
this.draw(); |
|
window.cancelAnimationFrame(aniId1); |
|
aniId1 = window.requestAnimationFrame(this.render); |
|
}, |
|
|
|
draw() { |
|
for (let i = 0; i < this.channelsArray.length; i++) { |
|
for (let j = 0; j < this.channelsArray[i].length; j++) { |
|
try { |
|
const barrage = this.channelsArray[i][j]; |
|
barrage.x -= this.speed; |
|
|
|
if (barrage.x <= this.containerWidth) { |
|
// 弹幕显示 |
|
this.borderColor && this.drawRoundRectBorder(this.ctx, barrage.x - this.barrageHeight / 2, i * (this.barrageHeight + 60) + 20, barrage.width + this.barrageHeight, this.barrageHeight, this.barrageHeight / 2); |
|
this.drawRoundRect(this.ctx, barrage.bgColor, barrage.x - this.barrageHeight / 2, i * (this.barrageHeight + 60) + 21, barrage.width + this.barrageHeight, this.barrageHeight - 2, this.barrageHeight / 2); |
|
this.ctx.fillStyle = `${barrage.color}`; |
|
this.ctx.fillText(barrage.content, barrage.x + (barrage.icon ? this.barrageHeight / 2 + 10 : -5), i * (this.barrageHeight + 60) + this.barrageHeight - 25); |
|
|
|
if (barrage.icon) { |
|
this.circleImg(this.ctx, barrage.icon, barrage.x - 40, i * (this.barrageHeight + 60) + 40, 40); |
|
} |
|
|
|
if (barrage.tagImage) { |
|
this.originImg(this.ctx, barrage.tagImage, barrage.x - this.barrageHeight - 10, i * (this.barrageHeight + 60) + 20, this.barrageHeight, this.barrageHeight); |
|
} |
|
} |
|
|
|
if (barrage.x < -(barrage.width + this.barrageHeight)) { |
|
// 弹幕删除 |
|
const arr = this.channelsArray.reduce((a, b) => a.concat(b)); |
|
|
|
if (this.loop) { |
|
if (this.checkBarrageStatus(arr)) { |
|
this.barrageQueue = []; |
|
this.barrageQueue = JSON.parse(JSON.stringify(this.newBarrageArray)); |
|
this.initData(); |
|
} |
|
} |
|
} // 弹幕插入时机判断 |
|
|
|
|
|
if (barrage.x <= Math.floor(this.containerWidth - barrage.width - 40) && barrage.x >= Math.floor(this.containerWidth - barrage.width - 40 - this.speed) && j === this.channelsArray[i].length - 1 && this.barrageArray.length !== 0) { |
|
const item = this.barrageArray.shift(); |
|
this.channelsArray[i].push(item); |
|
} |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* 重置数据 |
|
*/ |
|
add(obj) { |
|
const content = this.dealStr(obj.content); |
|
let img = null; |
|
let tagImg = null; |
|
|
|
if (obj.icon) { |
|
img = new Image(); |
|
img.src = obj.icon; |
|
} |
|
|
|
if (obj.tagImage) { |
|
tagImg = new Image(); |
|
tagImg.src = obj.tagImage; |
|
} |
|
|
|
const item = { |
|
id: obj.id, |
|
content, |
|
x: this.containerWidth + this.barrageHeight, |
|
icon: obj.icon ? img : '', |
|
tagImage: obj.tagImage ? tagImg : '', |
|
width: this.ctx1.measureText(content).width * 3 + (obj.icon ? this.barrageHeight : 0), |
|
color: obj.color || '#FFFFFF', |
|
bgColor: obj.bgColor || 'rgba(0,0,0,0.4)' |
|
}; |
|
const originItem = { |
|
id: obj.id, |
|
content: obj.content, |
|
icon: obj.icon, |
|
tagImage: obj.tagImage, |
|
color: obj.color || '#FFFFFF', |
|
bgColor: obj.bgColor || 'rgba(0,0,0,0.4)' |
|
}; |
|
|
|
if (this.barrageArray.length === 0) { |
|
// 剩余弹幕数为0 |
|
this.newBarrageArray.unshift(originItem); |
|
} else { |
|
this.barrageArray.unshift(item); |
|
const insertIndex = this.barrageList.length - this.barrageArray.length; |
|
this.newBarrageArray.splice(insertIndex, 0, originItem); |
|
} |
|
}, |
|
|
|
/** |
|
* 弹幕点击事件 |
|
*/ |
|
barrageClickEvent() { |
|
document.getElementById('canvas').addEventListener('click', e => { |
|
const p = this.getEventPosition(e); |
|
const channelIndex = Math.floor(p.y / (this.barrageHeight + 36)); |
|
const tempArray = JSON.parse(JSON.stringify(this.channelsArray[channelIndex])); |
|
|
|
for (let i = 0; i < tempArray.length; i++) { |
|
const channelItemArray = tempArray[i]; |
|
|
|
if (p.x > channelItemArray.x && p.x < channelItemArray.x + channelItemArray.width) { |
|
if (channelItemArray.id) { |
|
this.$emit('doLike', channelItemArray.id); |
|
} |
|
} |
|
} |
|
}, false); |
|
}, |
|
|
|
/** |
|
* 获取点击位置 |
|
*/ |
|
getEventPosition(ev) { |
|
let x, y; |
|
|
|
if (ev.layerX || ev.layerX === 0) { |
|
x = ev.layerX; |
|
y = ev.layerY; |
|
} else if (ev.offsetX || ev.offsetX === 0) { |
|
x = ev.offsetX; |
|
y = ev.offsetY; |
|
} |
|
|
|
return { |
|
x: 2 * x, |
|
y: 2 * y |
|
}; |
|
}, |
|
|
|
/** |
|
* 判断所有的弹幕是否滚动完成 |
|
* @params arr |
|
*/ |
|
checkBarrageStatus(arr) { |
|
for (let i = 0; i < arr.length; i++) { |
|
if (arr[i].x > -arr[i].width) return false; |
|
} |
|
|
|
return true; |
|
}, |
|
|
|
/** |
|
* 处理字符 |
|
*/ |
|
dealStr(str) { |
|
return str.length > 50 ? `${str.substring(0, 50)}...` : str; |
|
}, |
|
|
|
/** |
|
* 获取随机颜色 |
|
*/ |
|
getColor() { |
|
return `#${Math.floor(Math.random() * 16777215).toString(16)}`; |
|
}, |
|
|
|
/** |
|
* 裁剪图片 |
|
* @param ctx |
|
* @param img |
|
* @param x |
|
* @param y |
|
* @param r |
|
*/ |
|
circleImg(ctx, img, x, y, r) { |
|
ctx.save(); |
|
const d = 2 * r; |
|
const cx = x + r; |
|
const cy = y + r; |
|
ctx.beginPath(); |
|
ctx.arc(cx, cy, r, 0, 2 * Math.PI); |
|
ctx.clip(); |
|
ctx.drawImage(img, x, y, d, d); |
|
ctx.restore(); |
|
ctx.closePath(); |
|
}, |
|
|
|
/** |
|
* 绘制原始图片 |
|
* @param ctx |
|
* @param img |
|
* @param x |
|
* @param y |
|
* @param width |
|
* @param height |
|
*/ |
|
originImg(ctx, img, x, y, width, height) { |
|
try { |
|
ctx.beginPath(); |
|
ctx.drawImage(img, x, y, width, height); |
|
ctx.closePath(); |
|
} catch (e) { |
|
console.log(e); |
|
} |
|
}, |
|
|
|
/** |
|
* 绘画圆角矩形 |
|
* @param context |
|
* @param bgColor |
|
* @param x |
|
* @param y |
|
* @param width |
|
* @param height |
|
* @param radius |
|
*/ |
|
drawRoundRect(context, bgColor, x, y, width, height, radius) { |
|
if (this.linearGradient.startColor && this.linearGradient.endColor) { |
|
const linearGrad = context.createLinearGradient(x, y, x, y + height); |
|
linearGrad.addColorStop(0, this.linearGradient.startColor); |
|
linearGrad.addColorStop(1, this.linearGradient.endColor); |
|
context.fillStyle = linearGrad || bgColor; |
|
} else { |
|
context.fillStyle = this.background || bgColor; |
|
} |
|
|
|
context.beginPath(); |
|
context.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); |
|
context.lineTo(width - radius + x, y); |
|
context.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2); |
|
context.lineTo(width + x, height + y - radius); |
|
context.arc(width - radius + x, height - radius + y, radius, 0, Math.PI / 2); |
|
context.lineTo(radius + x, height + y); |
|
context.arc(radius + x, height - radius + y, radius, Math.PI / 2, Math.PI); |
|
context.fill(); |
|
context.closePath(); |
|
}, |
|
|
|
/** |
|
* 绘画圆角矩形 |
|
* @param context |
|
* @param x |
|
* @param y |
|
* @param width |
|
* @param height |
|
* @param radius 半径 |
|
*/ |
|
drawRoundRectBorder(context, x, y, width, height, radius) { |
|
context.beginPath(); |
|
context.lineWidth = 2; |
|
context.strokeStyle = this.borderColor; |
|
context.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2); |
|
context.lineTo(width - radius + x, y); |
|
context.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2); |
|
context.lineTo(width + x, height + y - radius); |
|
context.arc(width - radius + x, height - radius + y, radius, 0, Math.PI / 2); |
|
context.lineTo(radius + x, height + y); |
|
context.arc(radius + x, height - radius + y, radius, Math.PI / 2, Math.PI); |
|
context.stroke(); |
|
context.closePath(); |
|
} |
|
|
|
} |
|
}); |
|
// CONCATENATED MODULE: ./src/components/Barrage.vue?vue&type=script&lang=js& |
|
/* harmony default export */ var components_Barragevue_type_script_lang_js_ = (Barragevue_type_script_lang_js_); |
|
// EXTERNAL MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js |
|
var componentNormalizer = __webpack_require__(1); |
|
|
|
// CONCATENATED MODULE: ./src/components/Barrage.vue |
|
|
|
|
|
|
|
function injectStyles (context) { |
|
|
|
var style0 = __webpack_require__(158) |
|
if (style0.__inject__) style0.__inject__(context) |
|
|
|
} |
|
|
|
/* normalize component */ |
|
|
|
var component = Object(componentNormalizer["a" /* default */])( |
|
components_Barragevue_type_script_lang_js_, |
|
render, |
|
staticRenderFns, |
|
false, |
|
injectStyles, |
|
"c3f32de4", |
|
"61721d3f" |
|
|
|
) |
|
|
|
/* harmony default export */ var Barrage = __webpack_exports__["default"] = (component.exports); |
|
|
|
/***/ }) |
|
|
|
};; |
|
//# sourceMappingURL=barrage.js.map
|