Add catalog purchase animation

This commit is contained in:
Bill 2021-07-17 12:34:49 -04:00
parent da3c98b24d
commit 3b18493a41
8 changed files with 70 additions and 15 deletions

View File

@ -0,0 +1,55 @@
import { NitroToolbarAnimateIconEvent, TextureUtils, ToolbarIconEnum } from 'nitro-renderer';
import { FC, useCallback, useRef } from 'react';
import { GetRoomEngine } from '../../../../api';
import { CatalogEvent } from '../../../../events';
import { useUiEvent } from '../../../../hooks';
import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView';
import { RoomPreviewerViewProps } from '../../../shared/room-previewer/RoomPreviewerView.types';
export const CatalogRoomPreviewerView: FC<RoomPreviewerViewProps> = props =>
{
const { roomPreviewer = null } = props;
const elementRef = useRef<HTMLDivElement>(null);
const animatePurchase = useCallback(() =>
{
if(!elementRef) return;
const renderTexture = roomPreviewer.getRoomObjectCurrentImage();
if(!renderTexture) return;
const image = TextureUtils.generateImage(renderTexture);
if(!image) return;
const bounds = elementRef.current.getBoundingClientRect();
const x = (bounds.x + (bounds.width / 2));
const y = (bounds.y + (bounds.height / 2));
const event = new NitroToolbarAnimateIconEvent(image, x, y);
event.iconName = ToolbarIconEnum.INVENTORY;
GetRoomEngine().events.dispatchEvent(event);
}, [ roomPreviewer ]);
const onCatalogEvent = useCallback((event: CatalogEvent) =>
{
switch(event.type)
{
case CatalogEvent.PURCHASE_SUCCESS:
animatePurchase();
return;
}
}, [ animatePurchase ]);
useUiEvent(CatalogEvent.PURCHASE_SUCCESS, onCatalogEvent);
return (
<div ref={ elementRef }>
<RoomPreviewerView { ...props } />
</div>
);
}

View File

