javascript 在画布上使用铅笔绘制的像素未居中

3okqufwl  于 2024-01-05  发布在  Java
关注(0)|答案(3)|浏览(140)

我用p5.js在画布上用铅笔画像素。问题是,在这种情况下,当铅笔大小为1或更小时,它的位置不是居中的。它是左,右,不是居中的。

我在代码中注意到一个有趣的现象,当鼠标的x和y位置接近0.5时,绘制的像素似乎居中;然而,在其他情况下,像素似乎有点偏离中心。为了解决这个问题,我正在考虑改进我们的渲染逻辑。我将确保将像素密度设置为1,以防止任何自动缩放问题。另外,我可能会尝试通过引入一个校正因子来调整像素的位置,也许是从x和y坐标中减去0.5。在我们的代码中仔细检查任何可能影响像素精确位置的转换或缩放操作是至关重要的。

我注意到P5.image.set方法似乎不接受浮点数;它四舍五入到最接近的整数。有人找到解决这个问题的方法吗?或者我在文档中遗漏了什么?
Here是代码。Here是部署的应用程序。
生成问题的步骤:-
1.打开链接
1.缩放(鼠标键+滚轮)
1.选择铅笔
1.鼠标按在画布上
提前感谢。如果有任何疑问的意见,我会添加更多的清晰度。
下面是我们在for循环中设置像素值的mousepressed方法的代码

mousePressed(mouseX, mouseY) {
      if (this.menuSelection === 'drawPencil') {
        this.mapImage.loadPixels()
        let size = 1
        let y = mouseY
        for (let i = mouseX - size / 2; i < mouseX + size / 2; i++) {
          for (let j = y - size / 2; j < y + size / 2; j++) {
            this.mapImage.set(i, j, this.p5.color(255))
            //console.log('i,j', i, j)
          }
        }
        this.mapImage.updatePixels()
        return
      }
    },

字符串
x1c 0d1x的数据

wbrvyc0a

wbrvyc0a1#

你说过:
我注意到P5.image.set方法似乎不接受浮点数;**它四舍五入到最接近的整数。**是否有人找到了解决此问题的方法,或者我在文档中遗漏了什么?
正因为如此,你需要始终地板的价值观,
所以0.9必须被设置为0,即使它更接近1。所以在将其传递给P5.image.set方法之前,您应该将任何浮点数降到最低。
x1c 0d1x的数据
举例来说:这里的图像按比例放大以适应屏幕,因此在此图像中,如果您单击绿色区域,您将选择像素A而不是B(这是由舍入浮点值引起的),如果您自己对值进行地板处理,则将选择B

n7taea2i

n7taea2i2#

所有发生的是,当点击绘制用户需要滚动,它得到的位置在屏幕上的鼠标位置,而不是在画布上。

p5.mousePressed = () => {
        ;(this.x_value = p5.mouseX), (this.y_value = p5.mouseY)
        // if (this.firstTime) {
        this.mx = p5.mouseX
        this.my = p5.mouseY
        this.firstTime = false
        // }

        this.mousePressedFlag = true
        this.mousePressed(p5.mouseX, p5.mouseY)
      }

个字符
更新这些功能并检查它是否能按您的要求工作。

已更新

我已经尝试了一些不同的方法,它的工作正常,因为你想要的,但需要固定,因为我已经重写了一些代码。

import p5 from 'p5'

