css - HTML Canvas,多边形相互连接

标签 css reactjs next.js html5-canvas polygon

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

polygons

我正在 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

大家有什么想法吗?

最佳答案

错误是由于您将数据源中的所有区域合并到一条长路径中而导致的。这发生在 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();
});

enter image description here


关于 Kaiido 的评论,您可以考虑利用 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();

关于css - HTML Canvas,多边形相互连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69188642/

相关文章:

css - 如何使用 Bootstrap 3 将两个图像并排居中?

javascript - 如何在 extjs 显示字段中将 HTML 标签显示为纯文本

具有 100% 宽度和高度的 HTML 填充?

reactjs - NextJS URL 参数,如 React-Router

javascript - 我无法安装我的项目包

next.js - 如何在 Next.js 中在移动设备上显示不同大小的图像

html - 以当今现代方式使用 "caption"HTML 元素的最合适方式是什么?

javascript - 报错 "Type ' void' is not assignable to type 'ReactNode' "

javascript - 浅渲染找不到组件

reactjs - React Context - Context.Consumer 与 Class.contextType