@ -1,8 +1,8 @@
import { FC } from 'react'; import { FC } from 'react';
import { LimitedEditionCompletePlateView } from '../../../../../shared/limited-edition/complete-plate/LimitedEditionCompletePlateView'; import { LimitedEditionCompletePlateView } from '../../../../../shared/limited-edition/complete-plate/LimitedEditionCompletePlateView';
import { RoomPreviewerView } from '../../../../../shared/room-previewer/RoomPreviewerView';
import { GetCatalogPageImage, GetCatalogPageText, GetOfferName } from '../../../../common/CatalogUtilities'; import { GetCatalogPageImage, GetCatalogPageText, GetOfferName } from '../../../../common/CatalogUtilities';
import { useCatalogContext } from '../../../../context/CatalogContext'; import { useCatalogContext } from '../../../../context/CatalogContext';
import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView';
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView'; import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView'; import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
import { CatalogLayoutDefaultViewProps } from './CatalogLayoutDefaultView.types'; import { CatalogLayoutDefaultViewProps } from './CatalogLayoutDefaultView.types';
@ -29,7 +29,7 @@ export const CatalogLayoutDefaultView: FC<CatalogLayoutDefaultViewProps> = props
</div> } </div> }
{ product && { product &&
<div className="position-relative d-flex flex-column col-5"> <div className="position-relative d-flex flex-column col-5">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
{ product.uniqueLimitedItem && { product.uniqueLimitedItem &&
<LimitedEditionCompletePlateView uniqueLimitedItemsLeft={ product.uniqueLimitedItemsLeft } uniqueLimitedSeriesSize={ product.uniqueLimitedSeriesSize } /> } <LimitedEditionCompletePlateView uniqueLimitedItemsLeft={ product.uniqueLimitedItemsLeft } uniqueLimitedSeriesSize={ product.uniqueLimitedSeriesSize } /> }
<div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div> <div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div>

View File

@ -2,9 +2,9 @@ import { CatalogGroupsComposer } from 'nitro-renderer';
import { FC, useEffect } from 'react'; import { FC, useEffect } from 'react';
import { SendMessageHook } from '../../../../../../hooks/messages'; import { SendMessageHook } from '../../../../../../hooks/messages';
import { LocalizeText } from '../../../../../../utils/LocalizeText'; import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { RoomPreviewerView } from '../../../../../shared/room-previewer/RoomPreviewerView';
import { GetOfferName } from '../../../../common/CatalogUtilities'; import { GetOfferName } from '../../../../common/CatalogUtilities';
import { useCatalogContext } from '../../../../context/CatalogContext'; import { useCatalogContext } from '../../../../context/CatalogContext';
import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView';
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView'; import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView'; import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
import { CatalogLayoutGuildCustomFurniViewProps } from './CatalogLayoutGuildCustomFurniView.types'; import { CatalogLayoutGuildCustomFurniViewProps } from './CatalogLayoutGuildCustomFurniView.types';
@ -30,7 +30,7 @@ export const CatalogLayouGuildCustomFurniView: FC<CatalogLayoutGuildCustomFurniV
</div> </div>
{ product && { product &&
<div className="col position-relative d-flex flex-column"> <div className="col position-relative d-flex flex-column">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
<div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div> <div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div>
{ groups.length === 0 && <div className="bg-muted text-center rounded p-1 text-black mt-auto"> { groups.length === 0 && <div className="bg-muted text-center rounded p-1 text-black mt-auto">
{ LocalizeText('catalog.guild_selector.members_only') } { LocalizeText('catalog.guild_selector.members_only') }

View File

@ -4,10 +4,10 @@ import { GetProductDataForLocalization } from '../../../../../../api/nitro/sessi
import { SendMessageHook } from '../../../../../../hooks/messages/message-event'; import { SendMessageHook } from '../../../../../../hooks/messages/message-event';
import { LocalizeText } from '../../../../../../utils/LocalizeText'; import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { PetImageView } from '../../../../../shared/pet-image/PetImageView'; import { PetImageView } from '../../../../../shared/pet-image/PetImageView';
import { RoomPreviewerView } from '../../../../../shared/room-previewer/RoomPreviewerView';
import { GetCatalogPageImage, GetCatalogPageText, GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../common/CatalogUtilities'; import { GetCatalogPageImage, GetCatalogPageText, GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../common/CatalogUtilities';
import { useCatalogContext } from '../../../../context/CatalogContext'; import { useCatalogContext } from '../../../../context/CatalogContext';
import { CatalogActions } from '../../../../reducers/CatalogReducer'; import { CatalogActions } from '../../../../reducers/CatalogReducer';
import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView';
import { CatalogLayoutPetViewProps } from './CatalogLayoutPetView.types'; import { CatalogLayoutPetViewProps } from './CatalogLayoutPetView.types';
import { CatalogLayoutPetPurchaseView } from './purchase/CatalogLayoutPetPurchaseView'; import { CatalogLayoutPetPurchaseView } from './purchase/CatalogLayoutPetPurchaseView';
@ -169,12 +169,12 @@ export const CatalogLayoutPetView: FC<CatalogLayoutPetViewProps> = props =>
</div> } </div> }
{ (petIndex >= 0) && { (petIndex >= 0) &&
<div className="position-relative d-flex flex-column col-5"> <div className="position-relative d-flex flex-column col-5">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 }> <CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 }>
{ (petIndex > -1 && petIndex <= 7) && { (petIndex > -1 && petIndex <= 7) &&
<button type="button" className= { 'btn btn-primary btn-sm color-button ' + (colorsShowing ? 'active ' : '') } onClick={ event => setColorsShowing(!colorsShowing) }> <button type="button" className= { 'btn btn-primary btn-sm color-button ' + (colorsShowing ? 'active ' : '') } onClick={ event => setColorsShowing(!colorsShowing) }>
<i className="fas fa-fill-drip" /> <i className="fas fa-fill-drip" />
</button> } </button> }
</RoomPreviewerView> </CatalogRoomPreviewerView>
<div className="fs-6 text-black mt-1 overflow-hidden">{ petBreedName }</div> <div className="fs-6 text-black mt-1 overflow-hidden">{ petBreedName }</div>
<CatalogLayoutPetPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ petPurchaseString } /> <CatalogLayoutPetPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ petPurchaseString } />
</div> } </div> }

View File

@ -2,10 +2,10 @@ import { CatalogPageOfferData, IFurnitureData } from 'nitro-renderer';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetSessionDataManager } from '../../../../../../api'; import { GetSessionDataManager } from '../../../../../../api';
import { LocalizeText } from '../../../../../../utils/LocalizeText'; import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { RoomPreviewerView } from '../../../../../shared/room-previewer/RoomPreviewerView';
import { GetCatalogPageImage, GetCatalogPageText, GetOfferName } from '../../../../common/CatalogUtilities'; import { GetCatalogPageImage, GetCatalogPageText, GetOfferName } from '../../../../common/CatalogUtilities';
import { ProductTypeEnum } from '../../../../common/ProductTypeEnum'; import { ProductTypeEnum } from '../../../../common/ProductTypeEnum';
import { useCatalogContext } from '../../../../context/CatalogContext'; import { useCatalogContext } from '../../../../context/CatalogContext';
import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView';
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView'; import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView'; import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
import { CatalogLayoutSpacesViewProps } from './CatalogLayoutSpacesView.types'; import { CatalogLayoutSpacesViewProps } from './CatalogLayoutSpacesView.types';
@ -88,7 +88,7 @@ export const CatalogLayoutSpacesView: FC<CatalogLayoutSpacesViewProps> = props =
</div> } </div> }
{ product && { product &&
<div className="position-relative d-flex flex-column col"> <div className="position-relative d-flex flex-column col">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
<div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div> <div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div>
<CatalogPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } /> <CatalogPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } />
</div> } </div> }