export default {
  data() {
    return {
      imageLoad: null,
      menuSelection: null,
      mapImage: null,
      x_value: 0,
      y_value: 0,
      mousePressedFlag: false,
      sf: 1,
      mx: 0,
      my: 0,
      zoom: 1,
      loadImageWidth: 1500,
      loadImageHeight: 700,
      arrZoomScale: [
        0.1, 0.25, 0.33, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 3, 3.5, 4, 4.5, 5, 6, 7, 8,
        10, 12
      ],
      viewPort: {
        width: 0,
        height: 0
      },
      points: [],
      firstTime: true
    }
  },
  mounted() {
    let p5Handler = (p5) => {
      p5.preload= () => {
        this.imageLoad = p5.loadImage('image.png', (img) => {
          p5.resizeCanvas(img.width, img.height)
        })
      }
      p5.setup = () => {
        const canvas = p5.createCanvas(1500, 700)
        canvas.parent(this.$refs.p5Container)
        p5.imageMode(p5.CENTER)
        p5.noStroke()
      }
      p5.draw = () => {
        this.draw(p5)
      }
      p5.mouseClicked = (event) => {
        ;(this.x_value = event.clientX), (this.y_value = event.clientY)
        // if (this.firstTime) {
        this.mx = (event.clientX  - p5.width / 2) / this.zoom
        this.my = (event.clientY  - p5.height / 2) / this.zoom
        this.firstTime = false
        // }

        this.mousePressedFlag = true
        this.mousePressed(event.clientX, event.clientY)
      }

      p5.mouseWheel = (event) => {
        this.mouseWheel(event)
      }
    }
    let P5 = p5
    this.p5 = new P5(p5Handler)
  },
  methods: {
    draw(p5) {
      p5.background(255);
      p5.translate(p5.width / 2, p5.height / 2);
      p5.scale(this.zoom);
      p5.image(this.imageLoad, 0, 0);

      this.points.forEach(({ x, y, size }) => {
        p5.fill(255, 255, 255)
        p5.rect(x, y, size)
      })

      if (this.menuSelection === 'drawPencil') {
        p5.translate(this.mx, this.my)
        p5.translate(-this.mx, -this.my)
        p5.translate()

        p5.cursor(p5.CROSS)
        p5.strokeWeight(0.3 / this.zoom)
        p5.noFill()
        p5.stroke(69, 69, 69)
        p5.rect((p5.mouseX - p5.width / 2) / this.zoom, (p5.mouseY - p5.height / 2) / this.zoom, 1)
      }
    },
    mousePressed(mouseX, mouseY) {
      const cMouseX = (mouseX - this.p5.width / 2) / this.zoom
      const cMouseY = (mouseY - this.p5.height / 2) / this.zoom
      this.points.push({ x: cMouseX, y: cMouseY, size: 1 })
    },
    mouseWheel(event) {
      /* const delta = this.p5.constrain(event.deltaY * 0.01, -0.2, 0.2)
      this.zoom += delta
      this.zoom = this.p5.constrain(this.zoom, 0.1, 5) */

      if (this.mousePressedFlag) {
        if (event.deltaY > 0) {
          this.zoomOut()
        } else {
          this.zoomIn()
        }
      }
    },
    zoomIn() {
      for (let zoom of this.arrZoomScale) {
        if (zoom > this.zoom) {
          this.setZoom(zoom, 'zoomIn')
          break
        }
      }
    },
    zoomOut() {
      // Sort the array of zoom scales in ascending order
      this.arrZoomScale.sort((a, b) => a - b);

      // Find the index of the zoom level in the array that is just smaller than the current zoom
      const index = this.arrZoomScale.findIndex(scale => scale >= this.zoom) - 1;

      if (index >= 0) {
        const newZoom = this.arrZoomScale[index];
        console.log(newZoom)
        this.setZoom(newZoom, 'zoomOut');
      }
    },
    setZoom(newZoom, val) {
      if (val === 'zoomIn') {
        this.sf = newZoom
      } else if (val === 'zoomOut') {
        this.sf = newZoom
      }
      this.zoom = newZoom
    },
  }
}


链接帮助很多:

lvmkulzt

lvmkulzt3#

请添加下面的代码

p5.mouseMoved = (event) => {
   this.mouseMoved(event)
}

字符串

p5.mouseWheel = (event) => {
   this.mouseWheel(event)
}


然后修改方法代码块如下,

methods: {
    draw(p5) {
      let ctx = p5;
      if (this.mousePressedFlag) {
        p5.translate(this.mx, this.my);
        p5.scale(this.sf);
        p5.translate(-this.mx, -this.my);
      }

      this.drawMapImage(ctx); // ctx as arg
      if (this.menuSelection === 'drawPencil') {
        this.p5.cursor(this.p5.CROSS);
        p5.strokeWeight(0.3 / this.zoom);
        p5.noFill();
        p5.stroke(69, 69, 69);
        p5.rect(p5.mouseX - 0.5, p5.mouseY - 0.5, 1, 1); // Adjusted pixel position
      }
    },
    mousePressed(mouseX, mouseY) {
      if (this.menuSelection === 'drawPencil') {
        this.mapImage.loadPixels();
        let size = 1;
        let y = mouseY;
        for (let i = mouseX - size / 2; i < mouseX + size / 2; i++) {
          for (let j = y - size / 2; j < y + size / 2; j++) {
            this.mapImage.set(Math.floor(i), Math.floor(j), this.p5.color(255)); // Use Math.floor to ensure integer coordinates
          }
        }
        this.mapImage.updatePixels();
        return;
      }
    },
    mouseMoved() {
      if (this.mousePressedFlag) {
        this.setZoomCenter(this.p5.mouseX, this.p5.mouseY);
      }
    },
    mouseWheel(event) {
      if (this.mousePressedFlag) {
        let zoomChange = event.deltaY > 0 ? -0.1 : 0.1; // Adjust the zoom factor as needed
        this.setZoom(this.zoom + zoomChange);
        this.setZoomCenter(this.p5.mouseX, this.p5.mouseY);
      }
    },
    drawMapImage(p5) {
      let ctx = this.mapImage.drawingContext
      ctx.imageSmoothingEnabled = false
      this.imageContext = ctx

      ctx = p5.canvas.getContext('2d')
      ctx.imageSmoothingEnabled = false
      this.htmlContext = ctx

      p5.push()

      p5.image(
        this.mapImage,
        0,
        0,
        this.viewPort.width / this.zoom,
        this.viewPort.height / this.zoom
      )
      p5.pop()
    },
    zoomIn() {
      for (let zoom of this.arrZoomScale) {
        if (zoom > this.zoom) {
          this.setZoom(zoom, 'zoomIn')
          break
        }
      }
    },
    zoomOut() {
      for (let i = this.arrZoomScale.length - 1; i >= 0; i--) {
        let zoom = this.arrZoomScale[i]
        if (zoom < this.zoom) {
          this.setZoom(zoom, 'zoomOut')
          break
        }
      }
    },
    setZoom(newZoom) {
      this.sf = newZoom;
      this.zoom = newZoom;
      this.recalViewPort();
    },
    setZoomCenter(x, y) {
      this.mx = x;
      this.my = y;
    },
    recalViewPort() {
      this.viewPort.width = this.zoom * this.loadImageWidth
      this.viewPort.height = this.zoom * this.loadImageHeight
    }
  }

相关问题