【问题标题】:HTML Canvas, Polygons are connected each otherHTML Canvas,多边形相互连接
【发布时间】:2021-11-10 06:41:22
【问题描述】:

我正在尝试从一个很大的json 文件生成多个多边形。多边形应该相互分离,但它却以某种方式相互连接。

我正在 next.js 中构建它。

代码如下:

Canvas.tsx

// ../components/Canvas.tsx

import React, { useRef, useEffect } from 'react'

const Canvas = props => {
  
  const canvasRef = useRef(null)
  
  useEffect(() => {
    const canvas: any = canvasRef.current
    const context = canvas.getContext('2d')

    context.fillStyle = '#FF0000'
    context.beginPath()
    { props.x.map((pointx, i) => context.lineTo(0.25 * pointx, 0.25 * props.y[i])) } // I scaled it to 0.25 (25% original size)
    context.closePath()
    context.fill()
  }, [])
  
  return <canvas ref={canvasRef} {...props} width={props.width} height={props.height} style={{ zIndex: 20, position: 'absolute', objectFit: 'contain' }}/>
}

export default Canvas

index.tsx

import React, { ReactElement, useEffect, useRef, useState } from 'react'
import Image from 'next/image'
import dynamic from "next/dynamic";
import data from '../public/11_regions-copy.json'
import Canvas from '../components/Canvas';


export const getServerSideProps = async () => {

  let xTemp: any[] = []
  let yTemp: any[] = []

  for (var i = 0; i < Object.keys(data).length; i++) {
    xTemp.push(data[i].all_points_x)
    yTemp.push(data[i].all_points_y)
  }
  for (var j = 0; j < Object.keys(data).length; j++) {
    let xArray = xTemp[j]
    xArray.push(xArray[0])

    let yArray = yTemp[j]
    yArray.push(yArray[0])
  }
  
  let x = [].concat.apply([], xTemp);
  let y = [].concat.apply([], yTemp);


  return {
    props: {
      x,
      y
    },
  }
}

function Home({ x, y, xTemp1, yTemp1 }: any): ReactElement {

  return (
    <div>
      <Canvas width={1680} height={756} x={x} y={y} />
    </div>
  )
}

export default Home

json 文件: json

有人有什么想法吗?

【问题讨论】:

    标签: css reactjs next.js html5-canvas polygon


    【解决方案1】:

    错误是您将数据源中的所有区域合并到一条长路径的结果。这发生在getServerSideProps(有点笨重顺便说一句。)。

    因此,您的数据如下所示:

    {
        "0": {
    
            "all_points_x": [ ... ],
            "all_points_y": [ ... ]
        },
        "1": {
            "all_points_x": [ ... ],
            "all_points_y": [ ... ]
        },
        // ...
    }
    

    您的getServerSideProps 会这样做:

    {
        props: {
            x: [ ... ],
            y: [ ... ],
        }
    }
    

    然后你在这里画一条长路:

    context.beginPath()
    { props.x.map((pointx, i) => context.lineTo(0.25 * pointx, 0.25 * props.y[i])) }
    context.closePath()
    context.fill()
    

    如果你停止这样做,并简单地将每个 区域 绘制为单独的路径,你会得到你想要的:

    // here `data` would be something like:
    // const data = await (await fetch('11_regions-copy.json')).json();
    
    Object.values(data).forEach(({all_points_x: x, all_points_y: y}) => {
      ctx.beginPath();
    
      x.forEach((x, i) => {
        ctx.lineTo(0.25 * x, 0.25 * y[i]);
      });
    
      ctx.closePath();
      ctx.fill();
    });
    


    关于凯多的评论,你可以考虑画一条路,利用moveTo

    ctx.beginPath();
    
    Object.values(data).forEach(({all_points_x: x, all_points_y: y}) => {
      ctx.moveTo(0.25 * x[0], 0.25 * y[0]);
    
      x.forEach((x, i) => {
        ctx.lineTo(0.25 * x, 0.25 * y[i]);
      });
    });
    
    ctx.closePath();
    ctx.fill();
    

    【讨论】:

    • @Kaiido 是的,也许吧。尽管在某种程度上必须将这些区域分开。如果通过单独绘制它们或在moveTo 的帮助下将它们绘制成一条长路径,则可以考虑。尽管只要区域像现在这样合并,这两种方法都是不可能的。
    • 不是“也许”,绘制多个简单的形状总是比绘制一个更复杂的形状要慢。我不明白你的其余评论。
    • 好吧,显然你在这方面是正确的。我的 也许 是关于这是否真的会成为 OP 的问题,因为目前只有很少的地区。 // 我剩下的评论是关于这个问题的实际问题。 OP 将所有区域 合并 到一个大 region 中,从而丢失有关区域开始和结束位置的所有信息。
    • "OP 将所有区域合并为一个大区域,从而丢失有关区域开始和结束位置的所有信息。"我看不出问题中哪里提到这对他们来说是个问题。
    • 那你看过我的回答了吗?我基本上是在引导读者/ OP通过它?在测试项目中使用问题中的确切代码也会产生与问题中完全相同的问题输出。
    猜你喜欢
    • 2013-04-18
    • 1970-01-01
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多