View File

@ -1,7 +1,7 @@
import { FC, useState } from 'react'; import { FC, useState } from 'react';
import { RoomPreviewerView } from '../../../../../shared/room-previewer/RoomPreviewerView';
import { GetOfferName } from '../../../../common/CatalogUtilities'; import { GetOfferName } from '../../../../common/CatalogUtilities';
import { useCatalogContext } from '../../../../context/CatalogContext'; import { useCatalogContext } from '../../../../context/CatalogContext';
import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView';
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView'; import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView'; import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
import { CatalogLayoutTrophiesViewProps } from './CatalogLayoutTrophiesView.types'; import { CatalogLayoutTrophiesViewProps } from './CatalogLayoutTrophiesView.types';
@ -25,7 +25,7 @@ export const CatalogLayoutTrophiesView: FC<CatalogLayoutTrophiesViewProps> = pro
</div> </div>
{ product && { product &&
<div className="position-relative d-flex flex-column col"> <div className="position-relative d-flex flex-column col">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
<div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div> <div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div>
<CatalogPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ trophyText } /> <CatalogPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ trophyText } />
</div> } </div> }

View File

@ -1,8 +1,8 @@
import { FC } from 'react'; import { FC } from 'react';
import { LimitedEditionCompletePlateView } from '../../../../shared/limited-edition/complete-plate/LimitedEditionCompletePlateView'; import { LimitedEditionCompletePlateView } from '../../../../shared/limited-edition/complete-plate/LimitedEditionCompletePlateView';
import { RoomPreviewerView } from '../../../../shared/room-previewer/RoomPreviewerView';
import { GetOfferName } from '../../../common/CatalogUtilities'; import { GetOfferName } from '../../../common/CatalogUtilities';
import { useCatalogContext } from '../../../context/CatalogContext'; import { useCatalogContext } from '../../../context/CatalogContext';
import { CatalogRoomPreviewerView } from '../../catalog-room-previewer/CatalogRoomPreviewerView';
import { CatalogPurchaseView } from '../purchase/CatalogPurchaseView'; import { CatalogPurchaseView } from '../purchase/CatalogPurchaseView';
import { CatalogLayoutSearchResultViewProps } from './CatalogLayoutSearchResultView.types'; import { CatalogLayoutSearchResultViewProps } from './CatalogLayoutSearchResultView.types';
import { CatalogSearchResultOffersView } from './offers/CatalogSearchResultOffersView'; import { CatalogSearchResultOffersView } from './offers/CatalogSearchResultOffersView';
@ -22,7 +22,7 @@ export const CatalogLayoutSearchResultView: FC<CatalogLayoutSearchResultViewProp
</div> </div>
{ product && { product &&
<div className="position-relative d-flex flex-column col"> <div className="position-relative d-flex flex-column col">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
{ product.uniqueLimitedItem && { product.uniqueLimitedItem &&
<LimitedEditionCompletePlateView uniqueLimitedItemsLeft={ product.uniqueLimitedItemsLeft } uniqueLimitedSeriesSize={ product.uniqueLimitedSeriesSize } /> } <LimitedEditionCompletePlateView uniqueLimitedItemsLeft={ product.uniqueLimitedItemsLeft } uniqueLimitedSeriesSize={ product.uniqueLimitedSeriesSize } /> }
<div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div> <div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div>

View File

@ -1,5 +1,5 @@
import { ColorConverter, IRoomRenderingCanvas, Nitro, TextureUtils } from 'nitro-renderer'; import { ColorConverter, IRoomRenderingCanvas, Nitro, TextureUtils } from 'nitro-renderer';
import { createRef, FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useRef, useState } from 'react';
import { RoomPreviewerViewProps } from './RoomPreviewerView.types'; import { RoomPreviewerViewProps } from './RoomPreviewerView.types';
export const RoomPreviewerView: FC<RoomPreviewerViewProps> = props => export const RoomPreviewerView: FC<RoomPreviewerViewProps> = props =>
@ -8,7 +8,7 @@ export const RoomPreviewerView: FC<RoomPreviewerViewProps> = props =>
const [ renderingCanvas, setRenderingCanvas ] = useState<IRoomRenderingCanvas>(null); const [ renderingCanvas, setRenderingCanvas ] = useState<IRoomRenderingCanvas>(null);
const elementRef = createRef<HTMLDivElement>(); const elementRef = useRef<HTMLDivElement>();
const update = useCallback((time: number) => const update = useCallback((time: number) =>
{ {