Skip to content

Commit

Permalink
feat(composer): update TagResize feature implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sheilaXu authored and TheEvilDev committed Feb 28, 2023
1 parent 22a404a commit b8dfb46
Show file tree
Hide file tree
Showing 33 changed files with 890 additions and 1,136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
DefaultAnchorStatus,
INavLink,
IRuleBasedMap,
ITagSettings,
IValueDataBinding,
KnownComponentType,
SceneResourceType,
Expand All @@ -28,6 +29,7 @@ import { getSceneResourceInfo } from '../../../../utils/sceneResourceUtils';
import svgIconToWidgetSprite from '../common/SvgIconToWidgetSprite';
import { findComponentByType } from '../../../../utils/nodeUtils';
import { Layers } from '../../../../common/constants';
import { componentSettingsSelector } from '../../../../utils/componentSettingsUtils';

export interface AnchorWidgetProps {
node: ISceneNodeInternal;
Expand Down Expand Up @@ -59,6 +61,12 @@ export function AsyncLoadedAnchorWidget({
dataBindingTemplate,
} = useStore(sceneComposerId)((state) => state);
const isViewing = useStore(sceneComposerId)((state) => state.isViewing());
const tagSettings: ITagSettings = useStore(sceneComposerId)((state) =>
componentSettingsSelector(state, KnownComponentType.Tag),
);
const autoRescale = useMemo(() => {
return tagSettings.autoRescale;
}, [tagSettings.autoRescale]);

const onWidgetClick = useStore(sceneComposerId)((state) => state.getEditorConfig().onWidgetClick);
const getObject3DFromSceneNodeRef = useStore(sceneComposerId)((state) => state.getObject3DBySceneNodeRef);
Expand All @@ -77,8 +85,11 @@ export function AsyncLoadedAnchorWidget({

const baseScale = useMemo(() => {
// NOTE: For Fixed Size value was [0.05, 0.05, 1]
return new THREE.Vector3(0.5, 0.5, 1).multiply(new THREE.Vector3(...node.transform.scale));
}, [node.transform.scale]);
const defaultScale = autoRescale ? [0.05, 0.05, 1] : [0.5, 0.5, 1];
return new THREE.Vector3(...defaultScale).multiply(
new THREE.Vector3(tagSettings.scale, tagSettings.scale, tagSettings.scale),
);
}, [autoRescale, tagSettings.scale]);

useEffect(() => {
setParent(node.parentRef ? getObject3DFromSceneNodeRef(node.parentRef) : undefined);
Expand Down Expand Up @@ -115,9 +126,9 @@ export function AsyncLoadedAnchorWidget({
VideoIconSvgString,
];
return iconStrings.map((iconString, index) => {
return svgIconToWidgetSprite(iconString, keys[index], isAlwaysVisible);
return svgIconToWidgetSprite(iconString, keys[index], isAlwaysVisible, !autoRescale);
});
}, []);
}, [autoRescale]);

const isAnchor = (nodeRef?: string) => {
const node = getSceneNodeByRef(nodeRef);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('AnchorWidget', () => {
const setHighlightedSceneNodeRef = jest.fn();
const setSelectedSceneNodeRef = jest.fn();
const getObject3DBySceneNodeRef = jest.fn();
const getSceneProperty = jest.fn();

const node = {
ref: 'test-ref',
Expand All @@ -51,11 +52,13 @@ describe('AnchorWidget', () => {
getEditorConfig: () => ({ onWidgetClick }),
dataInput: 'dataInput' as any,
getObject3DBySceneNodeRef,
getSceneProperty,
} as any);
};

beforeEach(() => {
(useLoader as unknown as jest.Mock).mockReturnValue(['TestSvgData']);
getSceneProperty.mockReturnValue(undefined);
jest.clearAllMocks();
});

Expand Down Expand Up @@ -93,6 +96,14 @@ describe('AnchorWidget', () => {
expect(container).toMatchSnapshot();
});

it('should render correctly with non default tag settings', () => {
setStore('test-ref', 'test-ref');
getSceneProperty.mockReturnValue({ Tag: { scale: 3, autoRescale: true } });
const container = renderer.create(<AnchorWidget node={node as any} defaultIcon={DefaultAnchorStatus.Info} />);

expect(container).toMatchSnapshot();
});

it('should render correctly with an offset', () => {
setStore('test-ref', 'test-ref');
const node = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,64 @@ exports[`AnchorWidget should render correctly with an offset 1`] = `
</group>
`;

exports[`AnchorWidget should render correctly with non default tag settings 1`] = `
<group>
<group
scale={
Vector3 {
"x": 1,
"y": 1,
"z": 1,
}
}
>
<lineSegments>
<lineBasicMaterial
color="#ffffff"
/>
<bufferGeometry
attach="geometry"
/>
</lineSegments>
<anchor
isSelected={true}
onClick={[Function]}
position={
Array [
0,
0,
0,
]
}
scale={
Array [
0.15000000000000002,
0.15000000000000002,
3,
]
}
visualState="Info"
>
<div
data-test-id="Selected"
/>
<div
data-test-id="Info"
/>
<div
data-test-id="Warning"
/>
<div
data-test-id="Error"
/>
<div
data-test-id="Video"
/>
</anchor>
</group>
</group>
`;

exports[`AnchorWidget should render with a countered size when parent is scaled 1`] = `
<group>
<group
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import renderer from 'react-test-renderer';
import React from 'react';

import { DefaultAnchorStatus, SelectedAnchor } from '../../../..';
import {
ErrorIconSvgString,
InfoIconSvgString,
SelectedIconSvgString,
VideoIconSvgString,
WarningIconSvgString,
} from '../../../../assets';

import svgIconToWidgetSprite from './SvgIconToWidgetSprite';

describe('svgIconToWidgetSprite', () => {
const icons = [
['Selected', { key: SelectedAnchor, icon: SelectedIconSvgString }],
['Info', { key: DefaultAnchorStatus.Info, icon: InfoIconSvgString }],
['Warning', { key: DefaultAnchorStatus.Warning, icon: WarningIconSvgString }],
['Error', { key: DefaultAnchorStatus.Error, icon: ErrorIconSvgString }],
['Video', { key: DefaultAnchorStatus.Video, icon: VideoIconSvgString }],
];

icons.forEach((value) => {
it(`it should render the ${value[0]} correctly`, () => {
jest.spyOn(window.Math, 'random').mockReturnValue(0.1);
const { key, icon } = value[1] as any;
const container = renderer.create(svgIconToWidgetSprite(icon, key, false, true));

expect(container).toMatchSnapshot();
});
});

icons.forEach((value) => {
it(`it should render the always visible ${value[0]} correctly`, () => {
jest.spyOn(window.Math, 'random').mockReturnValue(0.1);
const { key, icon } = value[1] as any;
const container = renderer.create(svgIconToWidgetSprite(icon, key, true, true));

expect(container).toMatchSnapshot();
});
});

icons.forEach((value) => {
it(`it should render the constant sized ${value[0]} correctly`, () => {
jest.spyOn(window.Math, 'random').mockReturnValue(0.1);
const { key, icon } = value[1] as any;
const container = renderer.create(svgIconToWidgetSprite(icon, key, false, false));

expect(container).toMatchSnapshot();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default function svgIconToWidgetSprite(
svg: string,
key: DefaultAnchorStatus | string,
alwaysVisible,
sizeAttenuation: boolean, // when true, tag size changes when zooming
props?: WidgetSpriteProps,
) {
if (!THREE.Cache.get(key)) {
Expand All @@ -21,29 +22,30 @@ export default function svgIconToWidgetSprite(
THREE.Cache.add(key, texture);
}

const group = new THREE.Group();

const texture = THREE.Cache.get(key);
// NOTE: sizeAttenuation is true by default, but I am leaving this as setting it to false is what maintains a constant size.
const spriteMaterial = new THREE.SpriteMaterial({ map: texture, sizeAttenuation: true });
spriteMaterial.color.convertSRGBToLinear();
const sprite = new THREE.Sprite(spriteMaterial);
sprite.renderOrder = RenderOrder.DrawLate;

group.add(sprite);

if (alwaysVisible) {
const altSpriteMaterial = spriteMaterial.clone();
altSpriteMaterial.depthFunc = THREE.GreaterDepth;
altSpriteMaterial.opacity = 0.5;
const altSprite = new THREE.Sprite(altSpriteMaterial);
altSprite.renderOrder = RenderOrder.DrawLate;
group.add(altSprite);
}

return (
<widgetSprite key={key} name={key} {...props}>
<primitive object={group.clone()} attach='visual' />
<group attach='visual'>
<sprite renderOrder={RenderOrder.DrawLate}>
<spriteMaterial
key={sizeAttenuation ? 'change-size' : 'constant-size'}
map={texture}
sizeAttenuation={sizeAttenuation}
/>
</sprite>
{alwaysVisible && (
<sprite renderOrder={RenderOrder.DrawLate}>
<spriteMaterial
key={sizeAttenuation ? 'change-size' : 'constant-size'}
map={texture}
sizeAttenuation={sizeAttenuation}
depthFunc={THREE.GreaterDepth}
opacity={0.5}
/>
</sprite>
)}
</group>
</widgetSprite>
);
}
Loading

0 comments on commit b8dfb46

Please sign in to comment.