基于canvas画布的实用类Fabric.js的使用Part.3

目录

一、基于canvas画布的实用类Fabric.js的使用Part.1

  • Fabric.js简介

  • 开始

  • 方法

  • 事件

  • canvas常用属性

  • 对象属性

  • 图层层级操作

  • 复制和粘贴

二、基于canvas画布的实用类Fabric.js的使用Part.2

  • 锁定

  • 拖拽和缩放画布

  • 分组

  • 动画

  • 图像滤镜

  • 渐变

  • 右键菜单删除

三、基于canvas画布的实用类Fabric.js的使用Part.3

  • 自由绘画

  • 绘制背景图片

  • 绘制文本

  • 绘制线和路径

  • 自由绘制矩形

  • 自由绘制圆形

  • 自由绘制椭圆形

  • 自由绘制三角形

  • 自由绘制多边形

一、自由绘画

1、开启绘图模式
let canvas = new fabric.Canvas('canvas', {
  isDrawingMode: true // 开启绘图模式
})
canvas.freeDrawingBrush.color = '#11999e' // 设置画笔颜色
canvas.freeDrawingBrush.width = 10 // 设置画笔粗细
canvas.freeDrawingBrush.shadow = new fabric.Shadow({ // 设置画笔投影
  blur: 10,
  offsetX: 10,
  offsetY: 10,
  affectStroke: true,
  color: '#30e3ca'
})
2、关闭绘图模式
canvas.isDrawingMode = false

二、绘制背景图片

1、方式一:通过img元素添加
<img src="@/assets/images/logo.png" id="logo">

let img = document.getElementById('logo')
img.onload = () => {
  let canvasImage = new fabric.Image(imgElement, {
    left: 100, // 距离画布左侧距离
    top: 100, // 距离画布顶部距离
    width: 200, // 图片宽度
    height: 200, // 图片高度
    angle: 50, // 旋转
    opacity: 1 // 透明度
  })
  canvas.add(canvasImage)
}
2、方式二:通过图片路径添加
let url = 'http://localhost:82/public/img/logo.png'
fabric.Image.fromURL(url, img => {
  let canvasImage = img.set({
    scaleX: 0.5,
    scaleY: 0.5
  })
  canvas.add(canvasImage)
}) 

三、绘制文本

Fabric也提供了文本的相关功能,Fabric文本允许以面向对象的方式处理文本,原生canvas方法,只允许在非常低的级别上填充或描边文本,通过实例化fabric.Text实例,我们就可以使用文本,就像我们将使用任何其他Fabric对象:移动它,缩放它,更改其属性等, 其次它提供比canvas给我们更丰富的功能,包括:

Multiline support   // 支持多行
Text alignment      // 文本对齐 Left、center、right
Text background     // 文本背景 背景也遵循文本对齐
Text decoration     // 文字装饰 下划线Underline、上划线overline、贯穿线strike-through
Line height         // 行高 使用多行文字时出错
Char spacing        // 字符间距 使文本更紧凑或间距更大
Subranges           // 子范围 将颜色和属性应用于文本对象的子范围
Multibyte           // 多字节 支持表情符号
On canvas editing   // 交互式画布编辑 可以直接在canvas上键入文本
1、基础用法
let text = new fabric.Text('Hello World!', {
  left: 40,
  top: 10,
  fontFamily: 'Comic Sans', // 字体
  fontSize: 60, // 字号
  fontWeight: 600, // 字体重量(粗细),normal、bold 或 数字(100、200、400、600、800)
  fontStyle: 'normal', // 字体风格 正常 normal 或 斜体 italic
  charSpacing: 100, // 字距
  fill: 'red', // 字体颜色
  cornerColor: 'pink', // 角的颜色(被选中时)
  angle: 30, // 旋转
  backgroundColor: '#ffd460', // 背景色
  borderColor: 'yellowGreen', // 边框颜色(被选中时)
  borderScaleFactor: 4, // 边框粗细(被选中时)
  borderDashArray: [10, 4, 20], // 创建边框虚线
  stroke: '#3f72af', // 文字描边颜色(蓝色)
  strokeWidth: 2, // 文字描边粗细
  textAlign: 'left', // 对齐方式:left 左对齐; right 右对齐; center 居中
  opacity: 0.8, // 不透明度
  // text: '雷猴', // 文字内容,会覆盖之前设置的值
  selectable: true, // 能否被选中,默认true
  shadow: 'rgba(0, 0, 0, 0.5) 5px 5px 5px', // 投影
})
canvas.add(text)
2、文本修饰
// 下划线
let underlineText = new fabric.Text("I am an undrline text", {
  underline: true
})
canvas.add(underlineText)

