Skip to content

Commit

Permalink
v1.1.0 (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
IcculusC authored Oct 29, 2018
1 parent d5304bd commit 0c8c1f2
Show file tree
Hide file tree
Showing 10 changed files with 229 additions and 285 deletions.
3 changes: 1 addition & 2 deletions .storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import * as storybook from "@storybook/react";
import { setOptions } from "@storybook/addon-options";

setOptions({
name: "react-hex-engine",
addonPanelInRight: true
name: "react-hex-engine"
});

function loadStories() {
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
[![Storybook](https://github.com/storybooks/press/blob/master/badges/storybook.svg)](https://icculusc.github.io/react-hex-engine)
[![CircleCI](https://circleci.com/gh/IcculusC/react-hex-engine/tree/master.svg?style=shield)](https://circleci.com/gh/IcculusC/react-hex-engine/tree/master)

[![GitHub release](https://img.shields.io/github/release/icculusc/react-hex-engine.svg)](https://github.com/IcculusC/react-hex-engine/releases/latest)
[![CircleCI branch](https://img.shields.io/circleci/project/github/IcculusC/react-hex-engine/master.svg)](https://github.com/IcculusC/react-hex-engine/tree/master)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/icculusc/react-hex-engine.svg)](https://github.com/IcculusC/react-hex-engine/pulls)
[![GitHub issues](https://img.shields.io/github/issues/icculusc/react-hex-engine.svg)](https://github.com/IcculusC/react-hex-engine/issues)
[![GitHub last commit](https://img.shields.io/github/last-commit/icculusc/react-hex-engine.svg)](https://github.com/IcculusC/react-hex-engine/commits)
[![Docs status](https://img.shields.io/badge/docs-in_progress-orange.svg)](https://icculusc.github.io/react-hex-engine/)

# react-hex-engine

Check out the [storybook](https://icculusc.github.io/react-hex-engine) for the existing documentation. Improvements to the docs are in the pipeline!

Originally forked from [https://github.com/Hellenic/react-hexgrid](https://github.com/Hellenic/react-hexgrid)

Quote from the original readme
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-hex-engine",
"description": "Hexagon Map Editor and Game Engine",
"version": "1.0.0",
"version": "1.1.0",
"main": "lib/index.js",
"author": "IcculusC",
"repository": "IcculusC/react-hex-engine",
Expand Down
217 changes: 108 additions & 109 deletions src/HexEngine.js
Original file line number Diff line number Diff line change
@@ -1,123 +1,122 @@
import React, { Component } from "react";
import React from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import { HexEngineProvider } from "./Context";
import Point from "./models/Point";
import Orientation from "./models/Orientation";

class HexEngine extends Component {
static propTypes = {
children: PropTypes.node.isRequired,
classes: PropTypes.objectOf(PropTypes.string),
/** Determines if the hexagons are oriented with a point or an edge facing up */
flat: PropTypes.bool,
/** CSS string or number */
height: PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.number.isRequired
]),
/** Origin of the grid */
origin: PropTypes.oneOfType([
PropTypes.instanceOf(Point),
PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired
})
]),
/** Size of the hexagons in each dimension */
size: PropTypes.oneOfType([
PropTypes.instanceOf(Point),
PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired
})
]),
/** Space between hexagons */
spacing: PropTypes.number,
/** CSS string or number */
width: PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.number.isRequired
]),
/** The viewBox {x,y,width,height} of the svg view area */
viewBox: PropTypes.shape({
height: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired
})
};
function getPointOffset(corner, orientation, size) {
let angle = (2.0 * Math.PI * (corner + orientation.startAngle)) / 6;
return new Point(size.x * Math.cos(angle), size.y * Math.sin(angle));
}

static defaultProps = {
classes: { grid: "", layout: "" },
flat: true,
height: 480,
origin: new Point(0, 0),
size: new Point(10, 10),
spacing: 1.0,
width: 640,
viewBox: {
height: 100,
width: 100,
x: -50,
y: -50
}
};
function calculateCoordinates(orientation, size) {
const center = new Point(0, 0);
return [...Array(6).keys()].map((_, i) => {
const offset = getPointOffset(i, orientation, size);
return new Point(center.x + offset.x, center.y + offset.y);
});
}

static getPointOffset(corner, orientation, size) {
let angle = (2.0 * Math.PI * (corner + orientation.startAngle)) / 6;
return new Point(size.x * Math.cos(angle), size.y * Math.sin(angle));
}
const HexEngine = props => {
const {
children,
classes,
flat,
height,
origin,
size,
spacing,
viewBox,
width
} = props;

static calculateCoordinates(orientation, size) {
const center = new Point(0, 0);
return [...Array(6).keys()].map((_, i) => {
const offset = HexEngine.getPointOffset(i, orientation, size);
return new Point(center.x + offset.x, center.y + offset.y);
});
}
const orientation = flat ? Orientation.Flat : Orientation.Pointy;
const points = calculateCoordinates(orientation, size)
.map(point => point.toString())
.join(" ");
const layout = { orientation, origin, size, spacing };

render() {
const {
children,
classes,
flat,
height,
origin,
size,
spacing,
viewBox,
width
} = this.props;
return (
<svg
key={JSON.stringify(layout)}
className={classNames("grid", classes.grid)}
height={height}
version="1.1"
viewBox={`${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`}
width={width}
xmlns="http://www.w3.org/2000/svg"
>
<HexEngineProvider
value={{
layout,
points,
viewBox
}}
>
<g className={classes.layout}>{children}</g>
</HexEngineProvider>
</svg>
);
};

const orientation = flat ? Orientation.Flat : Orientation.Pointy;
const points = HexEngine.calculateCoordinates(orientation, size)
.map(point => point.toString())
.join(" ");
const layout = { orientation, origin, size, spacing };
HexEngine.propTypes = {
children: PropTypes.node.isRequired,
classes: PropTypes.objectOf(PropTypes.string),
/** Determines if the hexagons are oriented with a point or an edge facing up */
flat: PropTypes.bool,
/** CSS string or number */
height: PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.number.isRequired
]),
/** Origin of the grid */
origin: PropTypes.oneOfType([
PropTypes.instanceOf(Point),
PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired
})
]),
/** Size of the hexagons in each dimension */
size: PropTypes.oneOfType([
PropTypes.instanceOf(Point),
PropTypes.shape({
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired
})
]),
/** Space between hexagons */
spacing: PropTypes.number,
/** CSS string or number */
width: PropTypes.oneOfType([
PropTypes.string.isRequired,
PropTypes.number.isRequired
]),
/** The viewBox {x,y,width,height} of the svg view area */
viewBox: PropTypes.shape({
height: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
x: PropTypes.number.isRequired,
y: PropTypes.number.isRequired
})
};

return (
<svg
key={JSON.stringify(layout)}
className={classNames("grid", classes.grid)}
height={height}
version="1.1"
viewBox={`${viewBox.x} ${viewBox.y} ${viewBox.width} ${viewBox.height}`}
width={width}
xmlns="http://www.w3.org/2000/svg"
>
<HexEngineProvider
value={{
layout,
points,
viewBox
}}
>
<g className={classes.layout}>{children}</g>
</HexEngineProvider>
</svg>
);
HexEngine.defaultProps = {
classes: { grid: "", layout: "" },
flat: true,
height: 480,
origin: new Point(0, 0),
size: new Point(10, 10),
spacing: 1.0,
width: 640,
viewBox: {
height: 100,
width: 100,
x: -50,
y: -50
}
}
};

export default HexEngine;
export const HexEngine_ = HexEngine;
export default HexEngine_;
62 changes: 26 additions & 36 deletions src/Path.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,35 @@
import React, { Component } from "react";
import React from "react";
import PropTypes from "prop-types";
import HexUtils from "./HexUtils";
import { withHexEngine } from "./Context";

class Path extends Component {
static propTypes = {
end: PropTypes.object,
layout: PropTypes.object,
start: PropTypes.object
};

// TODO Refactor
getPoints() {
const { end, layout, start } = this.props;
if (!end || !start) {
return "";
}
function getPoints(start, end, layout) {
if (!end || !start) {
return "";
}

// Get all the intersecting hexes between start and end points
const distance = HexUtils.distance(start, end);
const intersects = [];
const step = 1.0 / Math.max(distance, 1);
for (let i = 0; i <= distance; i++) {
intersects.push(HexUtils.round(HexUtils.hexLerp(start, end, step * i)));
}
const distance = HexUtils.distance(start, end);
const step = 1.0 / Math.max(distance, 1);
const points = [...Array(distance + 1).keys()]
.map(i => {
const hex = HexUtils.round(HexUtils.hexLerp(start, end, step * i));
const pixel = HexUtils.hexToPixel(hex, layout);
return ` ${pixel.x},${pixel.y} `;
})
.join("L");

// Construct Path points out of all the intersecting hexes (e.g. M 0,0 L 10,20, L 30,20)
let points = "M";
points += intersects
.map(hex => {
let p = HexUtils.hexToPixel(hex, layout);
return ` ${p.x},${p.y} `;
})
.join("L");
return `M${points}`;
}

return points;
}
export const Path = ({ start, end, layout }) => (
<path d={getPoints(start, end, layout)} />
);

render() {
return <path d={this.getPoints()} />;
}
}
Path.propTypes = {
end: PropTypes.object,
layout: PropTypes.object,
start: PropTypes.object
};

export default withHexEngine(Path);
export const Path_ = Path;
export default withHexEngine(Path_);
Loading

0 comments on commit 0c8c1f2

Please sign in to comment.