mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-02-17 01:12:37 +01:00
Fix scaling issues
This commit is contained in:
parent
a5a73ba1fb
commit
ce623859df
79
src/App.tsx
79
src/App.tsx
@ -1,5 +1,5 @@
|
|||||||
import { ConfigurationEvent, HabboWebTools, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent, WebGL } from '@nitrots/nitro-renderer';
|
import { ConfigurationEvent, HabboWebTools, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroEvent, NitroLocalizationEvent, NitroVersion, RoomEngineEvent, WebGL } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { GetCommunication, GetConfiguration, GetNitroInstance, GetUIVersion } from './api';
|
import { GetCommunication, GetConfiguration, GetNitroInstance, GetUIVersion } from './api';
|
||||||
import { Base, TransitionAnimation, TransitionAnimationTypes } from './common';
|
import { Base, TransitionAnimation, TransitionAnimationTypes } from './common';
|
||||||
import { LoadingView } from './components/loading/LoadingView';
|
import { LoadingView } from './components/loading/LoadingView';
|
||||||
@ -16,12 +16,13 @@ export const App: FC<{}> = props =>
|
|||||||
const [ isError, setIsError ] = useState(false);
|
const [ isError, setIsError ] = useState(false);
|
||||||
const [ message, setMessage ] = useState('Getting Ready');
|
const [ message, setMessage ] = useState('Getting Ready');
|
||||||
const [ percent, setPercent ] = useState(0);
|
const [ percent, setPercent ] = useState(0);
|
||||||
|
const [ imageRendering, setImageRendering ] = useState<boolean>(true);
|
||||||
//@ts-ignore
|
|
||||||
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
|
||||||
|
|
||||||
if(!GetNitroInstance())
|
if(!GetNitroInstance())
|
||||||
{
|
{
|
||||||
|
//@ts-ignore
|
||||||
|
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
||||||
|
|
||||||
Nitro.bootstrap();
|
Nitro.bootstrap();
|
||||||
|
|
||||||
const worker = new WorkerBuilder(IntervalWebWorker);
|
const worker = new WorkerBuilder(IntervalWebWorker);
|
||||||
@ -29,28 +30,13 @@ export const App: FC<{}> = props =>
|
|||||||
Nitro.instance.setWorker(worker);
|
Nitro.instance.setWorker(worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPreloadAssetUrls = useCallback(() =>
|
|
||||||
{
|
|
||||||
const urls: string[] = [];
|
|
||||||
const assetUrls = GetConfiguration<string[]>('preload.assets.urls');
|
|
||||||
|
|
||||||
if(assetUrls && assetUrls.length)
|
|
||||||
{
|
|
||||||
for(const url of assetUrls) urls.push(GetNitroInstance().core.configuration.interpolate(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
return urls;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const loadPercent = useCallback(() => setPercent(prevValue => (prevValue + 20)), []);
|
|
||||||
|
|
||||||
const handler = useCallback((event: NitroEvent) =>
|
const handler = useCallback((event: NitroEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case ConfigurationEvent.LOADED:
|
case ConfigurationEvent.LOADED:
|
||||||
GetNitroInstance().localization.init();
|
GetNitroInstance().localization.init();
|
||||||
loadPercent();
|
setPercent(prevValue => (prevValue + 20));
|
||||||
return;
|
return;
|
||||||
case ConfigurationEvent.FAILED:
|
case ConfigurationEvent.FAILED:
|
||||||
setIsError(true);
|
setIsError(true);
|
||||||
@ -67,14 +53,14 @@ export const App: FC<{}> = props =>
|
|||||||
setTimeout(() => window.location.reload(), 1500);
|
setTimeout(() => window.location.reload(), 1500);
|
||||||
return;
|
return;
|
||||||
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING:
|
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKING:
|
||||||
loadPercent();
|
setPercent(prevValue => (prevValue + 20));
|
||||||
return;
|
return;
|
||||||
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED:
|
case NitroCommunicationDemoEvent.CONNECTION_HANDSHAKE_FAILED:
|
||||||
setIsError(true);
|
setIsError(true);
|
||||||
setMessage('Handshake Failed');
|
setMessage('Handshake Failed');
|
||||||
return;
|
return;
|
||||||
case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED:
|
case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED:
|
||||||
loadPercent();
|
setPercent(prevValue => (prevValue + 20));
|
||||||
|
|
||||||
GetNitroInstance().init();
|
GetNitroInstance().init();
|
||||||
|
|
||||||
@ -85,26 +71,30 @@ export const App: FC<{}> = props =>
|
|||||||
setMessage('Connection Error');
|
setMessage('Connection Error');
|
||||||
return;
|
return;
|
||||||
case NitroCommunicationDemoEvent.CONNECTION_CLOSED:
|
case NitroCommunicationDemoEvent.CONNECTION_CLOSED:
|
||||||
//if(GetNitroInstance().roomEngine) GetNitroInstance().roomEngine.dispose();
|
//if(GetNitroInstance().roomEngine) GetNitroInstance().roomEngine.dispose();
|
||||||
|
|
||||||
//setIsError(true);
|
//setIsError(true);
|
||||||
setMessage('Connection Error');
|
setMessage('Connection Error');
|
||||||
|
|
||||||
HabboWebTools.send(-1, 'client.init.handshake.fail');
|
HabboWebTools.send(-1, 'client.init.handshake.fail');
|
||||||
return;
|
return;
|
||||||
case RoomEngineEvent.ENGINE_INITIALIZED:
|
case RoomEngineEvent.ENGINE_INITIALIZED:
|
||||||
loadPercent();
|
setPercent(prevValue => (prevValue + 20));
|
||||||
|
|
||||||
setTimeout(() => setIsReady(true), 300);
|
setTimeout(() => setIsReady(true), 300);
|
||||||
return;
|
return;
|
||||||
case NitroLocalizationEvent.LOADED:
|
case NitroLocalizationEvent.LOADED: {
|
||||||
GetNitroInstance().core.asset.downloadAssets(getPreloadAssetUrls(), (status: boolean) =>
|
const assetUrls = GetConfiguration<string[]>('preload.assets.urls');
|
||||||
|
const urls: string[] = [];
|
||||||
|
|
||||||
|
if(assetUrls && assetUrls.length) for(const url of assetUrls) urls.push(GetNitroInstance().core.configuration.interpolate(url));
|
||||||
|
|
||||||
|
GetNitroInstance().core.asset.downloadAssets(urls, (status: boolean) =>
|
||||||
{
|
{
|
||||||
if(status)
|
if(status)
|
||||||
{
|
{
|
||||||
GetCommunication().init();
|
GetCommunication().init();
|
||||||
|
|
||||||
loadPercent();
|
setPercent(prevValue => (prevValue + 20))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -113,8 +103,9 @@ export const App: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [ getPreloadAssetUrls,loadPercent ]);
|
}, []);
|
||||||
|
|
||||||
UseMainEvent(Nitro.WEBGL_UNAVAILABLE, handler);
|
UseMainEvent(Nitro.WEBGL_UNAVAILABLE, handler);
|
||||||
UseMainEvent(Nitro.WEBGL_CONTEXT_LOST, handler);
|
UseMainEvent(Nitro.WEBGL_CONTEXT_LOST, handler);
|
||||||
@ -128,17 +119,31 @@ export const App: FC<{}> = props =>
|
|||||||
UseConfigurationEvent(ConfigurationEvent.LOADED, handler);
|
UseConfigurationEvent(ConfigurationEvent.LOADED, handler);
|
||||||
UseConfigurationEvent(ConfigurationEvent.FAILED, handler);
|
UseConfigurationEvent(ConfigurationEvent.FAILED, handler);
|
||||||
|
|
||||||
if(!WebGL.isWebGLAvailable())
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
DispatchUiEvent(new NitroEvent(Nitro.WEBGL_UNAVAILABLE));
|
if(!WebGL.isWebGLAvailable())
|
||||||
}
|
{
|
||||||
else
|
DispatchUiEvent(new NitroEvent(Nitro.WEBGL_UNAVAILABLE));
|
||||||
{
|
}
|
||||||
GetNitroInstance().core.configuration.init();
|
else
|
||||||
}
|
{
|
||||||
|
GetNitroInstance().core.configuration.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
const resize = (event: UIEvent) => setImageRendering(!(window.devicePixelRatio % 1));
|
||||||
|
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
|
||||||
|
resize(null);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
window.removeEventListener('resize', resize);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Base fit overflow="hidden">
|
<Base fit overflow="hidden" className={ imageRendering && 'image-rendering-pixelated' }>
|
||||||
{ (!isReady || isError) &&
|
{ (!isReady || isError) &&
|
||||||
<LoadingView isError={ isError } message={ message } percent={ percent } /> }
|
<LoadingView isError={ isError } message={ message } percent={ percent } /> }
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady) }>
|
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady) }>
|
||||||
|
@ -7,8 +7,8 @@ let clickCount = 0;
|
|||||||
|
|
||||||
export const DispatchMouseEvent = (event: MouseEvent, canvasId: number = 1) =>
|
export const DispatchMouseEvent = (event: MouseEvent, canvasId: number = 1) =>
|
||||||
{
|
{
|
||||||
const x = (event.clientX * window.devicePixelRatio);
|
const x = event.clientX;
|
||||||
const y = (event.clientY * window.devicePixelRatio);
|
const y = event.clientY;
|
||||||
|
|
||||||
let eventType = event.type;
|
let eventType = event.type;
|
||||||
|
|
||||||
|
@ -51,9 +51,6 @@ export const DispatchTouchEvent = (event: TouchEvent, canvasId: number = 1, long
|
|||||||
y = event.changedTouches[0].clientY;
|
y = event.changedTouches[0].clientY;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = Math.round(x / (1 / window.devicePixelRatio));
|
|
||||||
y = Math.round(y / (1 / window.devicePixelRatio));
|
|
||||||
|
|
||||||
switch(eventType)
|
switch(eventType)
|
||||||
{
|
{
|
||||||
case MouseEventType.MOUSE_CLICK:
|
case MouseEventType.MOUSE_CLICK:
|
||||||
|
@ -6,11 +6,8 @@ export const GetRoomObjectBounds = (roomId: number, objectId: number, category:
|
|||||||
|
|
||||||
if(!rectangle) return null;
|
if(!rectangle) return null;
|
||||||
|
|
||||||
if(window.devicePixelRatio !== 1)
|
rectangle.x = Math.round(rectangle.x);
|
||||||
{
|
rectangle.y = Math.round(rectangle.y);
|
||||||
rectangle.x = Math.round(rectangle.x / window.devicePixelRatio);
|
|
||||||
rectangle.y = Math.round(rectangle.y / window.devicePixelRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rectangle;
|
return rectangle;
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,8 @@ export const GetRoomObjectScreenLocation = (roomId: number, objectId: number, ca
|
|||||||
|
|
||||||
if(!point) return null;
|
if(!point) return null;
|
||||||
|
|
||||||
if(window.devicePixelRatio !== 1)
|
point.x = Math.round(point.x);
|
||||||
{
|
point.y = Math.round(point.y);
|
||||||
point.x = Math.round(point.x / window.devicePixelRatio);
|
|
||||||
point.y = Math.round(point.y / window.devicePixelRatio);
|
|
||||||
}
|
|
||||||
|
|
||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
opacity: .5;
|
opacity: 0.5;
|
||||||
filter: grayscale(1);
|
filter: grayscale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,9 +30,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.has-highlight {
|
&.has-highlight {
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: "";
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -48,7 +47,7 @@
|
|||||||
.nitro-room-thumbnail-camera {
|
.nitro-room-thumbnail-camera {
|
||||||
width: 132px;
|
width: 132px;
|
||||||
height: 192px;
|
height: 192px;
|
||||||
background-image: url('../assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png');
|
background-image: url("../assets/images/room-widgets/thumbnail-widget/thumbnail-camera-spritesheet.png");
|
||||||
|
|
||||||
.camera-frame {
|
.camera-frame {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -65,10 +64,10 @@
|
|||||||
height: 173px;
|
height: 173px;
|
||||||
color: black;
|
color: black;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
|
||||||
background-position: 0px 0px;
|
background-position: 0px 0px;
|
||||||
background-image: url('../assets/images/room-widgets/trophy-widget/trophy-spritesheet.png');
|
background-image: url("../assets/images/room-widgets/trophy-widget/trophy-spritesheet.png");
|
||||||
|
|
||||||
&.trophy-2 {
|
&.trophy-2 {
|
||||||
background-position: 0px 173px;
|
background-position: 0px 173px;
|
||||||
}
|
}
|
||||||
@ -103,7 +102,7 @@
|
|||||||
.nitro-gift-card {
|
.nitro-gift-card {
|
||||||
width: 306px;
|
width: 306px;
|
||||||
height: 159px;
|
height: 159px;
|
||||||
background: url('../assets/images/gift/gift_tag.png') center no-repeat;
|
background: url("../assets/images/gift/gift_tag.png") center no-repeat;
|
||||||
|
|
||||||
.gift-face {
|
.gift-face {
|
||||||
width: 65px;
|
width: 65px;
|
||||||
@ -111,7 +110,8 @@
|
|||||||
.gift-incognito {
|
.gift-incognito {
|
||||||
width: 37px;
|
width: 37px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
background: url('../assets/images/gift/incognito.png') center no-repeat;
|
background: url("../assets/images/gift/incognito.png") center
|
||||||
|
no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gift-avatar {
|
.gift-avatar {
|
||||||
@ -168,17 +168,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes sk-bouncedelay {
|
@-webkit-keyframes sk-bouncedelay {
|
||||||
0%, 80%, 100% { -webkit-transform: scale(0) }
|
0%,
|
||||||
40% { -webkit-transform: scale(1.0) }
|
80%,
|
||||||
|
100% {
|
||||||
|
-webkit-transform: scale(0);
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
-webkit-transform: scale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes sk-bouncedelay {
|
@keyframes sk-bouncedelay {
|
||||||
0%, 80%, 100% {
|
0%,
|
||||||
-webkit-transform: scale(0);
|
80%,
|
||||||
transform: scale(0);
|
100% {
|
||||||
} 40% {
|
-webkit-transform: scale(0);
|
||||||
-webkit-transform: scale(1.0);
|
transform: scale(0);
|
||||||
transform: scale(1.0);
|
}
|
||||||
|
40% {
|
||||||
|
-webkit-transform: scale(1);
|
||||||
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +195,9 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: 110px;
|
width: 110px;
|
||||||
height: 110px;
|
height: 110px;
|
||||||
background: url('../assets/images/navigator/thumbnail_placeholder.png') no-repeat center;
|
background: url("../assets/images/navigator/thumbnail_placeholder.png")
|
||||||
background-color: rgba($black, .125);
|
no-repeat center;
|
||||||
|
background-color: rgba($black, 0.125);
|
||||||
}
|
}
|
||||||
|
|
||||||
#draggable-windows-container {
|
#draggable-windows-container {
|
||||||
@ -223,7 +233,7 @@
|
|||||||
top: 2px;
|
top: 2px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
font-size: 9.5px;
|
font-size: 9.5px;
|
||||||
padding:2px 3px;
|
padding: 2px 3px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,16 +244,6 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
|
||||||
&.group-badge {
|
|
||||||
width: 39px;
|
|
||||||
height: 39px;
|
|
||||||
|
|
||||||
&.scale-2 {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge-information {
|
.badge-information {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -263,10 +263,10 @@
|
|||||||
background: $white;
|
background: $white;
|
||||||
left: -220px;
|
left: -220px;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: ' ';
|
content: " ";
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-left: 10px solid $white;
|
border-left: 10px solid $white;
|
||||||
@ -289,7 +289,7 @@
|
|||||||
.nitro-rarity-level {
|
.nitro-rarity-level {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
background: url('../assets/images/infostand/rarity-level.png');
|
background: url("../assets/images/infostand/rarity-level.png");
|
||||||
|
|
||||||
div {
|
div {
|
||||||
line-height: 28px;
|
line-height: 28px;
|
||||||
@ -306,12 +306,6 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center -8px;
|
background-position: center -8px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
image-rendering: pixelated;
|
|
||||||
|
|
||||||
&.scale-0-5,
|
|
||||||
&.scale-0-75 {
|
|
||||||
image-rendering: -webkit-optimize-contrast;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pet-image {
|
.pet-image {
|
||||||
@ -337,7 +331,7 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&.border-0 {
|
&.border-0 {
|
||||||
&::after {
|
&::after {
|
||||||
content: none;
|
content: none;
|
||||||
@ -346,7 +340,7 @@
|
|||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: '';
|
content: "";
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
@ -354,13 +348,13 @@
|
|||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
border-bottom: 2px solid white;
|
border-bottom: 2px solid white;
|
||||||
border-right: 2px solid white;
|
border-right: 2px solid white;
|
||||||
box-shadow: -2px -2px rgba(0, 0, 0, .4), inset 3px 3px rgba(0, 0, 0, .2);
|
box-shadow: -2px -2px rgba(0, 0, 0, 0.4),
|
||||||
|
inset 3px 3px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.unique-item {
|
.unique-item {
|
||||||
|
|
||||||
.unique-bg-override {
|
.unique-bg-override {
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
@ -369,26 +363,28 @@
|
|||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: '';
|
content: "";
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: url('../assets/images/unique/grid-bg.png') center no-repeat;
|
background: url("../assets/images/unique/grid-bg.png") center no-repeat;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: '';
|
content: "";
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: url('../assets/images/unique/grid-bg-glass.png') center no-repeat;
|
background: url("../assets/images/unique/grid-bg-glass.png") center
|
||||||
|
no-repeat;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.sold-out:after {
|
&.sold-out:after {
|
||||||
background: url('../assets/images/unique/grid-bg-sold-out.png') center no-repeat,
|
background: url("../assets/images/unique/grid-bg-sold-out.png") center
|
||||||
url('../assets/images/unique/grid-bg-glass.png') center no-repeat;
|
no-repeat,
|
||||||
|
url("../assets/images/unique/grid-bg-glass.png") center no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unique-item-counter {
|
.unique-item-counter {
|
||||||
@ -399,7 +395,8 @@
|
|||||||
bottom: 1px;
|
bottom: 1px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 9px;
|
height: 9px;
|
||||||
background: url('../assets/images/unique/grid-count-bg.png') center no-repeat;
|
background: url("../assets/images/unique/grid-count-bg.png") center
|
||||||
|
no-repeat;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +404,7 @@
|
|||||||
.unique-sold-out-blocker {
|
.unique-sold-out-blocker {
|
||||||
width: 364px;
|
width: 364px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
background: url('../assets/images/unique/catalog-info-sold-out.png');
|
background: url("../assets/images/unique/catalog-info-sold-out.png");
|
||||||
|
|
||||||
div {
|
div {
|
||||||
float: right;
|
float: right;
|
||||||
@ -428,7 +425,7 @@
|
|||||||
right: 16px;
|
right: 16px;
|
||||||
width: 34px;
|
width: 34px;
|
||||||
height: 37px;
|
height: 37px;
|
||||||
background: url('../assets/images/unique/inventory-info-amount-bg.png');
|
background: url("../assets/images/unique/inventory-info-amount-bg.png");
|
||||||
|
|
||||||
div {
|
div {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -441,7 +438,8 @@
|
|||||||
.unique-complete-plate {
|
.unique-complete-plate {
|
||||||
width: 170px;
|
width: 170px;
|
||||||
height: 29px;
|
height: 29px;
|
||||||
background: url('../assets/images/unique/catalog-info-amount-bg.png') no-repeat center;
|
background: url("../assets/images/unique/catalog-info-amount-bg.png")
|
||||||
|
no-repeat center;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
|
|
||||||
@ -462,7 +460,7 @@
|
|||||||
outline: 0;
|
outline: 0;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
background-image: url('../assets/images/unique/numbers.png');
|
background-image: url("../assets/images/unique/numbers.png");
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
@ -537,7 +535,12 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
transition: all 1s;
|
transition: all 1s;
|
||||||
border-radius: calc(#{$border-radius} / 2);
|
border-radius: calc(#{$border-radius} / 2);
|
||||||
background: repeating-linear-gradient($tertiary, $tertiary 50%, $quaternary 50%, $quaternary 100%);
|
background: repeating-linear-gradient(
|
||||||
|
$tertiary,
|
||||||
|
$tertiary 50%,
|
||||||
|
$quaternary 50%,
|
||||||
|
$quaternary 100%
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nitro-progress-bar-text {
|
.nitro-progress-bar-text {
|
||||||
@ -546,4 +549,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './card/NitroCardView';
|
@import "./card/NitroCardView";
|
||||||
|
@ -23,29 +23,10 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
|||||||
{
|
{
|
||||||
const newClassNames: string[] = [ 'avatar-image' ];
|
const newClassNames: string[] = [ 'avatar-image' ];
|
||||||
|
|
||||||
switch(scale)
|
|
||||||
{
|
|
||||||
case .5:
|
|
||||||
newClassNames.push('scale-0-5');
|
|
||||||
break;
|
|
||||||
case .75:
|
|
||||||
newClassNames.push('scale-0-75');
|
|
||||||
break;
|
|
||||||
case 1.25:
|
|
||||||
newClassNames.push('scale-1-25');
|
|
||||||
break;
|
|
||||||
case 1.50:
|
|
||||||
newClassNames.push('scale-1-50');
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
newClassNames.push(`scale-${ scale }`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(classNames.length) newClassNames.push(...classNames);
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
return newClassNames;
|
return newClassNames;
|
||||||
}, [ scale, classNames ]);
|
}, [ classNames ]);
|
||||||
|
|
||||||
const getStyle = useMemo(() =>
|
const getStyle = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -53,10 +34,17 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
|
|||||||
|
|
||||||
if(avatarUrl && avatarUrl.length) newStyle.backgroundImage = `url('${ avatarUrl }')`;
|
if(avatarUrl && avatarUrl.length) newStyle.backgroundImage = `url('${ avatarUrl }')`;
|
||||||
|
|
||||||
|
if(scale !== 1)
|
||||||
|
{
|
||||||
|
newStyle.transform = `scale(${ scale })`;
|
||||||
|
|
||||||
|
if(!(scale % 1)) newStyle.imageRendering = 'pixelated';
|
||||||
|
}
|
||||||
|
|
||||||
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
||||||
|
|
||||||
return newStyle;
|
return newStyle;
|
||||||
}, [ avatarUrl, style ]);
|
}, [ avatarUrl, scale, style ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
|
@ -16,22 +16,7 @@ export interface LayoutBadgeImageViewProps extends BaseProps<HTMLDivElement>
|
|||||||
export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
|
export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { badgeCode = null, isGroup = false, showInfo = false, customTitle = null, isGrayscale = false, scale = 1, classNames = [], style = {}, children = null, ...rest } = props;
|
const { badgeCode = null, isGroup = false, showInfo = false, customTitle = null, isGrayscale = false, scale = 1, classNames = [], style = {}, children = null, ...rest } = props;
|
||||||
const [ badgeUrl, setBadgeUrl ] = useState<string>('');
|
const [ imageElement, setImageElement ] = useState<HTMLImageElement>(null);
|
||||||
|
|
||||||
const getScaleClass = useMemo(() =>
|
|
||||||
{
|
|
||||||
let scaleName = scale.toString();
|
|
||||||
|
|
||||||
if(scale === .5) scaleName = '0-5';
|
|
||||||
|
|
||||||
else if(scale === .75) scaleName = '0-75';
|
|
||||||
|
|
||||||
else if(scale === 1.25) scaleName = '1-25';
|
|
||||||
|
|
||||||
else if(scale === 1.50) scaleName = '1-50';
|
|
||||||
|
|
||||||
return `scale-${ scaleName }`;
|
|
||||||
}, [ scale ]);
|
|
||||||
|
|
||||||
const getClassNames = useMemo(() =>
|
const getClassNames = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -41,23 +26,36 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
|
|||||||
|
|
||||||
if(isGrayscale) newClassNames.push('grayscale');
|
if(isGrayscale) newClassNames.push('grayscale');
|
||||||
|
|
||||||
if((scale !== 1) && getScaleClass.length) newClassNames.push(getScaleClass);
|
|
||||||
|
|
||||||
if(classNames.length) newClassNames.push(...classNames);
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
return newClassNames;
|
return newClassNames;
|
||||||
}, [ classNames, isGroup, isGrayscale, scale, getScaleClass ]);
|
}, [ classNames, isGroup, isGrayscale ]);
|
||||||
|
|
||||||
const getStyle = useMemo(() =>
|
const getStyle = useMemo(() =>
|
||||||
{
|
{
|
||||||
let newStyle: CSSProperties = {};
|
let newStyle: CSSProperties = {};
|
||||||
|
|
||||||
if(badgeUrl && badgeUrl.length) newStyle.backgroundImage = `url(${ badgeUrl })`;
|
if(imageElement)
|
||||||
|
{
|
||||||
|
newStyle.backgroundImage = `url('${ imageElement.src }')`;
|
||||||
|
newStyle.width = imageElement.width;
|
||||||
|
newStyle.height = imageElement.height;
|
||||||
|
|
||||||
|
if(scale !== 1)
|
||||||
|
{
|
||||||
|
newStyle.transform = `scale(${ scale })`;
|
||||||
|
|
||||||
|
if(!(scale % 1)) newStyle.imageRendering = 'pixelated';
|
||||||
|
|
||||||
|
newStyle.width = (imageElement.width * scale);
|
||||||
|
newStyle.height = (imageElement.height * scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
||||||
|
|
||||||
return newStyle;
|
return newStyle;
|
||||||
}, [ style, badgeUrl ]);
|
}, [ imageElement, scale, style ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -69,7 +67,9 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
|
|||||||
{
|
{
|
||||||
if(event.badgeId !== badgeCode) return;
|
if(event.badgeId !== badgeCode) return;
|
||||||
|
|
||||||
setBadgeUrl(TextureUtils.generateImageUrl(new NitroSprite(event.image)));
|
const element = TextureUtils.generateImage(new NitroSprite(event.image));
|
||||||
|
|
||||||
|
element.onload = () => setImageElement(element);
|
||||||
|
|
||||||
didSetBadge = true;
|
didSetBadge = true;
|
||||||
|
|
||||||
@ -80,29 +80,23 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
|
|||||||
|
|
||||||
const texture = isGroup ? GetSessionDataManager().getGroupBadgeImage(badgeCode) : GetSessionDataManager().getBadgeImage(badgeCode);
|
const texture = isGroup ? GetSessionDataManager().getGroupBadgeImage(badgeCode) : GetSessionDataManager().getBadgeImage(badgeCode);
|
||||||
|
|
||||||
if(texture && !didSetBadge) setBadgeUrl(TextureUtils.generateImageUrl(new NitroSprite(texture)));
|
if(texture && !didSetBadge)
|
||||||
|
{
|
||||||
|
const element = TextureUtils.generateImage(new NitroSprite(texture));
|
||||||
|
|
||||||
|
element.onload = () => setImageElement(element);
|
||||||
|
}
|
||||||
|
|
||||||
return () => GetSessionDataManager().events.removeEventListener(BadgeImageReadyEvent.IMAGE_READY, onBadgeImageReadyEvent);
|
return () => GetSessionDataManager().events.removeEventListener(BadgeImageReadyEvent.IMAGE_READY, onBadgeImageReadyEvent);
|
||||||
}, [ badgeCode, isGroup ]);
|
}, [ badgeCode, isGroup ]);
|
||||||
|
|
||||||
const BadgeInformationView = (props: { title: string, description: string }) =>
|
|
||||||
{
|
|
||||||
const { title = null, description = null } = props;
|
|
||||||
|
|
||||||
if(!GetConfiguration('badge.descriptions.enabled', true)) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Base className="badge-information text-black py-1 px-2 small">
|
|
||||||
<div className="fw-bold mb-1">{ title }</div>
|
|
||||||
<div>{ description }</div>
|
|
||||||
</Base>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Base classNames={ getClassNames } style={ getStyle } { ...rest }>
|
<Base classNames={ getClassNames } style={ getStyle } { ...rest }>
|
||||||
{ showInfo &&
|
{ (showInfo && GetConfiguration<boolean>('badge.descriptions.enabled', true)) &&
|
||||||
<BadgeInformationView title={ isGroup ? customTitle : LocalizeBadgeName(badgeCode) } description={ isGroup ? LocalizeText('group.badgepopup.body') : LocalizeBadgeDescription(badgeCode) } /> }
|
<Base className="badge-information text-black py-1 px-2 small">
|
||||||
|
<div className="fw-bold mb-1">{ isGroup ? customTitle : LocalizeBadgeName(badgeCode) }</div>
|
||||||
|
<div>{ isGroup ? LocalizeText('group.badgepopup.body') : LocalizeBadgeDescription(badgeCode) }</div>
|
||||||
|
</Base> }
|
||||||
{ children }
|
{ children }
|
||||||
</Base>
|
</Base>
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { IGetImageListener, ImageResult, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
|
import { IGetImageListener, ImageResult, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { CSSProperties, FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { BaseProps } from '..';
|
||||||
import { GetRoomEngine, ProductTypeEnum } from '../../api';
|
import { GetRoomEngine, ProductTypeEnum } from '../../api';
|
||||||
import { Base } from '../Base';
|
import { Base } from '../Base';
|
||||||
|
|
||||||
interface LayoutFurniImageViewProps
|
interface LayoutFurniImageViewProps extends BaseProps<HTMLDivElement>
|
||||||
{
|
{
|
||||||
productType: string;
|
productType: string;
|
||||||
productClassId: number;
|
productClassId: number;
|
||||||
@ -14,9 +15,32 @@ interface LayoutFurniImageViewProps
|
|||||||
|
|
||||||
export const LayoutFurniImageView: FC<LayoutFurniImageViewProps> = props =>
|
export const LayoutFurniImageView: FC<LayoutFurniImageViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { productType = 's', productClassId = -1, direction = 0, extraData = '', scale = 1 } = props;
|
const { productType = 's', productClassId = -1, direction = 2, extraData = '', scale = 1, style = {}, ...rest } = props;
|
||||||
const [ imageElement, setImageElement ] = useState<HTMLImageElement>(null);
|
const [ imageElement, setImageElement ] = useState<HTMLImageElement>(null);
|
||||||
|
|
||||||
|
const getStyle = useMemo(() =>
|
||||||
|
{
|
||||||
|
let newStyle: CSSProperties = {};
|
||||||
|
|
||||||
|
if(imageElement?.src?.length)
|
||||||
|
{
|
||||||
|
newStyle.backgroundImage = `url('${ imageElement.src }')`;
|
||||||
|
newStyle.width = imageElement.width;
|
||||||
|
newStyle.height = imageElement.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(scale !== 1)
|
||||||
|
{
|
||||||
|
newStyle.transform = `scale(${ scale })`;
|
||||||
|
|
||||||
|
if(!(scale % 1)) newStyle.imageRendering = 'pixelated';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
||||||
|
|
||||||
|
return newStyle;
|
||||||
|
}, [ imageElement, scale, style ]);
|
||||||
|
|
||||||
const buildImage = useCallback(() =>
|
const buildImage = useCallback(() =>
|
||||||
{
|
{
|
||||||
let imageResult: ImageResult = null;
|
let imageResult: ImageResult = null;
|
||||||
@ -59,7 +83,5 @@ export const LayoutFurniImageView: FC<LayoutFurniImageViewProps> = props =>
|
|||||||
|
|
||||||
if(!imageElement) return null;
|
if(!imageElement) return null;
|
||||||
|
|
||||||
const imageUrl = `url('${ imageElement.src }')`;
|
return <Base classNames={ [ 'furni-image' ] } style={ getStyle } { ...rest } />;
|
||||||
|
|
||||||
return <Base classNames={ [ 'furni-image', `scale-${ scale }` ] } style={ { backgroundImage: imageUrl, width: imageElement.width, height: imageElement.height } } />;
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
import { PetCustomPart, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
|
import { PetCustomPart, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useEffect, useRef, useState } from 'react';
|
import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { GetRoomEngine } from '../../api';
|
import { GetRoomEngine } from '../../api';
|
||||||
|
import { Base, BaseProps } from '../Base';
|
||||||
|
|
||||||
interface LayoutPetImageViewProps
|
interface LayoutPetImageViewProps extends BaseProps<HTMLDivElement>
|
||||||
{
|
{
|
||||||
figure?: string;
|
figure?: string;
|
||||||
typeId?: number;
|
typeId?: number;
|
||||||
paletteId?: number;
|
paletteId?: number;
|
||||||
color?: number;
|
petColor?: number;
|
||||||
customParts?: PetCustomPart[];
|
customParts?: PetCustomPart[];
|
||||||
posture?: string;
|
posture?: string;
|
||||||
headOnly?: boolean;
|
headOnly?: boolean;
|
||||||
@ -17,17 +18,35 @@ interface LayoutPetImageViewProps
|
|||||||
|
|
||||||
export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
|
export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { figure = '', typeId = -1, paletteId = -1, color = 0xFFFFFF, customParts = [], posture = 'std', headOnly = false, direction = 0, scale = 1 } = props;
|
const { figure = '', typeId = -1, paletteId = -1, petColor = 0xFFFFFF, customParts = [], posture = 'std', headOnly = false, direction = 0, scale = 1, style = {}, ...rest } = props;
|
||||||
const [ petUrl, setPetUrl ] = useState<string>(null);
|
const [ petUrl, setPetUrl ] = useState<string>(null);
|
||||||
const isDisposed = useRef(false);
|
const isDisposed = useRef(false);
|
||||||
|
|
||||||
|
const getStyle = useMemo(() =>
|
||||||
|
{
|
||||||
|
let newStyle: CSSProperties = {};
|
||||||
|
|
||||||
|
if(petUrl && petUrl.length) newStyle.backgroundImage = `url(${ petUrl })`;
|
||||||
|
|
||||||
|
if(scale !== 1)
|
||||||
|
{
|
||||||
|
newStyle.transform = `scale(${ scale })`;
|
||||||
|
|
||||||
|
if(!(scale % 1)) newStyle.imageRendering = 'pixelated';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
|
||||||
|
|
||||||
|
return newStyle;
|
||||||
|
}, [ petUrl, scale, style ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
let url = null;
|
let url = null;
|
||||||
|
|
||||||
let petTypeId = typeId;
|
let petTypeId = typeId;
|
||||||
let petPaletteId = paletteId;
|
let petPaletteId = paletteId;
|
||||||
let petColor = color;
|
let petColor1 = petColor;
|
||||||
let petCustomParts = customParts;
|
let petCustomParts = customParts;
|
||||||
let petHeadOnly = headOnly;
|
let petHeadOnly = headOnly;
|
||||||
|
|
||||||
@ -37,13 +56,13 @@ export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
|
|||||||
|
|
||||||
petTypeId = petFigureData.typeId;
|
petTypeId = petFigureData.typeId;
|
||||||
petPaletteId = petFigureData.paletteId;
|
petPaletteId = petFigureData.paletteId;
|
||||||
petColor = petFigureData.color;
|
petColor1 = petFigureData.color;
|
||||||
petCustomParts = petFigureData.customParts;
|
petCustomParts = petFigureData.customParts;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(petTypeId === 16) petHeadOnly = false;
|
if(petTypeId === 16) petHeadOnly = false;
|
||||||
|
|
||||||
const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor, new Vector3d((direction * 45)), 64, {
|
const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor1, new Vector3d((direction * 45)), 64, {
|
||||||
imageReady: (id, texture, image) =>
|
imageReady: (id, texture, image) =>
|
||||||
{
|
{
|
||||||
if(isDisposed.current) return;
|
if(isDisposed.current) return;
|
||||||
@ -65,7 +84,7 @@ export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}, [ figure, typeId, paletteId, color, customParts, posture, headOnly, direction ]);
|
}, [ figure, typeId, paletteId, petColor, customParts, posture, headOnly, direction ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -78,6 +97,6 @@ export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const url = `url('${ petUrl }')`;
|
const url = `url('${ petUrl }')`;
|
||||||
|
|
||||||
return <div className={ 'pet-image scale-' + scale.toString().replace('.', '-') } style={ (petUrl && url.length) ? { backgroundImage: url } : {} }></div>;
|
return <Base classNames={ [ 'pet-image' ] } style={ getStyle } { ...rest } />;
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,20 @@
|
|||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
box-shadow: 0 0 0 1.5px $white;
|
box-shadow: 0 0 0 1.5px $white;
|
||||||
border: 2px solid #921911;
|
border: 2px solid #921911;
|
||||||
background: repeating-linear-gradient(rgba(245,80,65,1), rgba(245,80,65,1) 50%, rgba(194,48,39,1) 50%, rgba(194,48,39,1) 100%);
|
background: repeating-linear-gradient(
|
||||||
|
rgba(245, 80, 65, 1),
|
||||||
|
rgba(245, 80, 65, 1) 50%,
|
||||||
|
rgba(194, 48, 39, 1) 50%,
|
||||||
|
rgba(194, 48, 39, 1) 100%
|
||||||
|
);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
padding: 1px 3px;
|
padding: 1px 3px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
filter: brightness(1.2);
|
filter: brightness(1.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
filter: brightness(0.8);
|
filter: brightness(0.8);
|
||||||
}
|
}
|
||||||
@ -28,42 +33,41 @@
|
|||||||
width: 320px;
|
width: 320px;
|
||||||
height: 320px;
|
height: 320px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.camera-canvas {
|
.camera-canvas {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 340px;
|
width: 340px;
|
||||||
height: 462px;
|
height: 462px;
|
||||||
background-image: url('../../assets/images/room-widgets/camera-widget/camera-spritesheet.png');
|
background-image: url("../../assets/images/room-widgets/camera-widget/camera-spritesheet.png");
|
||||||
background-position: -1px -1px;
|
background-position: -1px -1px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
.camera-button {
|
.camera-button {
|
||||||
width: 94px;
|
width: 94px;
|
||||||
height: 94px;
|
height: 94px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-top: 362px;
|
margin-top: 362px;
|
||||||
|
|
||||||
background-image: url('../../assets/images/room-widgets/camera-widget/camera-spritesheet.png');
|
background-image: url("../../assets/images/room-widgets/camera-widget/camera-spritesheet.png");
|
||||||
background-position: -343px -321px;
|
background-position: -343px -321px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-position: -535px -321px;
|
background-position: -535px -321px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:active {
|
&:active {
|
||||||
background-position: -439px -321px;
|
background-position: -439px -321px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.camera-view-finder {
|
.camera-view-finder {
|
||||||
background-image: url('../../assets/images/room-widgets/camera-widget/camera-spritesheet.png');
|
background-image: url("../../assets/images/room-widgets/camera-widget/camera-spritesheet.png");
|
||||||
background-position: -343px -1px;
|
background-position: -343px -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.camera-frame {
|
.camera-frame {
|
||||||
|
|
||||||
.camera-frame-preview-actions {
|
.camera-frame-preview-actions {
|
||||||
background: rgba(0, 0, 0, .5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +84,8 @@
|
|||||||
width: 56px;
|
width: 56px;
|
||||||
height: 56px;
|
height: 56px;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
|
object-fit: contain;
|
||||||
|
image-rendering: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +93,7 @@
|
|||||||
.nitro-camera-editor {
|
.nitro-camera-editor {
|
||||||
width: $camera-editor-width;
|
width: $camera-editor-width;
|
||||||
height: $camera-editor-height;
|
height: $camera-editor-height;
|
||||||
|
|
||||||
.picture-preview {
|
.picture-preview {
|
||||||
width: 320px;
|
width: 320px;
|
||||||
height: 320px;
|
height: 320px;
|
||||||
@ -99,7 +105,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.effect-thumbnail-image {
|
.effect-thumbnail-image {
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer';
|
import { IRoomCameraWidgetEffect, IRoomCameraWidgetSelectedEffect } from '@nitrots/nitro-renderer';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { AutoGrid } from '../../../../../common/AutoGrid';
|
import { Grid } from '../../../../../common';
|
||||||
import { CameraPictureThumbnail } from '../../../common/CameraPictureThumbnail';
|
import { CameraPictureThumbnail } from '../../../common/CameraPictureThumbnail';
|
||||||
import { CameraWidgetEffectListItemView } from './CameraWidgetEffectListItemView';
|
import { CameraWidgetEffectListItemView } from './CameraWidgetEffectListItemView';
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export const CameraWidgetEffectListView: FC<CameraWidgetEffectListViewProps> = p
|
|||||||
const { myLevel = 0, selectedEffects = [], effects = [], thumbnails = [], processAction = null } = props;
|
const { myLevel = 0, selectedEffects = [], effects = [], thumbnails = [], processAction = null } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutoGrid columnCount={ 2 } columnMinHeight={ 60 }>
|
<Grid columnCount={ 3 } overflow="auto">
|
||||||
{ effects && (effects.length > 0) && effects.map((effect, index) =>
|
{ effects && (effects.length > 0) && effects.map((effect, index) =>
|
||||||
{
|
{
|
||||||
const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name)));
|
const thumbnailUrl = (thumbnails.find(thumbnail => (thumbnail.effectName === effect.name)));
|
||||||
@ -26,6 +26,6 @@ export const CameraWidgetEffectListView: FC<CameraWidgetEffectListViewProps> = p
|
|||||||
|
|
||||||
return <CameraWidgetEffectListItemView key={ index } effect={ effect } thumbnailUrl={ ((thumbnailUrl && thumbnailUrl.thumbnailUrl) || null) } isActive={ isActive } isLocked={ (effect.minLevel > myLevel) } selectEffect={ () => processAction('select_effect', effect.name) } removeEffect={ () => processAction('remove_effect', effect.name) } />
|
return <CameraWidgetEffectListItemView key={ index } effect={ effect } thumbnailUrl={ ((thumbnailUrl && thumbnailUrl.thumbnailUrl) || null) } isActive={ isActive } isLocked={ (effect.minLevel > myLevel) } selectEffect={ () => processAction('select_effect', effect.name) } removeEffect={ () => processAction('remove_effect', effect.name) } />
|
||||||
}) }
|
}) }
|
||||||
</AutoGrid>
|
</Grid>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ export const RoomColorView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
if(!roomSession) return;
|
if(!roomSession) return;
|
||||||
|
|
||||||
const canvas = GetRoomEngine().getRoomInstanceRenderingCanvas(GetRoomEngine().activeRoomId, 1);
|
const canvas = GetRoomEngine().getRoomInstanceRenderingCanvas(roomSession.roomId, 1);
|
||||||
|
|
||||||
if(!canvas) return;
|
if(!canvas) return;
|
||||||
|
|
||||||
|
@ -88,9 +88,7 @@ export const RoomView: FC<{}> = props =>
|
|||||||
const roomEngine = GetRoomEngine();
|
const roomEngine = GetRoomEngine();
|
||||||
const roomId = roomSession.roomId;
|
const roomId = roomSession.roomId;
|
||||||
const canvasId = 1;
|
const canvasId = 1;
|
||||||
const displayObject = roomEngine.getRoomInstanceDisplay(roomId, canvasId, (window.innerWidth * window.devicePixelRatio), (window.innerHeight * window.devicePixelRatio), RoomGeometry.SCALE_ZOOMED_IN);
|
const displayObject = roomEngine.getRoomInstanceDisplay(roomId, canvasId, window.innerWidth, window.innerHeight, RoomGeometry.SCALE_ZOOMED_IN);
|
||||||
|
|
||||||
if((window.devicePixelRatio !== 1) && ((window.devicePixelRatio % 1) === 0)) roomEngine.setRoomInstanceRenderingCanvasScale(roomId, canvasId, window.devicePixelRatio);
|
|
||||||
|
|
||||||
if(!displayObject) return;
|
if(!displayObject) return;
|
||||||
|
|
||||||
@ -141,25 +139,20 @@ export const RoomView: FC<{}> = props =>
|
|||||||
canvas.ontouchend = event => DispatchTouchEvent(event);
|
canvas.ontouchend = event => DispatchTouchEvent(event);
|
||||||
canvas.ontouchcancel = event => DispatchTouchEvent(event);
|
canvas.ontouchcancel = event => DispatchTouchEvent(event);
|
||||||
|
|
||||||
if(window.devicePixelRatio !== 1)
|
canvas.style.width = `${ Math.floor(window.innerWidth) }px`;
|
||||||
{
|
canvas.style.height = `${ Math.floor(window.innerHeight) }px`;
|
||||||
let scaleValue = (1 / window.devicePixelRatio);
|
|
||||||
|
|
||||||
canvas.style.transform = `scale(${ scaleValue })`;
|
|
||||||
canvas.style.transformOrigin = 'top left';
|
|
||||||
canvas.style.width = `${ (100 * window.devicePixelRatio) }%`;
|
|
||||||
canvas.style.height = `${ (100 * window.devicePixelRatio) }%`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const resize = (event: UIEvent) =>
|
const resize = (event: UIEvent) =>
|
||||||
{
|
{
|
||||||
|
canvas.style.width = `${ Math.floor(window.innerWidth) }px`;
|
||||||
|
canvas.style.height = `${ Math.floor(window.innerHeight) }px`;
|
||||||
|
|
||||||
const nitroInstance = GetNitroInstance();
|
const nitroInstance = GetNitroInstance();
|
||||||
const width = (window.innerWidth * window.devicePixelRatio);
|
|
||||||
const height = (window.innerHeight * window.devicePixelRatio);
|
|
||||||
|
|
||||||
nitroInstance.renderer.resize(width, height);
|
nitroInstance.renderer.resolution = window.devicePixelRatio;
|
||||||
|
nitroInstance.renderer.resize(window.innerWidth, window.innerHeight);
|
||||||
|
|
||||||
InitializeRoomInstanceRenderingCanvas(width, height, 1);
|
InitializeRoomInstanceRenderingCanvas(window.innerWidth, window.innerHeight, 1);
|
||||||
|
|
||||||
nitroInstance.render();
|
nitroInstance.render();
|
||||||
}
|
}
|
||||||
@ -180,8 +173,7 @@ export const RoomView: FC<{}> = props =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<RoomContextProvider value={ { roomSession, eventDispatcher: (widgetHandler && widgetHandler.eventDispatcher), widgetHandler } }>
|
<RoomContextProvider value={ { roomSession, eventDispatcher: (widgetHandler && widgetHandler.eventDispatcher), widgetHandler } }>
|
||||||
<Base fit className={ (!roomSession && 'd-none') }>
|
<Base fit innerRef={ elementRef } className={ (!roomSession && 'd-none') }>
|
||||||
<Base innerRef={ elementRef } />
|
|
||||||
{ (roomSession && widgetHandler) &&
|
{ (roomSession && widgetHandler) &&
|
||||||
<>
|
<>
|
||||||
<RoomColorView />
|
<RoomColorView />
|
||||||
|
@ -69,7 +69,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ paletteId } color={ petFigureData.color } customParts={ petFigureData.customParts } direction={ 2 } />
|
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ paletteId } petColor={ petFigureData.color } customParts={ petFigureData.customParts } direction={ 2 } />
|
||||||
}
|
}
|
||||||
case FurniCategory.PET_CUSTOM_PART: {
|
case FurniCategory.PET_CUSTOM_PART: {
|
||||||
if(customParts.length < 4) return null;
|
if(customParts.length < 4) return null;
|
||||||
@ -96,7 +96,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
_local_10++;
|
_local_10++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } petColor={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
case FurniCategory.PET_CUSTOM_PART_SHAMPOO: {
|
case FurniCategory.PET_CUSTOM_PART_SHAMPOO: {
|
||||||
if(customParts.length < 3) return null;
|
if(customParts.length < 3) return null;
|
||||||
@ -122,7 +122,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
_local_10++;
|
_local_10++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } petColor={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
case FurniCategory.PET_SADDLE: {
|
case FurniCategory.PET_SADDLE: {
|
||||||
if(customParts.length < 4) return null;
|
if(customParts.length < 4) return null;
|
||||||
@ -150,7 +150,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } petColor={ petFigureData.color } customParts={ newCustomParts } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
case FurniCategory.MONSTERPLANT_REBREED:
|
case FurniCategory.MONSTERPLANT_REBREED:
|
||||||
case FurniCategory.MONSTERPLANT_REVIVAL:
|
case FurniCategory.MONSTERPLANT_REVIVAL:
|
||||||
@ -172,7 +172,7 @@ export const AvatarInfoUseProductConfirmView: FC<AvatarInfoUseProductConfirmView
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } color={ petFigureData.color } customParts={ petFigureData.customParts } posture={ posture } direction={ 2 } />;
|
return <LayoutPetImageView typeId={ petFigureData.typeId } paletteId={ petFigureData.paletteId } petColor={ petFigureData.color } customParts={ petFigureData.customParts } posture={ posture } direction={ 2 } />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [ petData, furniData, roomSession ]);
|
}, [ petData, furniData, roomSession ]);
|
||||||
|
@ -697,15 +697,15 @@
|
|||||||
|
|
||||||
.user-image {
|
.user-image {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -48px;
|
top: -15px;
|
||||||
left: -32.5px;
|
left: -9.25px;
|
||||||
width: 90px;
|
width: 45px;
|
||||||
height: 130px;
|
height: 65px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
transform: scale(0.5);
|
transform: scale(0.5);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
image-rendering: -webkit-optimize-contrast;
|
image-rendering: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ export const ChatWidgetView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
if(!chatMessages.length || (event.roomId !== roomSession.roomId)) return;
|
if(!chatMessages.length || (event.roomId !== roomSession.roomId)) return;
|
||||||
|
|
||||||
const offsetX = (event.offsetX / window.devicePixelRatio);
|
const offsetX = event.offsetX;
|
||||||
|
|
||||||
chatMessages.forEach(chat => (chat.elementRef && (chat.left += offsetX)));
|
chatMessages.forEach(chat => (chat.elementRef && (chat.left += offsetX)));
|
||||||
}, [ roomSession, chatMessages ]);
|
}, [ roomSession, chatMessages ]);
|
||||||
@ -200,7 +200,7 @@ export const ChatWidgetView: FC<{}> = props =>
|
|||||||
if(!elementRef || !elementRef.current) return;
|
if(!elementRef || !elementRef.current) return;
|
||||||
|
|
||||||
const currentHeight = elementRef.current.offsetHeight;
|
const currentHeight = elementRef.current.offsetHeight;
|
||||||
const newHeight = (document.body.offsetHeight * GetConfiguration<number>('chat.viewer.height.percentage'));
|
const newHeight = Math.round(document.body.offsetHeight * GetConfiguration<number>('chat.viewer.height.percentage'));
|
||||||
|
|
||||||
elementRef.current.style.height = `${ newHeight }px`;
|
elementRef.current.style.height = `${ newHeight }px`;
|
||||||
|
|
||||||
@ -208,17 +208,7 @@ export const ChatWidgetView: FC<{}> = props =>
|
|||||||
{
|
{
|
||||||
if(prevValue)
|
if(prevValue)
|
||||||
{
|
{
|
||||||
prevValue.forEach(chat =>
|
prevValue.forEach(chat => (chat.top -= (currentHeight - newHeight)));
|
||||||
{
|
|
||||||
if(chat.skipMovement)
|
|
||||||
{
|
|
||||||
chat.skipMovement = false;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
chat.top -= (currentHeight - newHeight);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return prevValue;
|
return prevValue;
|
||||||
|
@ -27,9 +27,10 @@ export const RoomToolsWidgetView: FC<{}> = props =>
|
|||||||
case 'zoom':
|
case 'zoom':
|
||||||
setIsZoomedIn(prevValue =>
|
setIsZoomedIn(prevValue =>
|
||||||
{
|
{
|
||||||
let scale = ((window.devicePixelRatio !== 1) && ((window.devicePixelRatio % 1) === 0)) ? window.devicePixelRatio : 1;
|
let scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomSession.roomId, 1);
|
||||||
|
|
||||||
if(!prevValue) scale /= 2;
|
if(!prevValue) scale /= 2;
|
||||||
|
else scale *= 2;
|
||||||
|
|
||||||
GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale);
|
GetRoomEngine().setRoomInstanceRenderingCanvasScale(roomSession.roomId, 1, scale);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
|
|||||||
<Flex gap={ 2 } alignItems="center">
|
<Flex gap={ 2 } alignItems="center">
|
||||||
<Flex alignItems="center" gap={ 2 }>
|
<Flex alignItems="center" gap={ 2 }>
|
||||||
<Flex center pointer className={ 'navigation-item item-avatar ' + (isMeExpanded ? 'active ' : '') } onClick={ event => setMeExpanded(!isMeExpanded) }>
|
<Flex center pointer className={ 'navigation-item item-avatar ' + (isMeExpanded ? 'active ' : '') } onClick={ event => setMeExpanded(!isMeExpanded) }>
|
||||||
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } />
|
<LayoutAvatarImageView figure={ userFigure } direction={ 2 } position="absolute" />
|
||||||
{ (getTotalUnseen > 0) &&
|
{ (getTotalUnseen > 0) &&
|
||||||
<LayoutItemCountView count={ getTotalUnseen } /> }
|
<LayoutItemCountView count={ getTotalUnseen } /> }
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
@import "./assets/styles";
|
||||||
@import './assets/styles';
|
|
||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
@ -8,10 +7,13 @@ body {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
image-rendering: pixelated;
|
|
||||||
image-rendering: -moz-crisp-edges;
|
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
|
|
||||||
|
.image-rendering-pixelated {
|
||||||
|
image-rendering: pixelated;
|
||||||
|
image-rendering: -moz-crisp-edges;
|
||||||
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
@ -21,4 +23,4 @@ img {
|
|||||||
object-fit: none;
|
object-fit: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './App';
|
@import "./App";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user