// 贯穿线
let strokeThroughText = new fabric.Text("I am a stroke-through text", {
  linethrough: true,
  top: 40
})
canvas.add(strokeThroughText)

// 上划线
let overlineText = new fabric.Text("I am overline text", {
  overline:true,
  top: 80
})
canvas.add(overlineText)
3、可编辑文本
let IText = new fabric.IText('雷猴啊,双击打几个字试下~', {
  fontFamily: 'Comic Sans'
})
canvas.add(IText)

四、绘制线和路径

1、绘制直线
let line = new fabric.Line([0, 100, 100, 100], {
  fill: 'green', // 填充色
  stroke: 'green', // 笔触颜色
  strokeWidth: 2, // 笔触宽度
});
canvas.add(line);
2、绘制虚线

在绘制直线的基础上添加属性strokeDashArray[a,b],表示每隔a个像素空b个像素。

let line = new fabric.Line([0, 100, 100, 100], {
  fill: 'green', // 填充色
  stroke: 'green', // 笔触颜色
  strokeWidth: 2, // 笔触宽度
  strokeDashArray:[3,1]
});
canvas.add(line);
3、绘制路径

Fabric.js使用 new fabric.Path 创建路径。

M:可以理解为新的起始点 x,y 坐标

L:每个折点的 x,y 坐标

z:自动闭合(自动把结束点和起始点连接起来)

let path = new fabric.Path('M 0 0 L 200 100 L 170 200 z')
path.set({
    top: 120, // 距离容器顶部距离 120px
    left: 120, // 距离容器左侧距离 120px
    fill: 'hotpink', // 填充 亮粉色
    opacity: 0.5, // 不透明度 50%
    stroke: 'black', // 描边颜色 黑色
    strokeWidth: 10 // 描边粗细 10px
})

上述代码第一行“M”代表“移动”命令,“M 0 0” 代表把画笔移动到(0, 0)点坐标。“L”代表“线”,“L 200 100 ”的意思是使用钢笔画一条线,从(0, 0)坐标画到(200, 100)坐标。“z” 代表让图形闭合路径。这样就画出了一个三角形。画好三角形后,我们可以用set( )方法对三角形的位置、颜色、角度、透明度等属性进行设置。

五、自由绘制矩形

<template>
  <div class="canvas-box" ref="canvasBox">
    <canvas id="canvas"></canvas>
    <el-button @click="handleActiveRect">绘制矩形</el-button>
  </div>
</template>
<script>
export default {
  name: 'PointerDetail',
  data () {
    return {
      canvas: null,
      lastPoint: null, // 上次鼠标点位坐标
      strokeColor: 'transparent', // 轮廓填充颜色
      isActiveRect: false, // 是否激活绘制矩形
      rectList: [] // 绘制的矩形列表
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.canvas = new fabric.Canvas('canvas', {
        width: this.$refs.canvasBox.offsetWidth,
        height: this.$refs.canvasBox.offsetHeight,
        backgroundColor: '#2E3136',
        selectionColor: 'transparent',
        selectionBorderColor: 'transparent',
        hoverCursor: 'default'
      })
      this.canvas.on('mouse:down', this.onMouseDown)
      this.canvas.on('mouse:up', this.onMouseUp)
      this.canvas.on('object:added', this.onObjectAdded)
    },
    // 监听鼠标按下事件
    onMouseDown(opt) {
      if (this.isActiveRect) {
        this.lastPoint = opt.absolutePointer || null
        this.strokeColor = '#00FF64'
      }
    },
    // 监听鼠标松开事件
    onMouseUp(opt) {
      if (this.isActiveRect) {
        this.drawRect(opt.absolutePointer)
      }
    },
    // 绘制完成元素事件
    onObjectAdded(opt) {
      let target = opt.target
      if (target.stroke === '#00FF64') {
        this.isActiveRect && this.rectList.push(target)
      }
    },
    // 绘制矩形
    drawRect(pointer) {
      if (!this.lastPoint || JSON.stringify(this.lastPoint) === JSON.stringify(pointer)) { // 点击事件,不生成矩形
        return
      }
      let top = Math.min(this.lastPoint.y, pointer.y)
      let left = Math.min(this.lastPoint.x, pointer.x)
      let width = Math.abs(this.lastPoint.x - pointer.x)
      let height = Math.abs(this.lastPoint.y - pointer.y)
      let rect = new fabric.Rect({ 
        top, 
        left,
        width,
        height,
        fill: 'transparent',
        stroke: this.strokeColor,
        selectable: false
      })
      this.canvas.add(rect)
      this.lastPoint = null
      this.strokeColor = 'transparent'
    },
    // 激活绘制矩形
    handleActiveRect() {
      this.isActiveRect = !this.isActiveRect
      if(this.isActiveRect) {
        this.canvas.selectionBorderColor = '#00FF64'
      }
    }
  }
}

