Removed edge snapping in favour of single layer fog system
This commit is contained in:
parent
1a2260515d
commit
7639297510
@ -92,12 +92,12 @@ function Map({
|
||||
onMapDraw(new RemoveShapeAction(shapeIds));
|
||||
}
|
||||
|
||||
function handleFogShapeAdd(shape) {
|
||||
onFogDraw(new AddShapeAction([shape]));
|
||||
function handleFogShapesAdd(shapes) {
|
||||
onFogDraw(new AddShapeAction(shapes));
|
||||
}
|
||||
|
||||
function handleFogShapeCut(shape) {
|
||||
onFogDraw(new CutShapeAction([shape]));
|
||||
function handleFogShapesCut(shapes) {
|
||||
onFogDraw(new CutShapeAction(shapes));
|
||||
}
|
||||
|
||||
function handleFogShapesRemove(shapeIds) {
|
||||
@ -228,8 +228,8 @@ function Map({
|
||||
<MapFog
|
||||
map={map}
|
||||
shapes={fogShapes}
|
||||
onShapeAdd={handleFogShapeAdd}
|
||||
onShapeCut={handleFogShapeCut}
|
||||
onShapesAdd={handleFogShapesAdd}
|
||||
onShapesCut={handleFogShapesCut}
|
||||
onShapesRemove={handleFogShapesRemove}
|
||||
onShapesEdit={handleFogShapesEdit}
|
||||
active={selectedToolId === "fog"}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect, useCallback, useRef } from "react";
|
||||
import shortid from "shortid";
|
||||
import { Group, Rect, Line, Circle } from "react-konva";
|
||||
import { Group, Rect, Line } from "react-konva";
|
||||
import useImage from "use-image";
|
||||
|
||||
import diagonalPattern from "../../images/DiagonalPattern.png";
|
||||
@ -18,7 +18,6 @@ import {
|
||||
getGuidesFromBoundingBoxes,
|
||||
getGuidesFromGridCell,
|
||||
findBestGuides,
|
||||
getSnappingVertex,
|
||||
} from "../../helpers/drawing";
|
||||
import colors from "../../helpers/colors";
|
||||
import {
|
||||
@ -27,13 +26,15 @@ import {
|
||||
getRelativePointerPosition,
|
||||
} from "../../helpers/konva";
|
||||
|
||||
import SubtractShapeAction from "../../actions/SubtractShapeAction";
|
||||
|
||||
import useSetting from "../../hooks/useSetting";
|
||||
|
||||
function MapFog({
|
||||
map,
|
||||
shapes,
|
||||
onShapeAdd,
|
||||
onShapeCut,
|
||||
onShapesAdd,
|
||||
onShapesCut,
|
||||
onShapesRemove,
|
||||
onShapesEdit,
|
||||
active,
|
||||
@ -66,7 +67,6 @@ function MapFog({
|
||||
// Bounding boxes for guides
|
||||
const [fogShapeBoundingBoxes, setFogShapeBoundingBoxes] = useState([]);
|
||||
const [guides, setGuides] = useState([]);
|
||||
const [vertexSnapping, setVertexSnapping] = useState();
|
||||
|
||||
const shouldHover =
|
||||
active &&
|
||||
@ -76,16 +76,7 @@ function MapFog({
|
||||
const shouldRenderGuides =
|
||||
active &&
|
||||
editable &&
|
||||
(toolSettings.type === "rectangle" || toolSettings.type === "polygon") &&
|
||||
!vertexSnapping;
|
||||
const shouldRenderVertexSnapping =
|
||||
active &&
|
||||
editable &&
|
||||
(toolSettings.type === "rectangle" ||
|
||||
toolSettings.type === "polygon" ||
|
||||
toolSettings.type === "brush") &&
|
||||
toolSettings.useEdgeSnapping &&
|
||||
vertexSnapping;
|
||||
(toolSettings.type === "rectangle" || toolSettings.type === "polygon");
|
||||
|
||||
const [patternImage] = useImage(diagonalPattern);
|
||||
|
||||
@ -99,20 +90,13 @@ function MapFog({
|
||||
function getBrushPosition(snapping = true) {
|
||||
const mapImage = mapStage.findOne("#mapImage");
|
||||
let position = getRelativePointerPosition(mapImage);
|
||||
if (snapping) {
|
||||
if (shouldRenderVertexSnapping) {
|
||||
position = Vector2.multiply(vertexSnapping, {
|
||||
x: mapWidth,
|
||||
y: mapHeight,
|
||||
});
|
||||
} else if (shouldRenderGuides) {
|
||||
for (let guide of guides) {
|
||||
if (guide.orientation === "vertical") {
|
||||
position.x = guide.start.x * mapWidth;
|
||||
}
|
||||
if (guide.orientation === "horizontal") {
|
||||
position.y = guide.start.y * mapHeight;
|
||||
}
|
||||
if (snapping && shouldRenderGuides) {
|
||||
for (let guide of guides) {
|
||||
if (guide.orientation === "vertical") {
|
||||
position.x = guide.start.x * mapWidth;
|
||||
}
|
||||
if (guide.orientation === "horizontal") {
|
||||
position.y = guide.start.y * mapHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,33 +188,53 @@ function MapFog({
|
||||
|
||||
function handleBrushUp() {
|
||||
if (
|
||||
toolSettings.type === "brush" ||
|
||||
(toolSettings.type === "rectangle" && drawingShape)
|
||||
(toolSettings.type === "brush" || toolSettings.type === "rectangle") &&
|
||||
drawingShape
|
||||
) {
|
||||
const cut = toolSettings.useFogCut;
|
||||
if (drawingShape.data.points.length > 1) {
|
||||
let shapeData = {};
|
||||
|
||||
let drawingShapes = [drawingShape];
|
||||
if (!toolSettings.multilayer) {
|
||||
const shapesToSubtract = shapes.filter((shape) =>
|
||||
cut ? !shape.visible : shape.visible
|
||||
);
|
||||
const subtractAction = new SubtractShapeAction(
|
||||
mergeFogShapes(shapesToSubtract, !cut)
|
||||
);
|
||||
const state = subtractAction.execute({
|
||||
[drawingShape.id]: drawingShape,
|
||||
});
|
||||
drawingShapes = Object.values(state)
|
||||
.filter((shape) => shape.data.points.length > 2)
|
||||
.map((shape) => ({ ...shape, id: shortid.generate() }));
|
||||
}
|
||||
|
||||
if (drawingShapes.length > 0) {
|
||||
drawingShapes = drawingShapes.map((shape) => {
|
||||
let shapeData = {};
|
||||
if (cut) {
|
||||
shapeData = { id: shape.id, type: shape.type };
|
||||
} else {
|
||||
shapeData = { ...shape, color: "black" };
|
||||
}
|
||||
return {
|
||||
...shapeData,
|
||||
data: {
|
||||
...shape.data,
|
||||
points: simplifyPoints(
|
||||
shape.data.points,
|
||||
gridCellNormalizedSize,
|
||||
// Downscale fog as smoothing doesn't currently work with edge snapping
|
||||
Math.max(stageScale, 1) / 2
|
||||
),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
if (cut) {
|
||||
shapeData = { id: drawingShape.id, type: drawingShape.type };
|
||||
onShapesCut(drawingShapes);
|
||||
} else {
|
||||
shapeData = { ...drawingShape, color: "black" };
|
||||
}
|
||||
const shape = {
|
||||
...shapeData,
|
||||
data: {
|
||||
...drawingShape.data,
|
||||
points: simplifyPoints(
|
||||
drawingShape.data.points,
|
||||
gridCellNormalizedSize,
|
||||
// Downscale fog as smoothing doesn't currently work with edge snapping
|
||||
stageScale / 2
|
||||
),
|
||||
},
|
||||
};
|
||||
if (cut) {
|
||||
onShapeCut(shape);
|
||||
} else {
|
||||
onShapeAdd(shape);
|
||||
onShapesAdd(drawingShapes);
|
||||
}
|
||||
}
|
||||
setDrawingShape(null);
|
||||
@ -273,9 +277,7 @@ function MapFog({
|
||||
function handlePolygonMove() {
|
||||
if (
|
||||
active &&
|
||||
(toolSettings.type === "polygon" ||
|
||||
toolSettings.type === "rectangle") &&
|
||||
!shouldRenderVertexSnapping
|
||||
(toolSettings.type === "polygon" || toolSettings.type === "rectangle")
|
||||
) {
|
||||
let guides = [];
|
||||
const brushPosition = getBrushPosition(false);
|
||||
@ -308,24 +310,6 @@ function MapFog({
|
||||
|
||||
setGuides(findBestGuides(brushPosition, guides));
|
||||
}
|
||||
if (
|
||||
active &&
|
||||
toolSettings.useEdgeSnapping &&
|
||||
(toolSettings.type === "polygon" ||
|
||||
toolSettings.type === "rectangle" ||
|
||||
toolSettings.type === "brush")
|
||||
) {
|
||||
const brushPosition = getBrushPosition(false);
|
||||
setVertexSnapping(
|
||||
getSnappingVertex(
|
||||
brushPosition,
|
||||
fogShapes,
|
||||
fogShapeBoundingBoxes,
|
||||
gridCellNormalizedSize,
|
||||
Math.min(0.4 / stageScale, 0.4)
|
||||
)
|
||||
);
|
||||
}
|
||||
if (toolSettings.type === "polygon") {
|
||||
const brushPosition = getBrushPosition();
|
||||
if (toolSettings.type === "polygon" && drawingShape) {
|
||||
@ -365,23 +349,50 @@ function MapFog({
|
||||
|
||||
const finishDrawingPolygon = useCallback(() => {
|
||||
const cut = toolSettings.useFogCut;
|
||||
const data = {
|
||||
...drawingShape.data,
|
||||
// Remove the last point as it hasn't been placed yet
|
||||
points: drawingShape.data.points.slice(0, -1),
|
||||
|
||||
let polygonShape = {
|
||||
id: drawingShape.id,
|
||||
type: drawingShape.type,
|
||||
data: {
|
||||
...drawingShape.data,
|
||||
// Remove the last point as it hasn't been placed yet
|
||||
points: drawingShape.data.points.slice(0, -1),
|
||||
},
|
||||
};
|
||||
if (cut) {
|
||||
onShapeCut({
|
||||
id: drawingShape.id,
|
||||
type: drawingShape.type,
|
||||
data: data,
|
||||
|
||||
let polygonShapes = [polygonShape];
|
||||
if (!toolSettings.multilayer) {
|
||||
const shapesToSubtract = shapes.filter((shape) =>
|
||||
cut ? !shape.visible : shape.visible
|
||||
);
|
||||
const subtractAction = new SubtractShapeAction(
|
||||
mergeFogShapes(shapesToSubtract, !cut)
|
||||
);
|
||||
const state = subtractAction.execute({
|
||||
[polygonShape.id]: polygonShape,
|
||||
});
|
||||
} else {
|
||||
onShapeAdd({ ...drawingShape, data: data, color: "black" });
|
||||
polygonShapes = Object.values(state)
|
||||
.filter((shape) => shape.data.points.length > 2)
|
||||
.map((shape) => ({ ...shape, id: shortid.generate() }));
|
||||
}
|
||||
|
||||
if (polygonShapes.length > 0) {
|
||||
if (cut) {
|
||||
onShapesCut(polygonShapes);
|
||||
} else {
|
||||
onShapesAdd(
|
||||
polygonShapes.map((shape) => ({
|
||||
...drawingShape,
|
||||
data: shape.data,
|
||||
id: shape.id,
|
||||
color: "black",
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setDrawingShape(null);
|
||||
}, [toolSettings, drawingShape, onShapeCut, onShapeAdd]);
|
||||
}, [toolSettings, drawingShape, onShapesCut, onShapesAdd, shapes]);
|
||||
|
||||
// Add keyboard shortcuts
|
||||
function handleKeyDown({ key }) {
|
||||
@ -467,9 +478,6 @@ function MapFog({
|
||||
// Disable collision if the fog is transparent and we're not editing it
|
||||
// This allows tokens to be moved under the fog
|
||||
hitFunc={editable && !active ? () => {} : undefined}
|
||||
// shadowColor={editable ? "rgba(0, 0, 0, 0)" : "rgba(34, 34, 34, 1)"}
|
||||
// shadowOffset={{ x: 0, y: 5 }}
|
||||
// shadowBlur={10}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -523,18 +531,6 @@ function MapFog({
|
||||
));
|
||||
}
|
||||
|
||||
function renderSnappingVertex() {
|
||||
return (
|
||||
<Circle
|
||||
x={vertexSnapping.x * mapWidth}
|
||||
y={vertexSnapping.y * mapHeight}
|
||||
radius={gridStrokeWidth}
|
||||
stroke="hsl(260, 100%, 80%)"
|
||||
strokeWidth={gridStrokeWidth * 0.25}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
function shapeVisible(shape) {
|
||||
return (active && !toolSettings.preview) || shape.visible;
|
||||
@ -559,7 +555,6 @@ function MapFog({
|
||||
{fogShapes.map(renderShape)}
|
||||
</Group>
|
||||
{shouldRenderGuides && renderGuides()}
|
||||
{shouldRenderVertexSnapping && renderSnappingVertex()}
|
||||
{drawingShape && renderShape(drawingShape)}
|
||||
{drawingShape &&
|
||||
toolSettings &&
|
||||
|
@ -1,32 +0,0 @@
|
||||
import React from "react";
|
||||
import { IconButton } from "theme-ui";
|
||||
|
||||
import SnappingOnIcon from "../../../icons/SnappingOnIcon";
|
||||
import SnappingOffIcon from "../../../icons/SnappingOffIcon";
|
||||
|
||||
function EdgeSnappingToggle({
|
||||
useEdgeSnapping,
|
||||
onEdgeSnappingChange,
|
||||
disabled,
|
||||
}) {
|
||||
return (
|
||||
<IconButton
|
||||
aria-label={
|
||||
useEdgeSnapping
|
||||
? "Disable Edge Snapping (S)"
|
||||
: "Enable Edge Snapping (S)"
|
||||
}
|
||||
title={
|
||||
useEdgeSnapping
|
||||
? "Disable Edge Snapping (S)"
|
||||
: "Enable Edge Snapping (S)"
|
||||
}
|
||||
onClick={() => onEdgeSnappingChange(!useEdgeSnapping)}
|
||||
disabled={disabled}
|
||||
>
|
||||
{useEdgeSnapping ? <SnappingOnIcon /> : <SnappingOffIcon />}
|
||||
</IconButton>
|
||||
);
|
||||
}
|
||||
|
||||
export default EdgeSnappingToggle;
|
@ -4,7 +4,7 @@ import { useMedia } from "react-media";
|
||||
|
||||
import RadioIconButton from "../../RadioIconButton";
|
||||
|
||||
import EdgeSnappingToggle from "./EdgeSnappingToggle";
|
||||
import MultilayerToggle from "./MultilayerToggle";
|
||||
import FogPreviewToggle from "./FogPreviewToggle";
|
||||
import FogCutToggle from "./FogCutToggle";
|
||||
|
||||
@ -40,8 +40,8 @@ function BrushToolSettings({
|
||||
onSettingChange({ type: "toggle" });
|
||||
} else if (key === "e") {
|
||||
onSettingChange({ type: "remove" });
|
||||
} else if (key === "s") {
|
||||
onSettingChange({ useEdgeSnapping: !settings.useEdgeSnapping });
|
||||
} else if (key === "l") {
|
||||
onSettingChange({ multilayer: !settings.multilayer });
|
||||
} else if (key === "f") {
|
||||
onSettingChange({ preview: !settings.preview });
|
||||
} else if (key === "c") {
|
||||
@ -128,11 +128,9 @@ function BrushToolSettings({
|
||||
onFogCutChange={(useFogCut) => onSettingChange({ useFogCut })}
|
||||
disabled={settings.preview}
|
||||
/>
|
||||
<EdgeSnappingToggle
|
||||
useEdgeSnapping={settings.useEdgeSnapping}
|
||||
onEdgeSnappingChange={(useEdgeSnapping) =>
|
||||
onSettingChange({ useEdgeSnapping })
|
||||
}
|
||||
<MultilayerToggle
|
||||
multilayer={settings.multilayer}
|
||||
onMultilayerChange={(multilayer) => onSettingChange({ multilayer })}
|
||||
disabled={settings.preview}
|
||||
/>
|
||||
<FogPreviewToggle
|
||||
|
22
src/components/map/controls/MultilayerToggle.js
Normal file
22
src/components/map/controls/MultilayerToggle.js
Normal file
@ -0,0 +1,22 @@
|
||||
import React from "react";
|
||||
import { IconButton } from "theme-ui";
|
||||
|
||||
import MultilayerOnIcon from "../../../icons/FogMultilayerOnIcon";
|
||||
import MultilayerOffIcon from "../../../icons/FogMultilayerOffIcon";
|
||||
|
||||
function MultilayerToggle({ multilayer, onMultilayerChange, disabled }) {
|
||||
return (
|
||||
<IconButton
|
||||
aria-label={
|
||||
multilayer ? "Disable Multilayer (L)" : "Enable Multilayer (L)"
|
||||
}
|
||||
title={multilayer ? "Disable Multilayer (L)" : "Enable Multilayer (L)"}
|
||||
onClick={() => onMultilayerChange(!multilayer)}
|
||||
disabled={disabled}
|
||||
>
|
||||
{multilayer ? <MultilayerOnIcon /> : <MultilayerOffIcon />}
|
||||
</IconButton>
|
||||
);
|
||||
}
|
||||
|
||||
export default MultilayerToggle;
|
@ -9,11 +9,13 @@ export function addPolygonDifferenceToShapes(shape, difference, shapes) {
|
||||
}
|
||||
}
|
||||
|
||||
const points = difference[i][0].map(([x, y]) => ({ x, y }));
|
||||
|
||||
shapes[newId] = {
|
||||
...shape,
|
||||
id: newId,
|
||||
data: {
|
||||
points: difference[i][0].map(([x, y]) => ({ x, y })),
|
||||
points,
|
||||
holes,
|
||||
},
|
||||
};
|
||||
@ -23,11 +25,14 @@ export function addPolygonDifferenceToShapes(shape, difference, shapes) {
|
||||
export function addPolygonIntersectionToShapes(shape, intersection, shapes) {
|
||||
for (let i = 0; i < intersection.length; i++) {
|
||||
let newId = `${shape.id}-int-${i}`;
|
||||
|
||||
const points = intersection[i][0].map(([x, y]) => ({ x, y }));
|
||||
|
||||
shapes[newId] = {
|
||||
...shape,
|
||||
id: newId,
|
||||
data: {
|
||||
points: intersection[i][0].map(([x, y]) => ({ x, y })),
|
||||
points,
|
||||
holes: [],
|
||||
},
|
||||
// Default intersection visibility to false
|
||||
|
@ -210,15 +210,16 @@ export function simplifyPoints(points, gridCellSize, scale) {
|
||||
/**
|
||||
* Merges overlapping fog shapes
|
||||
* @param {Fog[]} shapes
|
||||
* @param {boolean} ignoreHidden
|
||||
* @returns {Fog[]}
|
||||
*/
|
||||
export function mergeFogShapes(shapes) {
|
||||
export function mergeFogShapes(shapes, ignoreHidden = true) {
|
||||
if (shapes.length === 0) {
|
||||
return shapes;
|
||||
}
|
||||
let geometries = [];
|
||||
for (let shape of shapes) {
|
||||
if (!shape.visible) {
|
||||
if (ignoreHidden && !shape.visible) {
|
||||
continue;
|
||||
}
|
||||
const shapePoints = shape.data.points.map(({ x, y }) => [x, y]);
|
||||
@ -243,7 +244,7 @@ export function mergeFogShapes(shapes) {
|
||||
}
|
||||
merged.push({
|
||||
// Use the data of the first visible shape as the merge
|
||||
...shapes.find((shape) => shape.visible),
|
||||
...shapes.find((shape) => ignoreHidden || shape.visible),
|
||||
id: `merged-${i}`,
|
||||
data: {
|
||||
points: union[i][0].map(([x, y]) => ({ x, y })),
|
||||
@ -253,7 +254,7 @@ export function mergeFogShapes(shapes) {
|
||||
}
|
||||
return merged;
|
||||
} catch {
|
||||
logError(new Error(`Unable to merge shapes ${JSON.stringify(shapes)}`));
|
||||
console.error("Unable to merge shapes");
|
||||
return shapes;
|
||||
}
|
||||
}
|
||||
@ -464,69 +465,3 @@ export function findBestGuides(brushPosition, guides) {
|
||||
}
|
||||
return bestGuides;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Vector2} brushPosition
|
||||
* @param {Fog[]} shapes
|
||||
* @param {Vector2.BoundingBox} boundingBoxes
|
||||
* @param {Vector2} gridCellSize
|
||||
* @param {number} snappingSensitivity
|
||||
*/
|
||||
export function getSnappingVertex(
|
||||
brushPosition,
|
||||
shapes,
|
||||
boundingBoxes,
|
||||
gridCellSize,
|
||||
snappingSensitivity
|
||||
) {
|
||||
const minGrid = Vector2.min(gridCellSize);
|
||||
const snappingDistance = minGrid * snappingSensitivity;
|
||||
|
||||
let closestDistance = Number.MAX_VALUE;
|
||||
let closestPosition;
|
||||
for (let i = 0; i < shapes.length; i++) {
|
||||
// Check bounds before checking all points
|
||||
const bounds = boundingBoxes[i];
|
||||
const offsetMin = Vector2.subtract(bounds.min, gridCellSize);
|
||||
const offsetMax = Vector2.add(bounds.max, gridCellSize);
|
||||
if (
|
||||
brushPosition.x < offsetMin.x ||
|
||||
brushPosition.x > offsetMax.x ||
|
||||
brushPosition.y < offsetMin.y ||
|
||||
brushPosition.y > offsetMax.y
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const shape = shapes[i];
|
||||
// Include shape points and holes
|
||||
let pointArray = [shape.data.points, ...shape.data.holes];
|
||||
|
||||
for (let points of pointArray) {
|
||||
// Find the closest point to each edge of the shape
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const a = points[i];
|
||||
// Wrap around points to the start to account for closed shape
|
||||
const b = points[(i + 1) % points.length];
|
||||
|
||||
let { distance, point } = Vector2.distanceToLine(brushPosition, a, b);
|
||||
// Bias towards vertices
|
||||
distance += snappingDistance / 2;
|
||||
const isCloseToShape = distance < snappingDistance;
|
||||
if (isCloseToShape && distance < closestDistance) {
|
||||
closestPosition = point;
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
// Find cloest vertex
|
||||
for (let point of points) {
|
||||
const distance = Vector2.distance(point, brushPosition);
|
||||
const isCloseToShape = distance < snappingDistance;
|
||||
if (isCloseToShape && distance < closestDistance) {
|
||||
closestPosition = point;
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return closestPosition;
|
||||
}
|
||||
|
20
src/icons/FogMultilayerOffIcon.js
Normal file
20
src/icons/FogMultilayerOffIcon.js
Normal file
@ -0,0 +1,20 @@
|
||||
import React from "react";
|
||||
|
||||
function FogMultilayerOffIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
>
|
||||
<rect fill="none" height="24" width="24" y="0" />
|
||||
<path d="M19.97,13.2c-0.36-0.28-0.86-0.28-1.22,0l-1.23,0.96l1.43,1.43l1.03-0.8c0.51-0.4,0.51-1.17,0-1.57L19.97,13.2z" />
|
||||
<path d="M19.99,9.71c0.51-0.4,0.51-1.18,0-1.58l-6.76-5.26c-0.72-0.56-1.73-0.56-2.46,0L8.23,4.86l7.88,7.88L19.99,9.71z" />
|
||||
<path d="M20.48,19.94L3.51,2.97c-0.39-0.39-1.02-0.39-1.41,0c-0.39,0.39-0.39,1.02,0,1.41l2.95,2.95L4.01,8.14 c-0.51,0.4-0.51,1.18,0,1.58l6.76,5.26c0.61,0.48,1.43,0.52,2.11,0.18l1.47,1.47l-2.36,1.84l-6.77-5.26 c-0.36-0.28-0.86-0.28-1.22,0c-0.51,0.4-0.51,1.17,0,1.57l6.76,5.26c0.72,0.56,1.73,0.56,2.46,0l2.55-1.98l3.3,3.3 c0.39,0.39,1.02,0.39,1.41,0C20.88,20.97,20.88,20.33,20.48,19.94z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default FogMultilayerOffIcon;
|
18
src/icons/FogMultilayerOnIcon.js
Normal file
18
src/icons/FogMultilayerOnIcon.js
Normal file
@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
function FogMultilayerOnIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
>
|
||||
<rect fill="none" height="24" width="24" y="0" />
|
||||
<path d="M11.99,18.47l-6.77-5.26c-0.36-0.28-0.86-0.28-1.22,0l0,0c-0.51,0.4-0.51,1.17,0,1.57l6.76,5.26 c0.72,0.56,1.73,0.56,2.46,0l6.76-5.26c0.51-0.4,0.51-1.17,0-1.57l-0.01-0.01c-0.36-0.28-0.86-0.28-1.22,0L11.99,18.47z M13.23,14.97l6.76-5.26c0.51-0.4,0.51-1.18,0-1.58l-6.76-5.26c-0.72-0.56-1.73-0.56-2.46,0L4.01,8.14c-0.51,0.4-0.51,1.18,0,1.58 l6.76,5.26C11.49,15.54,12.51,15.54,13.23,14.97z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default FogMultilayerOnIcon;
|
@ -1,18 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function SnappingOffIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
>
|
||||
<path d="M24 24H0V0h24z" fill="none" />
|
||||
<path d="M10 5.59L6.62 2.2a1 1 0 00-.2-.15c.14-.03.27-.05.4-.05L7 2h.48c1.06 0 2.4.83 2.51 1.86L10 4v1.59zm10.88 10.88L16 11.59V4a2 2 0 011.85-2H19a3 3 0 013 2.82v6.87c0 1.69-.37 3.34-1.12 4.78zM13 21c-5.36 0-8.87-3.7-9-8.72V4.83l-.9-.9A1 1 0 014.51 2.5l.37.37a3 3 0 01.04-.04v.08l16.15 16.15a1 1 0 01-1.41 1.42l-1.17-1.17A8.98 8.98 0 0113 21zm5-12.97h.28c.55 0 1.72-.01 1.72-.03V5a1 1 0 00-.88-1H18v4.03zM6 8h.06L7.17 8 6 6.83V8zM13 15a3 3 0 00.98-.18L10 10.83V12c0 1.98 1.72 2.99 3 2.99z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default SnappingOffIcon;
|
@ -1,18 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
function SnappingOnIcon() {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
fill="currentcolor"
|
||||
>
|
||||
<path d="M24 24H0V0h24z" fill="none" />
|
||||
<path d="M13 21c-5.46 0-9-3.83-9-9V5a3 3 0 013-3h.48C8.58 2 10 2.9 10 4v8c0 1.98 1.72 2.99 3 2.99S16 14 16 12V4c0-1.1.9-2 2-2h1a3 3 0 013 3v6.69c0 4.79-3 9.31-9 9.31zm5-12.97h.28c.55 0 1.72-.01 1.72-.03V5a1 1 0 00-.88-1H18v4.03zM6 8h.06L8 8V4.2h-.01l-.02-.01c-.13-.1-.3-.17-.41-.2H7a1 1 0 00-1 .88v3.13z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default SnappingOnIcon;
|
@ -47,6 +47,13 @@ function loadVersions(settings) {
|
||||
delete newSettings.measure;
|
||||
return newSettings;
|
||||
});
|
||||
// v1.8.0 - Removed edge snapping for multilayer
|
||||
settings.version(5, (prev) => {
|
||||
let newSettings = { ...prev };
|
||||
delete newSettings.fog.useEdgeSnapping;
|
||||
newSettings.fog.multilayer = false;
|
||||
return newSettings;
|
||||
});
|
||||
}
|
||||
|
||||
export function getSettings() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user