028-动态选择框-数据纹理

028-动态选择框-数据纹理

通过生成纹理数据,构造一个选择框。

在这里插入图片描述

1、关键代码

App.js

class App {
  generateDataTexture() {
    // 生成数据纹理并初始化为白色。
    var width = 200;
    var height = 200;
    var data = new Uint8Array(width * height * 4);
    let dataTexture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);
    for (let i = 0, j = 0; i < dataTexture.image.data.length; i += 4, j++) {
      dataTexture.image.data[i + 0] = 255
      dataTexture.image.data[i + 1] = 255
      dataTexture.image.data[i + 2] = 255
      dataTexture.image.data[i + 3] = 1
    }
    ...

    // 指定一个区域,开始画线
    const rect = {
      x: 50,
      y: 100,
      w: 50,
      h: 50
    }
    line1.drawLine({
      start: {
        x: rect.x,
        y: rect.y
      },
      end: {
        x: rect.x + rect.w,
        y: rect.y
      },
      lineWidth: 2,
      color: "ff0000",
      imgWidth: 200,
      imgData: dataTexture.image.data
    })
  }
}

Line.js

export default class Line {
  ...
  drawLine({ start, end, color, lineWidth, imgData, imgWidth }) {
    let point = 2
    for (let x = start.x; x < end.x; x += 1) {
      if (x % point == 0 && this.falg == true) {
        Line.setPixel(x, start.y, color, imgWidth, imgData)
        continue
      }

      if (x % point == 1 && this.falg == false) {
        Line.setPixel(x, start.y, color, imgWidth, imgData)
        continue
      }
    }

    for (let y = start.y; y < end.y; y += 1) {
      if (y % point == 0 && this.falg == true) {
        Line.setPixel(start.x, y, color, imgWidth, imgData)
        continue
      }
      if (y % point == 1 && this.falg == false) {
        Line.setPixel(start.x, y, color, imgWidth, imgData)
        continue
      }
    }

    this.falg = !this.falg
  }
}

2、完整代码

App.js

import * as THREE from './lib/three.module.js'
import { Stage } from './Stage.js'
import Line from './Line.js'

window.THREE = THREE
let line1 = new Line()
let line2 = new Line()
let line3 = new Line()
let line4 = new Line()

let that = null
let count = 0
// var dataTexture = []

class App {
  constructor() {
    that = this
    this.srcTexturen = null
    this.stage = new Stage("#app")
    window.lm = this.stage
    this.addBox()
    this.stage.run()
  }



  generateDataTexture() {
    var width = 200;
    var height = 200;
    var data = new Uint8Array(width * height * 4);
    let dataTexture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);
    for (let i = 0, j = 0; i < dataTexture.image.data.length; i += 4, j++) {
      dataTexture.image.data[i + 0] = 255
      dataTexture.image.data[i + 1] = 255
      dataTexture.image.data[i + 2] = 255
      dataTexture.image.data[i + 3] = 1
    }

    const rect = {
      x: 50,
      y: 100,
      w: 50,
      h: 50
    }

    line1.drawLine({
      start: {
        x: rect.x,
        y: rect.y
      },
      end: {
        x: rect.x + rect.w,
        y: rect.y
      },
      lineWidth: 2,
      color: "ff0000",
      imgWidth: 200,
      imgData: dataTexture.image.data
    })
    line2.drawLine({
      start: {
        x: rect.x,
        y: rect.y
      },
      end: {
        x: rect.x,
        y: rect.y + rect.h
      },
      lineWidth: 2,
      color: "ff0000",
      imgWidth: 200,
      imgData: dataTexture.image.data
    })
    line3.drawLine({
      start: {
        x: rect.x + rect.h,
        y: rect.y
      },
      end: {
        x: rect.x,
        y: rect.y + rect.h
      },
      lineWidth: 2,
      color: "ff0000",
      imgWidth: 200,
      imgData: dataTexture.image.data
    })
    line4.drawLine({
      start: {
        x: rect.x,
        y: rect.y + rect.h
      },
      end: {
        x: rect.x + rect.w,
        y: rect.y + rect.h
      },
      lineWidth: 2,
      color: "ff0000",
      imgWidth: 200,
      imgData: dataTexture.image.data
    })
    return dataTexture
  }

  // 增加一个立方体
  addBox() {
    let texture = this.generateDataTexture()
    const material = new THREE.MeshBasicMaterial({ map: texture });
    let geometry = new THREE.BoxGeometry(10, 10, 10)
    let cube = new THREE.Mesh(geometry, material);
    cube.name = "cube"
    this.stage.scene.add(cube)
    this.stage.onUpdate(() => {
      count++
      if (count > 20) {
        let texture = this.generateDataTexture()
        cube.material.map = texture
      }

      if (count > 20) {
        count = 0
      }
    })
  }
}

window.onload = () => {
  new App()
}

Line.js


export default class Line {
  constructor() {
    this.falg = true
  }

  static getPixelColor(x, y, imgWidth, imgData) {
    const w = imgWidth
    const d = imgData

    var color = []
    color[0] = d[(y * w + x) * 4]
    color[1] = d[(y * w + x) * 4 + 1]
    color[2] = d[(y * w + x) * 4 + 2]
    color[3] = d[(y * w + x) * 4 + 3]
    let ret = Line.rgbToHex(color)
    return ret
  }

  static setPixel(x, y, color, imgWidth, imgData) {
    const w = imgWidth
    const d = imgData
    const hexColor = Line.hexToRgba(color)
    d[(y * w + x) * 4 + 0] = hexColor[0]
    d[(y * w + x) * 4 + 1] = hexColor[1]
    d[(y * w + x) * 4 + 2] = hexColor[2]
    d[(y * w + x) * 4 + 3] = 255
  }

  static rgbToHex(c) {
    const [r, g, b, a] = c
    return ((r << 16) | (g << 8) | b).toString(16);
  }

  static hexToRgba(hex) {
    let ret = []
    ret[0] = parseInt("0x" + hex.slice(0, 2))
    ret[1] = parseInt("0x" + hex.slice(2, 4))
    ret[2] = parseInt("0x" + hex.slice(4, 6))
    return ret
  }

  drawLine({ start, end, color, lineWidth, imgData, imgWidth }) {
    let point = 2
    for (let x = start.x; x < end.x; x += 1) {
      if (x % point == 0 && this.falg == true) {
        Line.setPixel(x, start.y, color, imgWidth, imgData)
        continue
      }

      if (x % point == 1 && this.falg == false) {
        Line.setPixel(x, start.y, color, imgWidth, imgData)
        continue
      }
    }

    for (let y = start.y; y < end.y; y += 1) {
      if (y % point == 0 && this.falg == true) {
        Line.setPixel(start.x, y, color, imgWidth, imgData)
        continue
      }
      if (y % point == 1 && this.falg == false) {
        Line.setPixel(start.x, y, color, imgWidth, imgData)
        continue
      }
    }

    this.falg = !this.falg


  }
}

<全文结束>

发布了74 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_21476953/article/details/104191678