六、自由绘制圆形

<template>
  <div class="canvas-box" ref="canvasBox">
    <canvas id="canvas"></canvas>
    <el-button @click="handleActiveCircle">绘制圆形</el-button>
  </div>
</template>
<script>
export default {
  name: 'PointerDetail',
  data () {
    return {
      canvas: null,
      canvasCircle: null,
      downPoint: null,
      strokeColor: 'transparent', // 轮廓填充颜色
      isActiveCircle: false, // 是否激活绘制圆形
      circleList: [] // 绘制的圆形列表
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.canvas = new fabric.Canvas('canvas', {
        width: this.$refs.canvasBox.offsetWidth,
        height: this.$refs.canvasBox.offsetHeight,
        backgroundColor: '#2E3136',
        selectionColor: 'transparent',
        selectionBorderColor: 'transparent',
        hoverCursor: 'default'
      })
      this.canvas.on('mouse:down', this.onMouseDown)
      this.canvas.on('mouse:move', this.onMouseMove)
      this.canvas.on('mouse:up', this.onMouseUp)
      this.canvas.on('object:added', this.onObjectAdded)
    },
    // 监听鼠标按下事件
    onMouseDown(opt) {
      if (this.isActiveCircle) {
        this.downPoint = opt.absolutePointer
        this.strokeColor = '#00FF64'
        this.canvasCircle = new fabric.Circle({
          top: this.downPoint.y,
          left: this.downPoint.x,
          radius: 0,
          fill: 'transparent',
          stroke: this.strokeColor,
          strokeWidth: 2,
          selectable: false,
        })
        this.canvas.add(this.canvasCircle)
      }
    },
    // 监听鼠标移动事件
    onMouseMove(opt) {
      if (this.isActiveCircle && this.canvasCircle) {
        let radius = Math.min(Math.abs(this.downPoint.x - opt.absolutePointer.x), Math.abs(this.downPoint.y - opt.absolutePointer.y)) / 2
        let top = opt.absolutePointer.y > this.downPoint.y ? this.downPoint.y : this.downPoint.y - radius * 2
        let left = opt.absolutePointer.x > this.downPoint.x ? this.downPoint.x :  this.downPoint.x - radius * 2
        this.canvasCircle.set('radius', radius)
        this.canvasCircle.set('top', top)
        this.canvasCircle.set('left', left)
        this.canvas.requestRenderAll()
      }
    },
    // 监听鼠标松开事件
    onMouseUp(opt) {
      if (this.isActiveCircle) {
        if (JSON.stringify(this.downPoint) === JSON.stringify(opt.absolutePointer)) {
          this.canvas.remove(this.canvasCircle)
        } else {
          if (this.canvasCircle){
            this.canvasCircle.set('stroke', this.strokeColor)
          }
        }
        this.canvasCircle = null
      }
    },
    // 绘制完成元素事件
    onObjectAdded(opt) {
      let target = opt.target
      if (target.stroke === '#00FF64') {
        this.isActiveCircle && this.circleList.push(target)
      }
    },
    // 激活绘制圆形
    handleActiveCircle() {
      this.isActiveCircle = !this.isActiveCircle
      if(this.isActiveCircle) {
        this.canvas.selectionBorderColor = '#00FF64'
      }
    }
  }
}

七、自由绘制椭圆形

<template>
  <div class="canvas-box" ref="canvasBox">
    <canvas id="canvas"></canvas>
    <el-button @click="handleActiveEllipse">绘制椭圆形</el-button>
  </div>
