diff --git a/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.scss b/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.scss new file mode 100644 index 0000000000..bd851295b9 --- /dev/null +++ b/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.scss @@ -0,0 +1,99 @@ +@import "scss/colours.scss"; +@import "scss/site-refresh.scss"; + +.fy-zoom-slider { + display: flex; + + &.fy-zoom-slider-vertical { + height: 100%; + flex-direction: column; + + .fy-zoom-slider-container { + height: 100%; + margin: 1.5rem 0; + } + + .fy-zoom-slider-track { + height: 100%; + width: 2.25rem; + justify-content: center; + } + + .fy-zoom-slider-track-bar { + width: 0.5rem; + height: 100%; + } + } + + &.fy-zoom-slider-horizontal { + width: 100%; + flex-direction: row-reverse; + + .fy-zoom-slider-container { + width: 100%; + margin: 0 1.5rem; + } + + .fy-zoom-slider-track { + width: 100%; + height: 2.25rem; + align-items: center; + } + + .fy-zoom-slider-track-bar { + height: 0.5rem; + width: 100%; + } + + svg { + align-self: center; + } + } + + svg { + color: rgba(#fff, 0.25); + cursor: pointer; + transition: color 0.25s ease-in-out; + + &:hover { + color: rgba(#fff, 0.5); + } + } + + .fy-zoom-slider-container { + height: 100%; + } + + .fy-zoom-slider-track { + display: inline-flex; + + .fy-zoom-slider-track-bar { + background-color: $secondary-darker; + border-radius: 0.25rem; + box-shadow: inset 0 5px 10px rgb(#000, 0.25); + border-bottom: 1px solid rgba(#fff, 0.07); + } + } + + .fy-zoom-slider-thumb { + color: rgba(#fff, 0.6); + border: 1px solid rgba(#fff, 0.04); + border-left: none; + border-right: none; + box-shadow: 0 5px 10px rgb(#000, 0.25); + + display: flex; + justify-content: center; + align-items: center; + font-size: 0.75rem; + background-color: $secondary; + border-radius: 0.75rem; + height: 2.25rem; + width: 2.25rem; + + &:focus-visible { + background-color: $secondary-light; + outline: none; + } + } +} diff --git a/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.tsx b/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.tsx index ed851aada8..bbdf63f1ae 100644 --- a/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.tsx +++ b/src/website/packages/fakeyou.com/src/components/common/ZoomSlider/ZoomSlider.tsx @@ -5,13 +5,15 @@ import { faMagnifyingGlassPlus, faMagnifyingGlassMinus, } from "@fortawesome/pro-solid-svg-icons"; +import "./ZoomSlider.scss"; export interface ZoomSliderOnChangeEvent { target: { name?: string; type: "zoom"; value: number }; } -interface Props { +interface ZoomSliderProps { name?: string; + horizontal?: boolean; onChange: (event: ZoomSliderOnChangeEvent) => void; value: number; } @@ -35,37 +37,64 @@ const thumb = export default function ZoomSlider({ name = "", + horizontal, onChange: inChange, value, -}: Props) { +}: ZoomSliderProps) { const onChange = (newVal: number[]) => inChange({ target: { ...(name && { name }), type: "zoom", value: newVal[0] }, }); + // react-easy-crop returns a zoom value from 1 to 3, so a range of 2 when starting with 0 + + const valueRange = 2; + const incrementDecrement = valueRange / 100; + return ( -
- +
+ { + if (value < 3) { + onChange([value + incrementDecrement]); + } + }, + }} + />
- + { + if (value > 1) { + onChange([value - incrementDecrement]); + } + }, + }} + />
); } diff --git a/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.scss b/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.scss index 8bcde1201a..7f5f6839f0 100644 --- a/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.scss +++ b/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.scss @@ -17,7 +17,7 @@ border-radius: 0.5rem; overflow: hidden; position: relative; - // background-color: $panel; + width: 100%; .fy-entity-input-crop-container-hidden { cursor: default; @@ -38,6 +38,33 @@ 0 0 15px rgb(#000, 0.5); } + .fy-entity-input-full { + display: grid; + } + + &.fy-entity-input-narrow { + min-height: 400px; + // background-color: red; + + .fy-entity-input-full { + grid-template-columns: 1fr; + grid-template-rows: 1fr auto; + + & > div { + width: 100%; + } + } + } + + &.fy-entity-input-wide { + min-height: 300px; + // background-color: red; + + .fy-entity-input-full { + grid-template-columns: 1fr fit-content(50%); + } + } + .fy-entity-input-play-button { @include video-tint; border: none; @@ -61,14 +88,6 @@ } } -.fy-entity-input-square { - aspect-ratio: 1/1; - height: 300px; - - .fy-entity-input-empty-controls { - } -} - .fy-entity-input-landscape { width: 100%; aspect-ratio: 4/3; @@ -77,16 +96,13 @@ .fy-entity-input-empty, .fy-entity-input-full { - // background-color: red; position: relative; - // overflow: hidden; justify-content: center; .fy-entity-input-icon { position: absolute; height: 80%; opacity: 75%; - // background-color: blue; margin: auto; inset: 0; @@ -97,8 +113,6 @@ .fy-entity-input-file-details { padding: 0 0.5rem; - // background-color: red; - // display: inline-flex; div { font-size: 0.75rem; } @@ -121,70 +135,43 @@ margin: 0; } -.fy-entity-input-full { - display: grid; - grid-template-columns: 1fr fit-content(50%); - // grid-template-rows: 1fr 1fr; - // display: flex; - - // video { - // width: 100%; - // } -} - .fy-entity-input-media-preview { - // display: inline-block; position: relative; - // width: 66%; - // height: 100%; - // width: 100%; - // aspect-ratio: 1; padding: 0.5rem; } .fy-entity-input-preview-controls { + // background-color: green; display: grid; // background-color: red; grid-template-rows: 1fr auto; + + background-color: $secondary-dark; gap: 0.5rem; padding: 1rem; } -.fy-entity-input-preview-tools { +.fy-entity-input-preview-tools-narrow, +.fy-entity-input-preview-tools-wide { display: grid; - grid-template-columns: auto 1fr; - // grid-template-rows: 1fr auto; + // grid-template-columns: auto 1fr; gap: 0.5rem; - // display: inline-block; - // width: 33%; - // height: 100%; - background-color: $secondary-dark; - - // display: flex; - // align-items: center; - // justify-content: space-between; - // position: absolute; - // background-color: red; - // background-color: rgba(#000, 0.5); - // background: linear-gradient( - // 0deg, - // rgba(0, 0, 0, 0) 0%, - // rgba(0, 0, 0, 0.1) 6.25%, - // rgba(0, 0, 0, 0.25) 12.5%, - // rgba(0, 0, 0, 0.4) 18.75%, - // rgba(0, 0, 0, 0.5) 25% - // ); - // padding: 1rem; - // backdrop-filter: blur(2px); overflow: hidden; border-radius: 0.5rem 0.5rem 0 0; - // width: 100%; .fy-zoom-slider { padding: 0.5rem 0; } } +.fy-entity-input-preview-tools-wide { + grid-template-columns: auto 1fr; +} + +.fy-entity-input-preview-tools-narrow { + grid-template-rows: auto 1fr; +} + .fy-entity-input-empty-controls { // background-color: red; position: absolute; @@ -230,69 +217,3 @@ } } } - -.fy-zoom-slider { - display: flex; - flex-direction: column; - height: 100%; - // padding: 1rem 0; - - svg { - color: rgba(#fff, 0.25); - } -} - -.fy-zoom-slider-container { - height: 100%; - // background-color: red; - margin: 1.5rem 0; - // width: 3rem; -} - -.fy-zoom-slider-track { - display: inline-flex; - justify-content: center; - height: 100%; - width: 2.25rem; - // background-color: green; - - .fy-zoom-slider-track-bar { - background-color: $secondary-darker; - border-radius: 0.25rem; - // margin: 1rem 0; - // flex-shrink: 1; - box-shadow: - // inset 0 0 1px 1px rgba(#000, 0.16), - inset 0 5px 10px rgb(#000, 0.25); - border-bottom: 1px solid rgba(#fff, 0.07); - // border-left: none; - // border-right: none; - width: 0.5rem; - height: 100%; - } -} - -.fy-zoom-slider-thumb { - color: rgba(#fff, 0.6); - border: 1px solid rgba(#fff, 0.04); - border-left: none; - border-right: none; - box-shadow: - // 0 0 0 1px rgba(#000, 0.16), - 0 5px 10px rgb(#000, 0.25); - // @include panel; - display: flex; - justify-content: center; - align-items: center; - font-size: 0.75rem; - background-color: $secondary; - border-radius: 0.75rem; - height: 2.25rem; - width: 2.25rem; - - &:focus-visible { - // color: $secondary; - background-color: $secondary-light; - outline: none; - } -} diff --git a/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.tsx b/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.tsx index b95146ec6b..b87b281029 100644 --- a/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.tsx +++ b/src/website/packages/fakeyou.com/src/components/entities/EntityInput/EntityInput.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from "react"; import { useLocation } from "react-router-dom"; import { a, useTransition } from "@react-spring/web"; +import useMeasure from "react-use-measure"; import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia"; import Iframe from "react-iframe"; import { Area, Point } from "react-easy-crop"; @@ -32,7 +33,7 @@ export interface CropProps { interface EntityInputProps { accept?: AcceptTypes | AcceptTypes[]; - aspectRatio?: "square" | "landscape" | "portrait"; + // aspectRatio?: "square" | "landscape" | "portrait"; className?: string; cropProps?: CropProps; debug?: string; @@ -47,6 +48,7 @@ interface EntityInputProps { export interface SlideProps { clear: () => void; cropProps?: CropProps; + isNarrow: boolean; media?: MediaFile; } @@ -63,7 +65,7 @@ const MediaBusy = () => { return ; }; -const EntityInputFull = ({ clear, cropProps, media }: SlideProps) => { +const EntityInputFull = ({ clear, cropProps, isNarrow, media }: SlideProps) => { const bucketConfig = new BucketConfig(); const mediaUrl = media?.public_bucket_path ? bucketConfig.getGcsUrl(media.public_bucket_path) @@ -94,6 +96,7 @@ const EntityInputFull = ({ clear, cropProps, media }: SlideProps) => { {...{ clear, entityType: "image", + isNarrow, media, showCrop: !!cropProps, zoomSliderChange, @@ -119,6 +122,7 @@ const EntityInputFull = ({ clear, cropProps, media }: SlideProps) => { {...{ clear, entityType: "video", + isNarrow, media, showCrop: !!cropProps, zoomSliderChange, @@ -166,7 +170,6 @@ const AnimatedSlide = ({ export default function EntityInput({ accept, - aspectRatio = "square", className, cropProps, debug, @@ -194,6 +197,10 @@ export default function EntityInput({ mediaToken: mediaToken || value, }); const [updated, updatedSet] = useState(false); + const [outerRef, { width }] = useMeasure(); + + const isNarrow = (width || 0) <= 480; + const clear = () => { mediaSet(undefined); mediaTokenSet(""); @@ -260,9 +267,10 @@ export default function EntityInput({