canvas自制简易画板

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
  html,body{
    margin:0;
    padding:0;
    height:100vh;
  }
  .canvasTool {
    width: 100%;
    height: 100%;
    background-color: gray;
  }

  .canvalParent {
    height:calc(100% - 60px);
    width: 100%;
    /* display: flex;
    justify-content: center;
    align-items: center; */
  }

  #canvas1 {
    background-color: white;
    position: absolute;
    z-index: 1;
  }

  #canvas2 {
    cursor: crosshair;
    position: absolute;
    z-index: 2;
  }

  .btn>div{
    margin-top:10px;
    /* display: flex;
    justify-content: center;
    align-items: center; */
  }

  .btn select {
    margin-right: 20px;
    width: 60px;
  }
</style>

<body>
  <div class="canvasTool">
    <div class="canvalParent">
      <canvas id="canvas1"></canvas>
      <canvas id="canvas2"></canvas>
    </div>
    <div class="btn">
      <div>
        操作:<select id="handlerSelect"></select>
        线条宽度:<select id="lineWidthSelect"></select>
        颜色:<select id="colorSelect"></select>
        数据精度:<select id="accuracySelect"></select>
        <button id="eraser">橡皮擦</button>
        <button id="clear">清除画布</button> 
      </div>
    </div>
  </div>
  <script>
    const handlerList = [{
        value: 'point',
        desc: '点',
        select: false
      },
      {
        value: 'straightLine',
        desc: '直线',
        select: true
      },
      {
        value: 'straightLineConnection',
        desc: '直线连线',
        select: false,
      },
      {
        value: 'circular',
        desc: '圆',
        select: false
      },
      {
        value: 'quadrilateral',
        desc: '四边形',
        select: false
      },
      {
        value: 'polygon',
        desc: '多边形',
        select: false
      },
      {
        value: 'line',
        desc: '画笔',
        select: false
      },
      {
        value: 'eraser',
        desc: '橡皮擦',
        select: false
      },
    ];
    const colorList = [{
        value: 'red',
        desc: '红',
        select: false
      },
      {
        value: 'orange',
        desc: '橙',
        select: true
      },
      {
        value: 'yellow',
        desc: '黄',
        select: false
      },
      {
        value: 'green',
        desc: '绿',
        select: false
      },
      {
        value: 'young',
        desc: '青',
        select: false
      },
      {
        value: 'blue',
        desc: '蓝',
        select: false
      },
      {
        value: 'purple',
        desc: '紫',
        select: false
      },
    ];
    const lineWidthList = [{
        value: '1',
        desc: '1',
        select: true
      },
      {
        value: '2',
        desc: '2',
        select: false
      },
      {
        value: '3',
        desc: '3',
        select: false
      },
      {
        value: '4',
        desc: '4',
        select: false
      },
      {
        value: '5',
        desc: '5',
        select: false
      },
      {
        value: '6',
        desc: '6',
        select: false
      },
      {
        value: '7',
        desc: '7',
        select: false
      },
      {
        value: '8',
        desc: '8',
        select: false
      },
      {
        value: '9',
        desc: '9',
        select: false
      },
      {
        value: '10',
        desc: '10',
        select: false
      },
      {
        value: '20',
        desc: '20',
        select: false
      },
      {
        value: '30',
        desc: '30',
        select: false
      },
      {
        value: '50',
        desc: '50',
        select: false
      },
      {
        value: '100',
        desc: '100',
        select: false
      },
    ]
    const accuracyList = [{
        value: '0',
        desc: '整数',
        select: true
      },
      {
        value: '10',
        desc: '一位小数',
        select: false
      },
      {
        value: '100',
        desc: '二位小数',
        select: false
      },
      {
        value: '1000',
        desc: '3位小数',
        select: false
      },
    ];
    class Draw {
      constructor() {
        this.id = '';
        this.c1 = document.getElementById('canvas1');
        this.c2 = document.getElementById('canvas2');
        this.c1.width=this.c2.width = document.body.clientWidth;
        this.c1.height=this.c2.height = document.body.clientHeight - 60;
        // this.drawImage();
        this.x = '';
        this.y = '';
        this.ctx1 = this.c1.getContext('2d');
        this.ctx2 = this.c2.getContext('2d');
        this.mouseType = 'up'; // 鼠标状态
        this.handlerType = this.addOption('handlerSelect'); // 绘制类型
        this.color = this.addOption('colorSelect'); // 绘制颜色
        this.lineWidth = this.addOption('lineWidthSelect'); // 线条宽度
        this.ccuracy = this.addOption('accuracySelect'); // 数据精确度
        this.currentObj = null; // 临时数据
        this.clickNumber = 0;
        this.correct = {};
        this.mouseDownData = {
          point: (obj) => {
            if (this.handlerType !== 'point') return;
            this.currentObj = obj; // 临时数据
          },
          straightLine: (obj) => {
            const {
              x,
              y
            } = obj;
            this.currentObj = {
              startX: x,
              startY: y
            };
          },
          line: (obj) => {
            const {
              x,
              y
            } = obj;
            this.ctx1.save();
            this.ctx1.beginPath();
            this.ctx1.moveTo(x, y);
          },
          straightLineConnection: (obj) => {},
          circular: (obj) => {
            const {
              x,
              y
            } = obj;
            this.currentObj = {
              startX: x,
              startY: y
            };
          },
          quadrilateral: (obj) => {
            const {
              x,
              y
            } = obj;
            this.currentObj = {
              startX: x,
              startY: y
            };
          },
          polygon: (obj) => {},
          eraser: (obj) => {

          }
        };
        this.mouseMoveData = {
          straightLine: (obj) => { // 直线
            this.drawStraightLine(this.ctx2, obj);
          },
          straightLineConnection: (obj) => {
            if (this.mouseType === 'down') return;
            this.drawStraightLineConnection('move', this.ctx2, obj);
          },
          line: (obj) => { // 画笔
            this.currentObj = obj; // 临时数据
            this.drawLine();
          },
          circular: (obj) => {
            this.drawCirclaur(this.ctx2, obj);
          },
          quadrilateral: (obj) => {
            this.drawQuadrilateral(this.ctx2, obj);
          },
          polygon: (obj) => {
            if (this.mouseType === 'down') return;
            this.drawPolygon('move', this.ctx2, obj);
          },
          eraser: (obj) => {
            this.drawEraser(obj);
          }
        };
        this.mouseUpData = {
          point: (obj) => {
            this.drawPoint();
            this.currentObj = null;
          },
          line: (obj) => {
            this.currentObj = null;
          },
          straightLine: (obj) => { // 直线
            this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
            this.drawStraightLine(this.ctx1, obj);
            console.log('直线:', this.currentObj, obj);
            this.currentObj = null;
          },
          straightLineConnection: (obj) => {
            this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
            this.drawStraightLineConnection('up', this.ctx2, obj);
          },
          circular: (obj) => {
            this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
            this.drawCirclaur(this.ctx1, obj);
            console.log('圆:', this.currentObj, obj);
            this.currentObj = null;
          },
          quadrilateral: (obj) => {
            this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
            this.drawQuadrilateral(this.ctx1, obj);
            console.log('四边形:', this.currentObj, obj);
            this.currentObj = null;
          },
          polygon: (obj) => {
            this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
            this.drawPolygon('up', this.ctx2, obj);
          },
          eraser: (obj) => {}
        }
      }
      // drawImage(){
      //   let img = new Image();
      //   img.src = './imgs/dt.png';
      //   img.onload = ()=>{
      //     this.ctx1.drawImage(img,0,0,this.c1.width,this.c1.height);
      //   }
      // }
      mouseHandler() { // 鼠标点击、拖动事件
        this.c2.onmousedown = (e) => {
          this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
          this.handlerType = this.addOption('handlerSelect'); // 绘制类型
          this.color = this.addOption('colorSelect'); // 绘制颜色
          this.lineWidth = this.addOption('lineWidthSelect'); // 线条宽度
          this.ccuracy = this.addOption('accuracySelect'); // 线条宽度
          this.mouseType = 'down';
          this.mouseDownData[this.handlerType] && this.mouseDownData[this.handlerType]({
            x: e.offsetX,
            y: e.offsetY,
            c: this.color,
            w: this.lineWidth,
          });
        }
        this.c2.onmousemove = (e) => {
          this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
          this.x = e.offsetX;
          this.y = e.offsetY;
          this.ctx2.save();
          this.ctx2.beginPath();
          this.ctx2.strokeStyle = 'rgba(2,2,2,.2)';
          this.ctx2.lineWidth = 1;
          this.ctx2.setLineDash([5, 5]);
          this.ctx2.moveTo(this.x, 0);
          this.ctx2.lineTo(this.x, this.c2.height);
          this.ctx2.moveTo(0, this.y);
          this.ctx2.lineTo(this.c2.width, this.y);
          this.ctx2.stroke();
          this.ctx2.restore();
          this.handlerType = this.addOption('handlerSelect'); // 绘制类型
          this.color = this.addOption('colorSelect'); // 绘制颜色
          this.lineWidth = this.addOption('lineWidthSelect'); // 线条宽度
          this.ccuracy = this.addOption('accuracySelect'); // 线条宽度
          if (this.handlerType === 'eraser') {
            this.mouseMoveData[this.handlerType] && this.mouseMoveData[this.handlerType]({
              x: e.offsetX,
              y: e.offsetY,
              c: this.color,
              w: this.lineWidth,
            });
            return;
          }
          if ((this.handlerType === 'polygon' || this.handlerType === 'straightLineConnection') && this
            .currentObj) {
            this.mouseMoveData[this.handlerType] && this.mouseMoveData[this.handlerType]({
              x: e.offsetX,
              y: e.offsetY,
              c: this.color,
              w: this.lineWidth,
            });
            return;
          }

        
          if (this.mouseType === 'up') {
            let {
              px,
              py
            } = this.showTextPosition(this.x, this.y);
            this.ctx2.beginPath();
            this.ctx2.save();
            this.ctx2.fillText(`x:${this.x},y:${this.y}`, px, py);
            this.ctx2.restore();
            return;
          }
          

          this.mouseMoveData[this.handlerType] && this.mouseMoveData[this.handlerType]({
            x: e.offsetX,
            y: e.offsetY,
            c: this.color,
            w: this.lineWidth,
          });
        }
        this.c2.onmouseup = (e) => {
          this.mouseType = 'up';
          if (e.button === 2) { // 鼠标右键
            // console.log('右键1')
          } else {
            this.c2.onpointermove = null;
            this.mouseUpData[this.handlerType] && this.mouseUpData[this.handlerType]({
              x: e.offsetX,
              y: e.offsetY,
              c: this.color,
              w: this.lineWidth,
            });
          }
        }
        this.c2.ondblclick = (e) => {
          this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
          if ((this.handlerType === 'polygon')) {
            this.drawPolygon('up', this.ctx1, null);
            console.log('多边形:', this.currentObj);
          } else if (this.handlerType === 'straightLineConnection') {
            console.log('直线连接:', this.currentObj);
            this.drawStraightLineConnection('up', this.ctx1, null);
          }
          this.currentObj = null;
        }
        this.c2.oncontextmenu = (e) => {
          e.preventDefault();
          console.log('右键2')
          this.ctx2.clearRect(0, 0, this.c2.width, this.c2.width);
          if ((this.handlerType === 'polygon')) {
            this.drawPolygon('up', this.ctx1, null);
            console.log('多边形:', this.currentObj);
          } else if (this.handlerType === 'straightLineConnection') {
            this.drawStraightLineConnection('up', this.ctx1, null);
            console.log('直线连接:', this.currentObj);
          }
          this.currentObj = null;
        }
        document.getElementById('clear').onclick = e => {
          this.ctx1.clearRect(0, 0, this.c1.width, this.c1.height);
          // this.drawImage();
        }
        document.getElementById('eraser').onclick = e => {
          handlerList.forEach(item => {
            if (item.value === 'eraser') {
              item.select = true;
            } else {
              item.select = false;
            }
          })
          this.addOption('handlerSelect', handlerList);
        }
      }
      drawPoint() { // 点
        const {
          x,
          y,
          w,
          c,
        } = this.currentObj;
        this.ctx1.save();
        this.ctx1.beginPath();
        this.ctx1.fillStyle = c;
        this.ctx1.arc(x, y, w, 0, Math.PI * 2, false);
        this.ctx1.fill();
        this.ctx1.closePath();
        this.ctx1.restore();
        console.log('点:', this.currentObj);
      }
      drawLine(ctx, obj) { // 线
        const {
          x,
          y,
          c,
          w
        } = this.currentObj;
        this.ctx1.strokeStyle = c;
        this.ctx1.lineWidth = w;
        // 2miter : 尖角 默认 // bevel : 斜角 // round : 圆角
        this.ctx1.lineJoin = 'round';
        // butt 默认。向线条的每个末端添加平直的边缘。 // round  向线条的每个末端添加圆形线帽。 // square 向线条的每个末端添加正方形线帽。
        this.ctx1.lineCap = 'round';
        this.ctx1.lineTo(x, y);
        this.ctx1.stroke();
        this.ctx1.restore();
        console.log('线:', obj);
      }
      drawStraightLine(ctx, obj) {
        const {
          startX,
          startY
        } = this.currentObj;
        const {
          x,
          y,
          c,
          w
        } = obj;
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(startX, startY);
        ctx.strokeStyle = c;
        ctx.lineWidth = w;
        // miter : 尖角 默认
        // bevel : 斜角
        // round : 圆角
        ctx.lineJoin = 'round';
        // butt 默认。向线条的每个末端添加平直的边缘。
        // round  向线条的每个末端添加圆形线帽。
        // square 向线条的每个末端添加正方形线帽。
        ctx.lineCap = 'round';
        const {
          angle,
          length,
          modifyX,
          modifyY,
        } = this.calculation(startX, startY, x, y);
        if (ctx === this.ctx2) {
          let {
            px,
            py
          } = this.showTextPosition(modifyX, modifyY, 145);
          ctx.fillText(`长度:${length},角度:${angle}`, px, py);
        }
        ctx.lineTo(modifyX, modifyY);
        ctx.stroke();
        ctx.restore();
      }
      drawCirclaur(ctx, obj) { // 圆
        const {
          startX,
          startY
        } = this.currentObj;
        const {
          x,
          y,
          c,
          w
        } = obj;
        ctx.save();
        ctx.beginPath();

        ctx.strokeStyle = c;
        ctx.lineWidth = w;
        // miter : 尖角 默认
        // bevel : 斜角
        // round : 圆角
        ctx.lineJoin = 'round';
        // butt 默认。向线条的每个末端添加平直的边缘。
        // round  向线条的每个末端添加圆形线帽。
        // square 向线条的每个末端添加正方形线帽。
        ctx.lineCap = 'round';
        const {
          length,
          modifyX,
          modifyY,
        } = this.calculation(startX, startY, x, y);
        if (ctx === this.ctx2) {
          let {
            px,
            py
          } = this.showTextPosition(modifyX, modifyY);
          ctx.fillText(`半径:${length}`, px, py);
        }
        let r = Math.sqrt(Math.pow(Math.abs(x - startX), 2) + Math.pow(Math.abs(y - startY), 2));
        ctx.moveTo(startX + length, startY);
        ctx.arc(startX, startY, length, 0, Math.PI * 2, false);
        ctx.stroke();
        ctx.restore();
      }
      drawQuadrilateral(ctx, obj) { // 四边形
        const {
          startX,
          startY
        } = this.currentObj;
        const {
          x,
          y,
          c,
          w
        } = obj;
        ctx.save();
        ctx.beginPath();
        ctx.strokeStyle = c;
        ctx.lineWidth = w;
        // miter : 尖角 默认
        // bevel : 斜角
        // round : 圆角
        ctx.lineJoin = 'round';
        // butt 默认。向线条的每个末端添加平直的边缘。
        // round  向线条的每个末端添加圆形线帽。
        // square 向线条的每个末端添加正方形线帽。
        ctx.lineCap = 'round';
        ctx.moveTo(startX, startY);
        const {
          lengthX,
          lengthY,
          modifyX,
          modifyY,
        } = this.calculation(startX, startY, x, y);
        if (ctx === this.ctx2) {
          let {
            px,
            py
          } = this.showTextPosition(modifyX, modifyY, 145);
          ctx.fillText(`长:${lengthX},宽:${lengthY}`, px, py);
        }
        ctx.strokeRect(startX, startY, lengthX, lengthY);
        ctx.stroke();
        ctx.restore();
      }
      drawStraightLineConnection(handler, ctx, obj) {
        let arr = [];
        if (handler === 'move') {
          arr = [...this.currentObj, obj];
        } else {
          if (obj) {
            const {
              x,
              y,
              w,
              c
            } = obj;
            if (Array.isArray(this.currentObj)) {
              // console.log('存储的点', this.correct);
              this.currentObj.push({
                x: this.correct.x || x,
                y: this.correct.y || y,
                w,
                c,
                clickNumber: ++this.clickNumber
              });
            } else {
              this.clickNumber = 0;
              this.currentObj = [{
                x,
                y,
                w,
                c,
                clickNumber: ++this.clickNumber
              }];
            }
            arr = [...this.currentObj];
          }
          arr = [...this.currentObj];
        }
        ctx.save()
        ctx.beginPath();
        arr.forEach((item, index) => {
          if (index === 0) {
            ctx.moveTo(item.x, item.y);
          } else if (index > 0) {
            const {
              x,
              y,
              c,
              w
            } = item;
            ctx.strokeStyle = c;
            ctx.lineWidth = w;
            // 2miter : 尖角 默认 // bevel : 斜角 // round : 圆角
            ctx.lineJoin = 'round';
            // butt 默认。向线条的每个末端添加平直的边缘。 // round  向线条的每个末端添加圆形线帽。 // square 向线条的每个末端添加正方形线帽。
            ctx.lineCap = 'round';
            let previous = arr[index - 1];
            const {
              length,
              angle,
              modifyX,
              modifyY,
            } = this.calculation(previous.x, previous.y, x, y);
            this.correct = {
              x: modifyX,
              y: modifyY
            };
            if (ctx === this.ctx2) {
              let {
                px,
                py
              } = this.showTextPosition(modifyX, modifyY, 145);
              ctx.fillText(`长度:${length},角度:${angle}`, px, py);
            }
            ctx.lineTo(modifyX, modifyY);
          }
          ctx.stroke();
          ctx.restore();
        })
      }
      drawPolygon(handler, ctx, obj) { // 多边形
        let arr = [];
        if (handler === 'move') {
          arr = [...this.currentObj, obj];
        } else {
          if (obj) {
            const {
              x,
              y,
              w,
              c
            } = obj;
            if (Array.isArray(this.currentObj)) {
              console.log('存储的点', this.correct);
              this.currentObj.push({
                x: this.correct.x || x,
                y: this.correct.y || y,
                w,
                c,
                clickNumber: ++this.clickNumber
              });
            } else {
              this.clickNumber = 0;
              this.currentObj = [{
                x,
                y,
                w,
                c,
                clickNumber: ++this.clickNumber
              }];
            }
            arr = [...this.currentObj];
          }
          arr = [...this.currentObj];
        }
        ctx.save()
        ctx.beginPath();
        arr.forEach((item, index) => {
          if (index === 0) {
            ctx.moveTo(item.x, item.y);
          } else if (index > 0) {
            const {
              x,
              y,
              c,
              w
            } = item;
            ctx.strokeStyle = c;
            ctx.lineWidth = w;
            // 2miter : 尖角 默认 // bevel : 斜角 // round : 圆角
            ctx.lineJoin = 'round';
            // butt 默认。向线条的每个末端添加平直的边缘。 // round  向线条的每个末端添加圆形线帽。 // square 向线条的每个末端添加正方形线帽。
            ctx.lineCap = 'round';
            let previous = arr[index - 1];
            const {
              length,
              angle,
              modifyX,
              modifyY,
            } = this.calculation(previous.x, previous.y, x, y);
            this.correct = {
              x: modifyX,
              y: modifyY
            };
            if (ctx === this.ctx2) {
              let {
                px,
                py
              } = this.showTextPosition(this.x, this.y,145);
              ctx.fillText(`长度:${length},角度:${angle}`, px, py);
            }
            ctx.lineTo(modifyX, modifyY);
            if (arr.length > 2 && index === arr.length - 1) {
              ctx.closePath();
            }
          }
          ctx.stroke();
          ctx.restore();
        })
      }
      addOption(id, arr) { // 渲染select下拉列表以及获取下拉列表值
        let dom = document.getElementById(id);
        if (!arr) {
          return dom.value;
        } else {
          for (let i = 0; i < dom.childNodes.length; i++) {
            let item = dom.childNodes[i];
            dom.removeChild(item)
          }
          for (let i = 0; i < arr.length; i++) {
            const {
              value,
              desc,
              select
            } = arr[i];
            const option = document.createElement('option');
            option.value = value;
            option.text = desc;
            option.selected = select;
            dom.appendChild(option);
          }
        }
      }
      calculation(startX, startY, endX, endY) {
        let differenceX = endX - startX;
        let differenceY = endY - startY;
        let angle;
        if (differenceX >= 0 && differenceY >= 0) {
          angle = Math.atan(differenceY / differenceX) / Math.PI * 180;
        } else if (differenceX < 0 && differenceY >= 0) {
          angle = 180 + Math.atan(differenceY / differenceX) / Math.PI * 180;
        } else if (differenceX < 0 && differenceY < 0) {
          angle = 180 + Math.atan(differenceY / differenceX) / Math.PI * 180;
        } else {
          angle = 360 + Math.atan(differenceY / differenceX) / Math.PI * 180;
        }
        let length = Math.sqrt(Math.pow(Math.abs(differenceX), 2) + Math.pow(Math.abs(differenceY), 2));
        angle = this.format(angle);
        length = this.format(length);
        let currentX = this.format(Math.cos(angle / 180 * Math.PI) * length);
        let currentY = this.format(Math.sin(angle / 180 * Math.PI) * length);
        return {
          length,
          angle,
          modifyX: currentX + startX,
          modifyY: currentY + startY,
          lengthX: currentX,
          lengthY: currentY,
        }
      }
      format(value) {
        let n = this.ccuracy; // 线条宽度;
        if (n === '0') return Math.floor(value);
        return Math.floor(value * n) / n;
      }
      showTextPosition(x, y, z) {
        if (!z) z = 80;
        let px = x,
          py = y;
        if (x < 14) px = 10;
        if (x > this.c2.width - z) px = this.c2.width - z;
        if (y < 14) py = 10;
        if (y > this.c2.height - 20) py = this.c2.height - 10;
        return {
          px,
          py
        };
      };
      drawEraser(obj) { // 黑板擦
        let {
          x,
          y,
          w
        } = obj;
        w = parseFloat(w);
        if (w < 2) w = 2;
        w = w * 5;
        this.ctx2.save();
        this.ctx2.beginPath();
        this.ctx2.strokeStyle = 'black';
        this.ctx2.width = 1;
        this.ctx2.strokeRect(x - w / 2, y - w / 2, w, w);
        this.ctx1.clearRect(x - w / 2, y - w / 2, w, w)
        this.ctx2.stroke();
        this.ctx2.restore();
        // this.drawImage();
      }
    };
    let draw = new Draw();
    draw.mouseHandler();
    draw.addOption('handlerSelect', handlerList);
    draw.addOption('lineWidthSelect', lineWidthList);
    draw.addOption('colorSelect', colorList);
    draw.addOption('accuracySelect', accuracyList);
  </script>
</body>

</html>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值