</template>
<script>
export default {
  name: 'PointerDetail',
  data () {
    return {
      canvas: null,
      canvasEllipse: null,
      downPoint: null,
      strokeColor: 'transparent', // 轮廓填充颜色
      isActiveEllipse: false, // 是否激活绘制椭圆形
      ellipseList: [] // 绘制的椭圆形列表
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.canvas = new fabric.Canvas('canvas', {
        width: this.$refs.canvasBox.offsetWidth,
        height: this.$refs.canvasBox.offsetHeight,
        backgroundColor: '#2E3136',
        selectionColor: 'transparent',
        selectionBorderColor: 'transparent',
        hoverCursor: 'default'
      })
      this.canvas.on('mouse:down', this.onMouseDown)
      this.canvas.on('mouse:move', this.onMouseMove)
      this.canvas.on('mouse:up', this.onMouseUp)
      this.canvas.on('object:added', this.onObjectAdded)
    },
    // 监听鼠标按下事件
    onMouseDown(opt) {
      if (this.isActiveEllipse) {
        this.downPoint = opt.absolutePointer
        this.strokeColor = '#00FF64'
        this.canvasEllipse = new fabric.Ellipse({
          top: this.downPoint.y,
          left: this.downPoint.x,
          rx: 0,
          ry: 0,
          fill: 'transparent',
          stroke: this.strokeColor,
          strokeWidth: 2,
          selectable: false,
        })
        this.canvas.add(this.canvasEllipse)
      }
    },
    // 监听鼠标移动事件
    onMouseMove(opt) {
      if (this.isActiveEllipse && this.canvasEllipse) {
        let rx = Math.abs(this.downPoint.x - opt.absolutePointer.x) / 2
        let ry = Math.abs(this.downPoint.y - opt.absolutePointer.y) / 2
        let top = opt.absolutePointer.y > this.downPoint.y ? this.downPoint.y : this.downPoint.y - ry * 2
        let left = opt.absolutePointer.x > this.downPoint.x ? this.downPoint.x :  this.downPoint.x - rx * 2
        this.canvasEllipse.set('rx', rx)
        this.canvasEllipse.set('ry', ry)
        this.canvasEllipse.set('top', top)
        this.canvasEllipse.set('left', left)
        this.canvas.requestRenderAll()
      }
    },
    // 监听鼠标松开事件
    onMouseUp(opt) {
      if (this.isActiveEllipse) {
        if (JSON.stringify(this.downPoint) === JSON.stringify(opt.absolutePointer)) {
          this.canvas.remove(this.canvasEllipse)
        } else {
          if (this.canvasEllipse){
            this.canvasEllipse.set('stroke', this.strokeColor)
          }
        }
        this.canvasEllipse = null
      }
    },
    // 绘制完成元素事件
    onObjectAdded(opt) {
      let target = opt.target
      if (target.stroke === '#00FF64') {
        this.isActiveEllipse && this.ellipseList.push(target)
      }
    },
    // 激活绘制椭圆形
    handleActiveEllipse() {
      this.isActiveEllipse = !this.isActiveEllipse
      if(this.isActiveEllipse) {
        this.canvas.selectionBorderColor = '#00FF64'
      }
    }
  }
}

八、自由绘制三角形

<template>
  <div class="canvas-box" ref="canvasBox">
    <canvas id="canvas"></canvas>
    <el-button @click="handleActiveTriangle">绘制三角形</el-button>
  </div>
