当前位置: 首页 > news >正文

uniapp小程序实现弹幕不重叠

uniapp小程序实现弹幕不重叠

1、在父组件中引入弹幕组件

<template><!-- 弹幕 --><barrage ref="barrage" class="barrage-content" @reloadDanmu="reloadDanmu"></barrage>
</template>
<script>import barrage from './components/barrage.vue'import {getBarrageListApi} from '@/api/voteApi.js'export default {components: {barrage},data() {return {danmuList: [], // 弹幕列表danmuContion: { // 弹幕查询条件page: 1,size: 200}},onLoad(){this.getBarrageList()},methods: {async getBarrageList(isInit) {try {let res = await getBarrageListApi(this.danmuContion)let resData = (res && res.data) || {}let list = Array.isArray(resData.records) ? resData.records : []list.map((item) => {item.color = '#fff'item.timestampt = new Date().getTime()item.image = {head: {src: item.avatarUrl,width: 44,height: 44}, // 弹幕头部添加图片gap: 8 // 图片与文本间隔}item.content = `{${item.nickname}} 已为《${item.voteName}》投下宝贵的一票`})let danmuLength = this.danmuList.lengththis.danmuList = listthis.addBarrage(isInit || danmuLength === 0)} catch (e) {uni.showToast({title: (e && e.message) || '查询弹幕列表失败',icon: 'none',during: 2000})}},addBarrage(isInit) {if (!isInit || !this.danmuList.length) {return}const barrageComp = this.$refs && this.$refs.barrage || {}barrageComp.getBarrageInstance({duration: 15, // 弹幕动画时长 (移动 1500px 所需时长)lineHeight: 2.4, // 弹幕行高padding: [0, 0, 0, 0], // 弹幕区四周留白alpha: 1, // 全局透明度font: '10px PingFang SC', // 全局字体range: [0, 1], // 弹幕显示的垂直范围,支持两个值。[0,1]表示弹幕整个随机分布,tunnelShow: false, // 显示轨道线tunnelMaxNum: 200, // 隧道最大缓冲长度maxLength: 5000, // 弹幕最大字节长度,汉字算双字节safeGap: 20, // 发送时的安全间隔enableTap: false, // 点击弹幕停止动画高亮显示danmuList: this.danmuList})},async reloadDanmu(type) {const barrageComp = this.$refs && this.$refs.barrage || {}if(type === 'addDanmu') {await this.getBarrageList(false)barrageComp.open()barrageComp.addData(this.danmuList)return}await this.getBarrageList(true)}, }
</script><style lang="less" scoped>.barrage-conten {width: 100%;height: 156rpx;position: absolute;top: 192rpx;box-sizing: border-box;}
</style>

2、弹幕组件

 <template><view class="barrage-area" :style="{'opacity': alpha, 'font-size': fontSize*2 + 'rpx', 'padding': padding}"><block v-for="(tunnel, tunnelId) in tunnels" :key="tunnelId"><view class="barrage-tunnel":style="{'height': tunnel.height*2 + 'rpx', 'border-top-width': (tunnelShow ? 1 : 0) + 'px'}"><view class="tunnel-tips" :style="{'display': !tunnelShow ? 'none' : 'block'}">轨道{{tunnelId}}</view><block v-for="(bullet, bulletId) in tunnel.bullets" :key="bullet.timestampt + bulletId"><view :data-tunnelid="{tunnelId}" :data-bulletid="{bulletId}":class="['bullet-item', bullet.duration > 0 ? 'bullet-move' : '', bullet.paused ? 'paused' : '']":style="{'color': bullet.paused ? '#fff' : bullet.color, 'line-height': tunnel.height*2 + 'rpx', 'animation-duration': bullet.duration + 's', 'animation-play-state': bullet.paused ? 'paused' : 'running'}"@animationend="onAnimationend" @tap="onTapBullet"><image class="bullet-item_img" v-if="bullet.image && bullet.image.head":style="{'width': bullet.image.head.width + 'rpx', 'height': bullet.image.head.height + 'rpx'}"mode="aspectFill" :src="bullet.image.head.src"></image><view class="bullet-item_text":style="{'margin':'0 ' + (bullet.image && bullet.image.gap || 0) + 'rpx', opacity: 1}"><text>{{bullet.content}}</text></view></view></block></view></block></view>
</template><script>export default {data() {return {fontSize: 10, // 字体大小,单位pxwidth: 375, // 弹幕区域宽度height: 80, // 弹幕区域高度duration: 15, // 弹幕动画时长lineHeight: 3, // 弹幕行高padding: [0, 0, 0, 0], // 弹幕区四周留白alpha: 1, // 全局透明度font: '10px PingFang SC', // 全局字体range: [0, 1], // 弹幕显示的垂直范围,支持两个值。[0,1]表示弹幕整个随机分布,tunnelShow: false, // 显示轨道线tunnelMaxNum: 200, // 轨道最大缓冲长度maxLength: 5000, // 弹幕最大字节长度,汉字算双字节safeGap: 20, // 发送时的安全间隔enableTap: false, // 点击弹幕停止动画高亮显示tunnelHeight: 0,tunnelNum: 0,tunnels: [],idleTunnels: null,enableTunnels: {},distance: 1500, // 移动距离, 单位pxsystemInfo: {},danmuList: []};},methods: {init() {this.fontSize = this.getFontSize(this.font)this.idleTunnels = new Set()this.enableTunnels = new Set()this.tunnels = []this.availableHeight = (this.height - this.padding[0] - this.padding[2])this.tunnelHeight = this.fontSize * this.lineHeight// 轨道行数 = 弹幕区域高度/(单个弹幕高度+下边距)this.tunnelNum = Math.floor(this.availableHeight / (this.tunnelHeight + 15))// tunnel(轨道)class Tunnel {constructor(opt = {}) {const defaultTunnelOpt = {tunnelId: 0,height: 0, // 轨道高度width: 0, // 轨道宽度safeGap: 4, // 相邻弹幕安全间隔maxNum: 10, // 缓冲队列长度bullets: [], // 弹幕last: -1, // 上一条发送的弹幕序号bulletStatus: [], // 0 空闲,1 占用中disabled: false, // 禁用中sending: false, // 弹幕正在发送}Object.assign(this, defaultTunnelOpt, opt)this.bulletStatus = new Array(this.maxNum).fill(0)class Bullet {constructor(opt = {}) {this.bulletId = opt.bulletId}/*** image 结构* {*   head: {src, width, height},*   gap: 4 // 图片与文本间隔* }*/addContent(opt = {}) {const defaultBulletOpt = {duration: 0, // 动画时长passtime: 0, // 弹幕穿越右边界耗时content: '', // 文本color: '#000000', // 默认黑色width: 0, // 弹幕宽度height: 0, // 弹幕高度image: {}, // 图片paused: false // 是否暂停}Object.assign(this, defaultBulletOpt, opt)}removeContent() {this.addContent({})}}for (let i = 0; i < this.maxNum; i++) {this.bullets.push(new Bullet({bulletId: i,}))}}disable() {this.disabled = truethis.last = -1this.sending = falsethis.bulletStatus = new Array(this.maxNum).fill(1)this.bullets.forEach(bullet => bullet.removeContent())}enable() {if (this.disabled) {this.bulletStatus = new Array(this.maxNum).fill(0)}this.disabled = false}clear() {this.last = -1this.sending = falsethis.bulletStatus = new Array(this.maxNum).fill(0)this.bullets.forEach(bullet => bullet.removeContent())}getIdleBulletIdx() {return this.bulletStatus.indexOf(0)}getIdleBulletNum() {let count = 0this.bulletStatus.forEach(status => {if (status === 0) count++})return count}addBullet(opt) {if (this.disabled) returnconst idx = this.getIdleBulletIdx()if (idx >= 0) {this.bulletStatus[idx] = 1this.bullets[idx].addContent(opt)}}removeBullet(bulletId) {if (this.disabled) returnthis.bulletStatus[bulletId] = 0const bullet = this.bullets[bulletId]bullet.removeContent()}}for (let i = 0; i < this.tunnelNum; i++) {this.idleTunnels.add(i) // 空闲的轨道id集合this.enableTunnels.add(i) // 可用的轨道id集合this.tunnels.push(new Tunnel({ // 轨道集合width: this.width,height: this.tunnelHeight,safeGap: this.safeGap,maxNum: this.tunnelMaxNum,tunnelId: i,}))}// 筛选符合范围的轨道this.setRange()},resize() {const query = uni.createSelectorQuery().in(this)query.select('.barrage-area').boundingClientRect((res) => {res = res || {}let systemInfo = uni.getSystemInfoSync()this.systemInfo = systemInfo || {}this.width = res.width || systemInfo.windowWidththis.height = res.height || 300this.last = -1this.$emit('reloadDanmu')}).exec()},// 设置显示范围 range: [0,1]setRange(range) {range = range || this.rangeconst top = range[0] * this.tunnelNumconst bottom = range[1] * this.tunnelNum// 释放符合要求的轨道// 找到目前空闲的轨道const idleTunnels = new Set()const enableTunnels = new Set()this.tunnels.forEach((tunnel, tunnelId) => {if (tunnelId >= top && tunnelId < bottom) {const disabled = tunnel.disabledtunnel.enable()enableTunnels.add(tunnelId)if (disabled || this.idleTunnels.has(tunnelId)) {idleTunnels.add(tunnelId)}} else {tunnel.disable()}})this.idleTunnels = idleTunnelsthis.enableTunnels = enableTunnelsthis.range = range},setFont(font) {this.font = font},setAlpha(alpha) {if (typeof alpha !== 'number') returnthis.alpha = alpha},setDuration(duration) {if (typeof duration !== 'number') returnthis.duration = durationthis.clear()},// 开启弹幕open() {this._isActive = true},// 关闭弹幕,清除所有数据close(cb) {this._isActive = falsethis.clear(cb)},clear(cb) {this.tunnels.forEach(tunnel => tunnel.clear())this.idleTunnels = new Set(this.enableTunnels)if (typeof cb === 'function') {cb()}},// 添加一批弹幕,轨道满时会被丢弃addData(data = []) {if (!this._isActive || !data || !data.length) returndata.forEach((item, index) => {item.timestampt = new Date().getTime()item.content = item.content || ''item.content = this.substring(item.content, this.maxLength)if (!item.width) {// 一个弹幕总长度=头像(包含边框)+文本+内边距+外边距item.width = (44 + 4) + item.content.length * this.fontSize * 2 + (8 + 20) + 60item.width = Math.ceil(((this.systemInfo.windowWidth || 375) / 375) * (item.width / 2))}this.addBullet2Tunnel(item, index)})// 更新弹幕this.updateBullets()},// 添加至轨道addBullet2Tunnel(opt = {}, index) {const tunnel = this.getIdleTunnel(index)if (tunnel === null) returnconst tunnelId = tunnel.tunnelIdtunnel.addBullet(opt)if (tunnel.getIdleBulletNum() === 0) {this.idleTunnels.delete(tunnelId)}},updateBullets() {if (!this.tunnels || !this.tunnels.length) {return}this.tunnels.map((a) => {a.batchTime = 0 // 通过一批弹幕花费(即一次addData添加的所有弹幕)的时间a.lastBulletIndex = a.lastBulletIndex >= 0 ? a.lastBulletIndex : -1 // 轨道最后通过的弹幕下标a.bullets && a.bullets.map((b, bIndex) => {if ((a.lastBulletIndex === -1 || bIndex > a.lastBulletIndex) && b.content) {a.lastBulletIndex = bIndexconst duration = this.distance * this.duration / (this.distance + b.width)const passDistance = b.width + a.safeGap// 等上一条通过右边界b.passtime1 = Math.ceil(passDistance * this.duration * 1000 / this.distance)a.batchTime += b.passtime1}})this.tunnelAnimate(a)})let list = JSON.parse(JSON.stringify(this.tunnels))list.sort((a, b) => {return b.batchTime - a.batchTime})let lastBullet = list[0].bullets[list[0].lastBulletIndex]// 最后一条弹幕通过屏幕的时间let lastPassTime = list[0].batchTime + Math.ceil((this.width) * this.duration * 1000 / this.distance)console.log('最后一条弹幕通过屏幕的时间:', lastPassTime)let reloadDanmuTimer = setTimeout(() => {// 轨道已满,重置轨道并重新加载弹幕if (!this.idleTunnels || this.idleTunnels.size === 0) {this.last = -1this.$emit('reloadDanmu')} else {this.$emit('reloadDanmu', 'addDanmu')}clearTimeout(reloadDanmuTimer)}, lastPassTime)},tunnelAnimate(tunnel) {if (tunnel.disabled || tunnel.sending) returnconst next = (tunnel.last + 1) % tunnel.maxNumconst bullet = tunnel.bullets[next]if (!bullet) returnif (bullet.content || bullet.image) {tunnel.sending = truetunnel.last = nextconst duration = this.distance * this.duration / (this.distance + bullet.width)const passDistance = bullet.width + tunnel.safeGapbullet.duration = this.duration// 等上一条通过右边界bullet.passtime = Math.ceil(passDistance * bullet.duration * 1000 / this.distance)let sendTimer = setTimeout(() => {tunnel.sending = falsethis.tunnelAnimate(tunnel)clearTimeout(sendTimer)}, bullet.passtime)}},// 从还有余量的轨道中随机挑选一个getIdleTunnel(addIndex) {if (!this.idleTunnels || this.idleTunnels.size === 0) return nullconst idleTunnels = Array.from(this.idleTunnels)let index = -1if (this.tunnelNum == 2 && (addIndex || addIndex === 0)) { // 只有两个轨道的情况下,优先手动分发轨道index = addIndex % 2 === 0 ? 0 : 1}if (index === -1 || (!idleTunnels[index] && idleTunnels[index] !== 0)) { // 随机选轨道index = this.getRandom(idleTunnels.length)}return this.tunnels[idleTunnels[index]]},animationend(opt) {const {tunnelId,bulletId} = optconst tunnel = this.tunnels[tunnelId]const bullet = tunnel && tunnel.bullets && tunnel.bullets[bulletId]if (!tunnel || !bullet) returntunnel.removeBullet(bulletId)this.idleTunnels.add(tunnelId)},tapBullet(opt) {if (!this.enableTap) returnconst {tunnelId,bulletId} = optconst tunnel = this.tunnels[tunnelId]const bullet = tunnel.bullets[bulletId]bullet.paused = !bullet.paused},// 初始化弹幕组件数据getBarrageInstance(opt) {for (let key in opt) {this[key] = opt[key]}const query = uni.createSelectorQuery().in(this)query.select('.barrage-area').boundingClientRect((res) => {res = res || {}let systemInfo = uni.getSystemInfoSync()this.systemInfo = systemInfo || {}this.width = res.width || systemInfo.windowWidththis.height = res.height || 80this.init()this.open()this.addData(this.danmuList)}).exec()},onAnimationend(e) {const {tunnelid,bulletid} = e.currentTarget.datasetthis.animationend({tunnelId: tunnelid,bulletId: bulletid})},onTapBullet(e) {const {tunnelid,bulletid} = e.currentTarget.datasetthis.tapBullet({tunnelId: tunnelid,bulletId: bulletid})},// 获取字节长度,中文算2个字节getStrLen(str) {// eslint-disable-next-line no-control-regexreturn str.replace(/[^\x00-\xff]/g, 'aa').length},// 截取指定字节长度的子串substring(str, n) {if (!str) return ''const len = this.getStrLen(str)if (n >= len) return strlet l = 0let result = ''for (let i = 0; i < str.length; i++) {const ch = str.charAt(i)// eslint-disable-next-line no-control-regexl = /[^\x00-\xff]/i.test(ch) ? l + 2 : l + 1result += chif (l >= n) break}return result},getRandom(max = 10, min = 0) {return Math.floor(Math.random() * (max - min) + min)},getFontSize(font) {const reg = /(\d+)(px)/iconst match = font.match(reg)return (match && match[1]) || 10},}}
</script><style scoped>.barrage-area {position: relative;box-sizing: border-box;width: 100%;height: 100%;z-index: 2;pointer-events: auto;overflow-x: hidden;}.barrage-tunnel {box-sizing: border-box;position: relative;display: flex;align-items: center;border-top: 1px solid #CCB24D;width: 100%;margin-bottom: 30rpx;}.tunnel-tips {display: inline-block;margin-left: 60px;}.bullet-item {position: absolute;display: flex;align-items: center;top: 0;left: 100%;white-space: nowrap;background: rgba(0, 0, 0, 0.3);border-radius: 80rpx;padding: 0 20rpx 0 0;}.bullet-item.paused {background: #000;opacity: 0.6;padding: 0 10px;z-index: 2;}.bullet-item_img {max-height: 100%;border-radius: 50%;border: 2px solid #FFFFFF;}.bullet-item_text {display: inline-block;margin: 0;}.bullet-move {animation: 0s linear slidein}@keyframes slidein {0% {transform: translate3d(0, 0, 0)}100% {transform: translate3d(-1500px, 0, 0)}}
</style>

相关文章:

uniapp小程序实现弹幕不重叠

uniapp小程序实现弹幕不重叠 1、在父组件中引入弹幕组件 <template><!-- 弹幕 --><barrage ref"barrage" class"barrage-content" reloadDanmu"reloadDanmu"></barrage> </template> <script>import barr…...

拼多多纠偏,能否实现买卖平权?

科技新知 原创作者丨江蓠 编辑丨蕨影 当曾将仅退款、运费险作为标配的电商平台们开始听到商家诉求&#xff0c;有意优化营商环境&#xff0c;作为“仅退款”服务发起者的拼多多也坐不住了。 在推出一揽子减免计划讨好中小商家之后&#xff0c;拼多多近期被传正在内测精选用户…...

【Leetcode】3159. 查询数组中元素的出现位置

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接&#x1f517; 给你一个整数数组 nums &#xff0c;一个整数数组 queries 和一个整数 x 。 对于每个查询 q u e r i e s [ i ] queries[i] queries[i] &#xff0c;你需要找到 n u m s nums nu…...

PHP语言laravel框架中基于Redis的异步队列使用实践与原理

在 Laravel 中&#xff0c;基于 Redis 的异步队列是通过 Laravel 的队列系统与 Redis 服务结合来实现的。这种队列机制允许你将任务推送到队列中&#xff0c;并由后台工作进程异步处理这些任务。这样&#xff0c;你就可以将耗时的操作&#xff08;如发送邮件、处理视频、数据同…...

Element-plus自动导入

安装 npm i element-plus 自动引入 1. 安装两个插件 npm install -D unplugin-vue-components unplugin-auto-import2. 配置插件 vue3项目修改vite.config.js&#xff0c;把两个插件添加入即可&#xff0c;注意:不是覆盖原有配置 Vite // vite.config.js import { define…...

贪心算法(常见贪心模型)

常见贪心模型 简单排序模型 最小化战斗力差距 题目分析&#xff1a; #include <bits/stdc.h> using namespace std;const int N 1e5 10;int n; int a[N];int main() {// 请在此输入您的代码cin >> n;for (int i 1;i < n;i) cin >> a[i];sort(a1,a1n);…...

碰一碰发视频后端源码技术开发详解,支持OEM

一、引言 碰一碰发视频作为一种新颖的交互方式&#xff0c;在前端为用户带来便捷体验的同时&#xff0c;后端技术起着至关重要的支撑作用。后端负责管理视频资源、处理 NFC 标签信息与视频的关联逻辑、用户数据的存储与分析以及与前端的高效通信&#xff0c;确保整个系统稳定、…...

Python vs PHP:哪种语言更适合网页抓取

本文将比较 Python 和 PHP&#xff0c;以帮助读者确定哪种语言更适合他们的需求。文章将探讨两种语言的优点和缺点&#xff0c;并根据读者的经验水平分析哪种语言可能更容易上手。接下来&#xff0c;文章将深入探讨哪种语言在抓取网页数据方面更胜一筹。 简而言之&#xff0c;…...

SpringBoot 新特性

优质博文&#xff1a;IT-BLOG-CN 2.1.0新特性最低支持jdk8,支持tomcat9 对响应式编程的支持&#xff0c;spring-boot-starter-webflux starter POM可以快速开始使用Spring WebFlux&#xff0c;它由嵌入式Netty服务器支持 1.5.8 2.1.0/2.7.0/3.0.0 Configuration propertie…...

NAT 技术如何解决 IP 地址短缺问题?

NAT 技术如何解决 IP 地址短缺问题&#xff1f; 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 随着互联网的普及和发展&#xff0c;IP 地址的需求量迅速增加。尤其是 IPv4 地址&…...

微积分复习(微分方程)

1,一阶微分方程 可分离的微分方程: 可以把x和y分列等号两边,然后求积分可以解决 齐次方程和准齐次方程 要求是 :yf(y/x),也就是没有单独的x项,我们可以通过设ty/x来统一变量方便我们运算 准齐次方程就是常数项不统一,我们可以将Xxa,Yyb来消灭常数项进而转化为齐次形式…...

动态规划子序列问题系列一>等差序列划分II

题目&#xff1a; 解析&#xff1a; 1.状态表示&#xff1a; 2.状态转移方程&#xff1a; 这里注意有个优化 3.初始化&#xff1a; 4.填表顺序&#xff1a; 5.返回值&#xff1a; 返回dp表总和 代码&#xff1a; public int numberOfArithmeticSlices(int[] nums) {in…...

【连续学习之SSL算法】2018年论文Selfless sequential learning

1 介绍 年份&#xff1a;2018 期刊&#xff1a; arXiv preprint Aljundi R, Rohrbach M, Tuytelaars T. Selfless sequential learning[J]. arXiv preprint arXiv:1806.05421, 2018. 本文提出了一种名为SLNID&#xff08;Sparse coding through Local Neural Inhibition and…...

【FastAPI】中间件

【FastAPI】中间件 一、概述二、作用2.1 日志记录与监控2.2 身份验证与授权2.3 CORS&#xff08;跨域资源共享&#xff09;2.4 Gzip压缩2.5 会话管理2.6 自定义功能2.7 执行顺序 三、 总结四、相关链接 一、概述 FastAPI的中间件提供了一种强大的机制&#xff0c;允许开发者在…...

文档大师:打造一站式 Word 报告解决方案1

前言 在政府、医院、银行、财务以及销售等领域&#xff0c;常常需要创建各种报告文件来展开工作汇报&#xff0c;譬如季度销售报告、年度总结报告、体检报告和保险合同等。在没有报表工具支持之前&#xff0c;这类报告主要通过 Word 制作&#xff0c;费时费力且难以维护&#…...

再谈c++线性关系求值

目的 线性关系是最简单的一种关系&#xff0c;在编程当中应用非常多&#xff0c;所以&#xff0c;再说一次线性关系。 线性关系的定义是这样的&#xff1a; 两个变量之间存在一次方函数关系&#xff0c;就称它们之间存在线性关系。正比例关系是线性关系中的特例&#xff0c;反…...

【ES6复习笔记】Class类(15)

介绍 ES6 提供了更接近传统语言的写法&#xff0c;引入了 Class&#xff08;类&#xff09;这个概念&#xff0c;作为对象的模板。通过 class 关键字&#xff0c;可以定义类。基本上&#xff0c;ES6 的 class 可以看作只是一个语法糖&#xff0c;它的绝大部分功能&#xff0c;…...

AppAgent 源码 (xml 解析)

1. 数据准备 adb shell uiautomator dump /sdcard/output.xml # 获取手机ui界面的xml文件 adb pull /sdcard/output.xml output.xml # 将手机上的xml文件拉取到电脑上具体的xml文件&#xff1a; <?xml version1.0 encodingUTF-8 standaloneyes ?> <hierarchy ro…...

Oracle 11G还有新BUG?ORACLE 表空间迷案!

前段时间遇到一个奇葩的问题&#xff0c;在开了SR和oracle support追踪两周以后才算是有了不算完美的结果&#xff0c;在这里整理出来给大家分享。 1.问题描述 12/13我司某基地MES全厂停线&#xff0c;系统卡死不可用&#xff0c;通知到我排查&#xff0c;查看alert log看到是…...

FreeSwitch中启用WebRTC

在FreeSwitch中启用WebRTC需要进行一系列配置。以下是详细的步骤&#xff1a; 1. 安装必要的依赖&#xff1a; 确保安装了支持WebRTC的依赖库&#xff0c;如libsrtp。 2. 配置SIP Profile&#xff1a; 编辑 conf/sip_profiles/internal.xml 文件&#xff0c;添加或修改以下内…...

力扣矩阵-算法模版总结

lc-73.矩阵置零-(时隔14天)-12.27 思路&#xff1a;(23min22s) 1.直接遍历遇0将行列设0肯定不行&#xff0c;会影响后续判断&#xff0c;题目又要求原地算法&#xff0c;那么进一步考虑是否可以将元素为0&#xff0c;其行列需要设为0的位置给存储下来&#xff0c;最后再遍历根据…...

服务端高并发分布式结构演进之路

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 服务端高并发分布式结构演进之路 收录于专栏[redis] 本专栏旨在分享学习Redis的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 概述 …...

虚拟机桥接模式

主机Win10,虚拟机xp 1.虚拟机设置中选择桥接模式 2.在虚拟机菜单&#xff1a;编辑>虚拟机网络编辑&#xff0c;点击“更改设置”&#xff0c;可以看到三个网卡&#xff0c;这三个网卡分别对应不同的网络共享模式。桥接模式须使用VMnet0&#xff0c;如果没看到这个网卡&…...

JVM调优实践篇

理论篇 1多功能养鱼塘&#xff0d;JVM内存 大鱼塘O&#xff08;可分配内存&#xff09;&#xff1a; JVM可以调度使用的总的内存数&#xff0c;这个数量受操作系统进程寻址范围、系统虚拟内存总数、系统物理内存总数、其他系统运行所占用的内存资源等因素的制约。 小池塘A&a…...

SpeedTree学习笔记总结

SpeedTree是一款业界领先的三维树木植被建模软件&#xff0c;特别适用于游戏开发和影视制作。 一、基础操作 旋转&#xff1a;鼠标左键 平移&#xff1a;鼠标中键 缩放&#xff1a;鼠标中键滚动 Trunks树干节点 Branches树枝 Cap给树干封口 Frond创建大树叶 Decorations…...

【MuJoCo和PhysX】

MuJoCo 与 Unity 的 PhysX 引擎的主要区别 应用领域&#xff1a; MuJoCo&#xff1a;主要用于机器人学、强化学习、生物力学等领域&#xff0c;擅长处理多自由度、复杂动力学问题&#xff0c;尤其适合进行高精度的物理仿真。 Unity PhysX&#xff1a;主要用于游戏开发、虚拟现…...

HTML制作一个普通的背景换肤案例2024版

一&#xff0c;完整的代码&#xff1a; <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>换肤</t…...

python学opencv|读取图像(二十一)使用cv2.circle()绘制圆形进阶

【1】引言 前序已经掌握了使用cv2.circle()绘制圆形的基本操作&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;二十&#xff09;使用cv2.circle()绘制圆形-CSDN博客 由于圆形本身绘制起来比较简单&#xff0c;因此可以自由操作的空间也就大&#x…...

qt QZipReader详解

1、概述 QZipReader 是 Qt 中用于从 .zip 文件中读取和提取文件内容的类。它提供了便捷的方法来访问压缩包中的文件和目录&#xff0c;并允许你解压缩单个或多个文件。通过 QZipReader&#xff0c;你可以以编程方式读取 .zip 文件中的内容&#xff0c;并提取它们到目标目录中。…...

开发场景中Java 集合的最佳选择

在 Java 开发中&#xff0c;集合类是处理数据的核心工具。合理选择集合&#xff0c;不仅可以提高代码效率&#xff0c;还能让代码更简洁。本篇文章将重点探讨 List、Set 和 Map 的适用场景及优缺点&#xff0c;帮助你在实际开发中找到最佳解决方案。 一、List&#xff1a;有序存…...

顶顶通呼叫中心中间件mod_cti模块安全增强,预防盗打风险(mod_cti基于FreeSWITCH)

文章目录 前言联系我们mod_cti版本支持安全加强说明 前言 FreeSWITCH暴露在公网最大的风险就是被不法之人盗打 出现盗打的主要原因以下几点&#xff1a; 分机密码太简单或者密码泄露了拨号方案配置不合理sofia配置错误 所以我们给顶顶通呼叫中心中间件添加了安全加强功能&am…...

bash shell的条件语句

&#xff5e; script% touch if.sh &#xff5e; script% chmod 755 if.sh1.if-then-fi #!/usr/bin/env bashFOOD$1 if [ $FOOD"apple" ] thenecho The food is $FOOD fi exit 0~ script % ./if.sh apple The food is apple如果要将多条语句写在一行&#xff0c;可以…...

拦截器Interceptor与过滤器Filter

拦截器Interceptor 定义&#xff1a; SpringMVC内置拦截机制,允许在请求被目标方法处理的前后进行拦截&#xff0c;执行一些额外操作&#xff1b;比如&#xff1a;权限验证&#xff0c;日志记录&#xff0c;数据共享等。 实现步骤 1、自定义拦截器 Component public class …...

水电站视频智能监控系统方案设计与技术应用方案

一、背景需求 水电站作为国家重要的能源基地&#xff0c;其安全运行对于保障能源供应和社会稳定具有重要意义。然而&#xff0c;传统的人工监控方式存在着诸多问题&#xff0c;如人力成本高、监控范围有限、反应不及时等。因此&#xff0c;水电站急需引进一种先进的视频智能监控…...

教师管理系统

大概功能&#xff1a; 1.显示所有教师 2.按姓名查找教师 3.按工号查找教师 4.增加教师 5.删除教师 6.退出 数据会保存到 txt 文件里面 姓名&#xff1a;必须是中文 手机号码&#xff1a;必须是11位&#xff0c;必须是数字 效果展示&#xff1a; 代码展示&#xff1a; Teache…...

nexus docker安装

#nexus docker 安装 docker pull sonatype/nexus3 mkdir -p /data/nexus-data docker run -itd -p 8081:8081 --privilegedtrue --name nexus3 \ -v /data/nexus-data:/var/nexus-data --restartalways docker.io/sonatype/nexus3 #访问 http://192.168.31.109:8081/ 用户名&am…...

canvas之进度条

canvas之进度条 效果&#xff1a; 封装的组件 <template><div class"circle" :style"{ width: props.radius px, height: props.radius px }"><div class"circle-bg" :style"{ width: props.radius - 5 px, height: pr…...

【ES6复习笔记】Promise对象详解(12)

1. 什么是 Promise&#xff1f; Promise 是 JavaScript 中处理异步操作的一种机制&#xff0c;它可以让异步操作更加容易管理和控制。Promise 对象代表一个异步操作的最终完成或失败&#xff0c;并提供了一种方式来处理操作的结果。 2. Promise 的基本语法 Promise 对象有三…...

前端Python应用指南(五)用FastAPI快速构建高性能API

《写给前端的python应用指南》系列&#xff1a; &#xff08;一&#xff09;快速构建 Web 服务器 - Flask vs Node.js 对比&#xff08;二&#xff09;深入Flask&#xff1a;理解Flask的应用结构与模块化设计&#xff08;三&#xff09;Django vs Flask&#xff1a;哪种框架适…...

c#多线程之生产者-消费者模型

在 C# 中实现 生产者-消费者模式&#xff0c;通常需要多个线程来处理数据的生产和消费。我们可以使用 Queue<T> 来作为存储数据的队列&#xff0c;并使用 Thread、Mutex 或 Monitor 来确保线程安全。BlockingCollection<T> 是 C# 提供的一个线程安全的集合&#xf…...

2011-2020年各省城镇职工基本医疗保险年末参保人数数据

2011-2020年各省城镇职工基本医疗保险年末参保人数数据 1、时间&#xff1a;2011-2020年 2、来源&#xff1a;国家统计局 3、指标&#xff1a;省份、时间、城镇职工基本医疗保险年末参保人数 4、范围&#xff1a;31省 5、指标解释&#xff1a;参保人数指报告期末按国家有关…...

Python基础语法知识——列表、字典、元组与集合

列表&#xff08;list&#xff09;、字典(dictionary)、元组(tuple)与集合(set)都可以看成存储数据的容器&#xff0c;但是前两者常用&#xff0c;后两者用得相对较少。 目录 1 列表&#xff08;list) 1.1列表入门 1 列表&#xff08;list) 1.1列表入门 class1["李白…...

Mysql数据库中,监测某张表中某字段的修改情况(被哪个ip所修改、新老值)

在Mysql数据库中&#xff0c;通过写一个触发器&#xff0c;来监测某张表(q_device)字段(run_status)的改变情况。 【示例】 -- 1. 创建监测日志表 CREATE TABLE change_log (id INT AUTO_INCREMENT PRIMARY KEY,table_name VARCHAR(255),column_name VARCHAR(255),old_value T…...

迁移学习 详解及应用示例

简介&#xff1a; 迁移学习是一种机器学习技术&#xff0c;其核心思想是利用在一个任务上已经学到的知识&#xff08;源任务&#xff1a;任务已经有一个训练好的模型&#xff0c;然后我们将这个模型的某些部分或知识迁移到一个新的但相关的“目标任务”上。&#xff09;来帮助解…...

ubuntu控制器多网口配置

在Ubuntu系统中配置多网口&#xff0c;可以通过编辑网络配置文件&#xff08;Netplan 或旧版 /etc/network/interfaces&#xff09;实现。这适用于需要管理多个网络接口&#xff08;如 eth0、eth1 等&#xff09;的场景&#xff0c;例如负载均衡、网络隔离或多路径通信。 以下…...

接口调用限频(代理模式+滑动窗口)

目录 代码示例 接口 代理 接口实现 限流工厂 限流处理器接口 直接交换处理器 限流处理器 限流配置 滑动窗口限流 通过代理模式滑动窗口&#xff0c;限流请求第三方平台&#xff0c;避免出现第三方平台抛出限流异常&#xff0c;影响正常业务流程&#xff0c;从出口出发…...

FFmpeg在python里推流被处理过的视频流

链式算法处理视频流 视频源是本地摄像头 # codinggbk # 本地摄像头直接推流到 RTMP 服务器 import cv2 import mediapipe as mp import subprocess as sp# 初始化 Mediapipe mp_drawing mp.solutions.drawing_utils mp_drawing_styles mp.solutions.drawing_styles mp_holis…...

2- Linux系统的命令帮助

Linux 命令行帮助信息使用指南 一、引言 对于初学者来说,Linux命令行可能会显得复杂和难以捉摸。然而,一旦掌握了如何有效地利用命令行的帮助信息,您将发现它是一个强大而灵活的工具,可以极大地提高您的工作效率。本指南旨在为新手介绍如何在Linux中获取命令的帮助信息,…...

Mysql事务

一、数据库事务基础 1.1. 什么是事务 简单来说&#xff0c;事务就是要保证一组数据库操作&#xff0c;要么全部成功&#xff0c;要么全部失败。在 MySQL 中&#xff0c;事务支持是在引擎层实现的。 比如 MySQL 原生的MyISAM引擎就不支持事务&#xff0c;这也是MyISAM被InnoDB…...

Fast adaptively balanced min-cut clustering

#0.论文信息 标题&#xff1a;Fast adaptively balanced min-cut clustering期刊&#xff1a;Pattern Recognition作者: Feiping Nie , Fangyuan Xie , Jingyu Wang ,Xuelong Li机构: China Telecom, Northwestern Polytechnic al University.代码链接&#xff1a; #1.摘要 …...