</template>
<script>
export default {
  name: 'PointerDetail',
  data () {
    return {
      canvas: null,
      canvasTriangle: null,
      downPoint: null,
      strokeColor: 'transparent', // 轮廓填充颜色
      isActiveTriangle: false, // 是否激活绘制三角形
      triangleList: [] // 绘制的三角形列表
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.canvas = new fabric.Canvas('canvas', {
        width: this.$refs.canvasBox.offsetWidth,
        height: this.$refs.canvasBox.offsetHeight,
        backgroundColor: '#2E3136',
        selectionColor: 'transparent',
        selectionBorderColor: 'transparent',
        hoverCursor: 'default'
      })
      this.canvas.on('mouse:down', this.onMouseDown)
      this.canvas.on('mouse:move', this.onMouseMove)
      this.canvas.on('mouse:up', this.onMouseUp)
      this.canvas.on('object:added', this.onObjectAdded)
    },
    // 监听鼠标按下事件
    onMouseDown(opt) {
      if (this.isActiveTriangle) {
        this.downPoint = opt.absolutePointer
        this.strokeColor = '#00FF64'
        this.canvasTriangle = new fabric.Triangle({
          top: this.downPoint.y,
          left: this.downPoint.x,
          width: 0,
          height: 0,
          fill: 'transparent',
          stroke: this.strokeColor,
          strokeWidth: 2,
          selectable: false,
        })
        this.canvas.add(this.canvasTriangle)
      }
    },
    // 监听鼠标移动事件
    onMouseMove(opt) {
      if (this.isActiveTriangle && this.canvasTriangle) {
        let width = Math.abs(this.downPoint.x - opt.absolutePointer.x)
        let height = Math.abs(this.downPoint.y - opt.absolutePointer.y)
        let top = opt.absolutePointer.y > this.downPoint.y ? this.downPoint.y : opt.absolutePointer.y
        let left = opt.absolutePointer.x > this.downPoint.x ? this.downPoint.x : opt.absolutePointer.x
        this.canvasTriangle.set('width', width)
        this.canvasTriangle.set('height', height)
        this.canvasTriangle.set('top', top)
        this.canvasTriangle.set('left', left)
        this.canvas.requestRenderAll()
      }
    },
    // 监听鼠标松开事件
    onMouseUp(opt) {
      if (this.isActiveTriangle) {
        if (JSON.stringify(this.downPoint) === JSON.stringify(opt.absolutePointer)) {
          this.canvas.remove(this.canvasTriangle)
        } else {
          if (this.canvasTriangle){
            this.canvasTriangle.set('stroke', this.strokeColor)
          }
        }
        this.canvasTriangle = null
      }
    },
    // 绘制完成元素事件
    onObjectAdded(opt) {
      let target = opt.target
      if (target.stroke === '#00FF64') {
        this.isActiveTriangle && this.triangleList.push(target)
      }
    },
    // 激活绘制矩形
    handleActiveTriangle() {
      this.isActiveTriangle = !this.isActiveTriangle
      if(this.isActiveTriangle) {
        this.canvas.selectionBorderColor = '#00FF64'
      }
    }
  }
}

九、自由绘制多边形

<template>
  <div class="canvas-box" ref="canvasBox">
    <canvas id="canvas"></canvas>
    <el-button @click="handleActivePolygon">绘制多边形</el-button>
  </div>
</template>
<script>
export default {
  name: 'PointerDetail',
  data () {
    return {
      canvas: null,
      canvasPolygon: null,
      strokeColor: 'transparent', // 轮廓填充颜色
      isActivePolygon: false, // 是否激活绘制多边形
      polygonList: [] // 绘制的多边形列表
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      this.canvas = new fabric.Canvas('canvas', {
        width: this.$refs.canvasBox.offsetWidth,
        height: this.$refs.canvasBox.offsetHeight,
        backgroundColor: '#2E3136',
        selectionColor: 'transparent',
        selectionBorderColor: 'transparent',
        hoverCursor: 'default'
      })
      this.canvas.on('mouse:down', this.onMouseDown)
      this.canvas.on('mouse:move', this.onMouseMove)
      this.canvas.on('mouse:dblclick', this.onDblclick)
      this.canvas.on('object:added', this.onObjectAdded)
    },
    // 监听鼠标按下事件
    onMouseDown(opt) {
      if (this.isActivePolygon) {
        this.strokeColor = '#00FF64'
        if (this.canvasPolygon === null) {
          this.createPolygon(opt)
        } else {
          this.changeCurrentPolygon(opt)
        }
      }
    },
    // 监听鼠标移动事件
    onMouseMove(opt) {
      if (this.isActivePolygon && this.canvasPolygon) {
        this.changePolygonBelt(opt)
      }
    },
    // 鼠标双击事件
    onDblclick(opt) {
      this.finishPolygon(opt)
    },
    // 绘制完成元素事件
    onObjectAdded(opt) {
      let target = opt.target
      if (target.stroke === '#00FF64') {
        this.isActivePolygon && this.polygonList.push(target)
      }
    },
    // 创建多边形
    createPolygon(opt) {
      this.canvasPolygon = new fabric.Polygon([
          { x: opt.absolutePointer.x, y: opt.absolutePointer.y },
          { x: opt.absolutePointer.x, y: opt.absolutePointer.y }
        ], {
          fill: 'transparent',
          stroke: this.strokeColor,
          objectCaching: false
      })
      this.canvas.add(this.canvasPolygon)
    },
    // 修改当前正在创建的多边形
    changeCurrentPolygon(opt) {
      let points = this.canvasPolygon.points
      points.push({
        x: opt.absolutePointer.x,
        y: opt.absolutePointer.y
      })
      this.canvas.requestRenderAll()
    },
    // 多边形橡皮带
    changePolygonBelt(opt) {
      let points = this.canvasPolygon.points
      points[points.length - 1].x = opt.absolutePointer.x
      points[points.length - 1].y = opt.absolutePointer.y
      this.canvas.requestRenderAll()
    },
    // 完成多边形绘制
    finishPolygon(opt) {
      let points = this.canvasPolygon.points
      points[points.length - 1].x = opt.absolutePointer.x
      points[points.length - 1].y = opt.absolutePointer.y
      points.pop()
      points.pop()
      this.canvas.remove(this.canvasPolygon)
      if (points.length > 2) {
        let polygon = new fabric.Polygon(points, {
          stroke: this.strokeColor,
          fill: 'transparent',
          selectable: false
        })
        this.canvas.add(polygon)
      } else {
        this.$message.warning('标记框小于最小标定像素!')
      }
      this.canvasPolygon = null
      this.canvas.requestRenderAll()
      this.strokeColor = 'transparent'
    },
    // 激活绘制多边形
    handleActivePolygon() {
      this.isActivePolygon = !this.isActivePolygon
      if(this.isActivePolygon) {
        this.canvas.selectionBorderColor = '#00FF64'
      }
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/5761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gcc在Linux下如何运行一个C/C++程序

安装gcc&#xff1a;sudo apt-get install gcc&#xff08;之后输入密码即可&#xff09; 绝对路径的方式进入usr目录&#xff1a; cd /home /home/&#xff1a;是普通用户的主目录&#xff0c;在创建用户时&#xff0c;每个用户要有一个默认登录和保存自己数据的位置&#x…

【数据结构刷题集】链表经典习题

&#x1f63d;PREFACE&#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐ 评论&#x1f4dd;&#x1f4e2;系列专栏&#xff1a;数据结构刷题集&#x1f50a;本专栏涉及到题目是数据结构专栏的补充与应用&#xff0c;只更新相关题目&#xff0c;旨在帮助提高代码熟练度&#x…

第14章_视图

第14章_视图 &#x1f3e0;个人主页&#xff1a;shark-Gao &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是shark-Gao&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f389;目前状况&#xff1a;23届毕业生&#xff0c;目前在某公司…

Python 自动化指南(繁琐工作自动化)第二版:六、字符串操作

原文&#xff1a;https://automatetheboringstuff.com/2e/chapter6/ 文本是程序将处理的最常见的数据形式之一。您已经知道如何用操作符将两个字符串值连接在一起&#xff0c;但是您可以做得更多。您可以从字符串值中提取部分字符串&#xff0c;添加或删除空格&#xff0c;将字…

【新2023Q2模拟题JAVA】华为OD机试 - 找数字 or 找等值元素

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:找数字 or 找等值元素 题目 …

华为OD机试 用java实现 -【重组字符串】

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本篇题解:重组字符串 题目 给定一个非…

计算机网络 第一章 概述小结

计算机网络 第一章 概述 1.1 因特网概述 名词解释&#xff1a;因特网服务提供者ISP&#xff08;Internet Service Provider&#xff09; 1.2 三种交换方式 电路交换&#xff1a; 优点&#xff1a;通信时延小、有序传输、没有冲突、适用范围广、实时性强、控制简单&#x…

【美赛】2023年MCM问题Y:理解二手帆船价格(代码思路)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

新导则下的防洪评价报告编制方法及洪水建模实践技术

目录 1、《防洪评价报告编制导则解读河道管理范围内建设项目编制导则》&#xff08;SL/T808- 2021&#xff09;解读 2、防洪评价相关制度与解析 3、防洪评价地形获取及常用计算 4、HEC-RAS软件原理及特点 5、HEC-RAS地形导入 6、一维数学模型计算 7、基于数学模型软件的…

用 云GPU 云服务器训练数据集--yolov5

目录 为何使用云GPU训练我们数据集&#xff1f; 云服务器训练数据集教程&#xff1a; 1.创建实例 2.上传数据&#xff08;OSS命令&#xff09; 以下是oss的操作过程 训练模型时可能出现的报错&#xff1a; 为何使用云GPU训练我们数据集&#xff1f; 我们总是花费长达十几个…

ISO文件内添加kickstart完成自动安装

目录 将待制作的centos iso文件挂载到/mnt/目录 将/mnt/下的所有文件复制到新的目录/tmp/mycentos 创建kickstart文件 修改启动文件 重新制作ISO文件 制作完成 kickstart可以实现根据配置自动安装操作系统&#xff0c;本文主要讲解如何让机器读取到iso文件后自动完成操作…

vue尚品汇商城项目-day02【11.对axios二次封装+12.接口统一管理】

文章目录11.对axios二次封装11.1为什么需要进行二次封装axios&#xff1f;11.2在项目当中经常有API文件夹【axios】12.接口统一管理12.1跨域问题12.2接口统一管理12.3不同请求方式的src/api/index.js说明本人其他相关文章链接11.对axios二次封装 安装命令&#xff1a;cnpm inst…

移动端滑动(touch)选项并实现多选效果

移动端滑动选项实现多选效果通过 touchstart、touchmove、 touchend、touchcancel 事件实现通过父元素代理事件的方式实现子组件点击选中选项如果选项添加 disabled 属性将不会被选中移动端拖拽 .box 和 .options 元素时&#xff0c;是有拖拽效果的&#xff0c;去除拖拽效果有两…

文件操作-C语言实现图片、压缩包等文件的“复制粘贴“过程

大部分参考自&#xff1a; 文件操作-C语言实现图片的“复制粘贴“过程_一个图像一部分复制到另一个图像中c语言_philippe coutinho的博客-CSDN博客 #define _CRT_SECURE_NO_WARNINGS的作用参考&#xff1a; https://mp.csdn.net/mp_blog/creation/editor/new/129414996 首先我们…

线程池的优点

线程池的优点&#x1f50e;优点1(降低资源消耗)&#x1f50e;优点2(提高响应速度)&#x1f50e;优点3(可管理性)&#x1f50e;结尾&#x1f50e;优点1(降低资源消耗) 有了线程池后,创建线程不再是向系统申请,而是从线程池中拿 当线程不再使用后,再还给线程池 线程的创建,虽然相…

47了解公有云平台 GCP 的基本服务和使用方法,包括 Compute Engine、Cloud Storage

GCP Compute Engine Google Cloud Platform (GCP) 的 Compute Engine 是一个可扩展的云计算平台&#xff0c;可以让您快速启动虚拟机实例来运行您的应用程序。它提供了一种灵活的方式来管理您的计算资源&#xff0c;并支持多种操作系统、应用程序框架和开发工具。以下是一些基本…

Leetcode.939 最小面积矩形

题目链接 Leetcode.939 最小面积矩形 Rating &#xff1a; 1752 题目描述 给定在 xy平面上的一组点&#xff0c;确定由这些点组成的矩形的最小面积&#xff0c;其中矩形的边平行于 x 轴和 y 轴。 如果没有任何矩形&#xff0c;就返回 0。 示例 1&#xff1a; 输入&#xff1…

centos7安装rabbitmq服务

centos7安装rabbitmq服务 第一 软件包准备 1.erlang依赖包 2.rabbitmq安装包 第二 安装rabbitmq 1.安装依赖 rpm -ivh erlang-21.3-1.el7.x86_64.rpmyum install socat -y2.安装rabbitmq服务 rpm -ivh rabbitmq-server-3.8.8-1.el7.noarch.rpm3.启动rabbitmq服务 system…

一次线上MySQL vCPU飙升引发的思考

vCPU飙升 在一个漆黑的深夜&#xff0c;MySQL丛库的vCPU在做一个三点任务的时候突然飙升&#xff0c;从MySQL面板中可以查到是以下查询导致的。 表数据及相关索引说明&#xff1a; hotel_info_tbl: 数据量&#xff1a;100w&#xff0c;id 为 primary keydynamic_cache_task_…

二项式反演

二项式反演 在很多情况下&#xff0c;“恰好”往往是不好求的&#xff0c;因为恰好意味着"≤\leq≤"并且"≥\geq≥"&#xff0c;需要进行很多限制&#xff0c;破坏了情况之间的独立性。 二项式反演则通过一定手段&#xff0c;使得限制"≤\leq≤&quo…
最新文章