Add watch view export and update promo video watch display
- Add ExportableWatchViews.swift with exportable versions of watch app views - Add WatchExporter.swift service to export all watch view variations - Add export watch screenshots button to Settings (DEBUG) - Update ConceptB promo: use watch_voting_light.png inside watch frame at 1.2x size Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
BIN
feels-promo/public/watch_voting_light.png
Normal file
BIN
feels-promo/public/watch_voting_light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 76 KiB |
@@ -139,7 +139,7 @@ const ProblemScene: React.FC = () => {
|
||||
// Scene 2: Single tap voting - Widget, Watch, In-App
|
||||
const SingleTapScene: React.FC = () => {
|
||||
const frame = useCurrentFrame();
|
||||
const { fps, width } = useVideoConfig();
|
||||
const { fps, width, height } = useVideoConfig();
|
||||
|
||||
// Title animations (matching other scenes)
|
||||
const line1Progress = spring({ frame, fps, config: { damping: 200 } });
|
||||
@@ -174,7 +174,7 @@ const SingleTapScene: React.FC = () => {
|
||||
});
|
||||
|
||||
|
||||
const watchSize = width * 0.27;
|
||||
const watchSize = width * 0.27 * 1.2;
|
||||
const widgetSize = width * 0.33;
|
||||
|
||||
return (
|
||||
@@ -239,172 +239,165 @@ const SingleTapScene: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Three device rows - full width, image at 33%, label at 66% */}
|
||||
{/* Watch row - top at 33% */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "33%",
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 450,
|
||||
bottom: 80,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-evenly",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{/* Watch row */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
left: "33%",
|
||||
transform: "translateX(-50%)",
|
||||
}}
|
||||
>
|
||||
{/* Image at 33% */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "33%",
|
||||
transform: "translateX(-50%)",
|
||||
position: "relative",
|
||||
width: watchSize,
|
||||
height: watchSize,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
<Img
|
||||
src={staticFile("watch_voting_light.png")}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: "48%",
|
||||
height: "auto",
|
||||
borderRadius: 8,
|
||||
zIndex: 1,
|
||||
}}
|
||||
/>
|
||||
<Img
|
||||
src={staticFile("watch.png")}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
filter: "drop-shadow(0 10px 30px rgba(0,0,0,0.3))",
|
||||
position: "relative",
|
||||
width: watchSize,
|
||||
height: watchSize,
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("watch.png")}
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
filter: "drop-shadow(0 10px 30px rgba(0,0,0,0.3))",
|
||||
}}
|
||||
/>
|
||||
<Img
|
||||
src={staticFile("vote_light_small_notvoted.png")}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
width: "62%",
|
||||
height: "auto",
|
||||
borderRadius: 8,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/* Label at 66% */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "66%",
|
||||
fontSize: 58,
|
||||
fontWeight: 700,
|
||||
color: "white",
|
||||
fontFamily: "system-ui, -apple-system, sans-serif",
|
||||
textShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
||||
opacity: interpolate(watchLabelProgress, [0, 1], [0, 1]),
|
||||
transform: `translateX(${interpolate(watchLabelProgress, [0, 1], [30, 0])}px)`,
|
||||
}}
|
||||
>
|
||||
Watch
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* In-App row */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{/* Image at 33% */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "33%",
|
||||
transform: "translateX(-50%)",
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("voting_header.png")}
|
||||
style={{
|
||||
width: widgetSize * 1.1,
|
||||
height: "auto",
|
||||
borderRadius: 24,
|
||||
boxShadow: "0 10px 40px rgba(0,0,0,0.3)",
|
||||
zIndex: 2,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/* Label at 66% */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "66%",
|
||||
fontSize: 58,
|
||||
fontWeight: 700,
|
||||
color: "white",
|
||||
fontFamily: "system-ui, -apple-system, sans-serif",
|
||||
textShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
||||
opacity: interpolate(inAppLabelProgress, [0, 1], [0, 1]),
|
||||
transform: `translateX(${interpolate(inAppLabelProgress, [0, 1], [30, 0])}px)`,
|
||||
}}
|
||||
>
|
||||
In-App
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Widget row */}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
left: "66%",
|
||||
fontSize: 58,
|
||||
fontWeight: 700,
|
||||
color: "white",
|
||||
fontFamily: "system-ui, -apple-system, sans-serif",
|
||||
textShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
||||
opacity: interpolate(watchLabelProgress, [0, 1], [0, 1]),
|
||||
transform: `translateX(${interpolate(watchLabelProgress, [0, 1], [30, 0])}px)`,
|
||||
}}
|
||||
>
|
||||
{/* Image at 33% */}
|
||||
<div
|
||||
Watch
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* In-App row - centered at 61.5% (midpoint of 33% and 90%) */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "61.5%",
|
||||
left: 0,
|
||||
right: 0,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
transform: "translateY(-50%)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "33%",
|
||||
transform: "translateX(-50%)",
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("voting_light_large.png")}
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "33%",
|
||||
transform: "translateX(-50%)",
|
||||
width: widgetSize * 1.1,
|
||||
height: "auto",
|
||||
borderRadius: 24,
|
||||
boxShadow: "0 10px 40px rgba(0,0,0,0.3)",
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("vote_dark_medium_notvoted.png")}
|
||||
style={{
|
||||
width: widgetSize,
|
||||
height: "auto",
|
||||
borderRadius: 24,
|
||||
boxShadow: "0 10px 40px rgba(0,0,0,0.3)",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/* Label at 66% */}
|
||||
<div
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "66%",
|
||||
fontSize: 58,
|
||||
fontWeight: 700,
|
||||
color: "white",
|
||||
fontFamily: "system-ui, -apple-system, sans-serif",
|
||||
textShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
||||
opacity: interpolate(inAppLabelProgress, [0, 1], [0, 1]),
|
||||
transform: `translateX(${interpolate(inAppLabelProgress, [0, 1], [30, 0])}px)`,
|
||||
}}
|
||||
>
|
||||
In-App
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Widget row - bottom at 90% (10% from bottom) */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "10%",
|
||||
left: 0,
|
||||
right: 0,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "33%",
|
||||
bottom: 0,
|
||||
transform: "translateX(-50%)",
|
||||
}}
|
||||
>
|
||||
<Img
|
||||
src={staticFile("voting_light_medium.png")}
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "66%",
|
||||
fontSize: 58,
|
||||
fontWeight: 700,
|
||||
color: "white",
|
||||
fontFamily: "system-ui, -apple-system, sans-serif",
|
||||
textShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
||||
opacity: interpolate(widgetLabelProgress, [0, 1], [0, 1]),
|
||||
transform: `translateX(${interpolate(widgetLabelProgress, [0, 1], [30, 0])}px)`,
|
||||
width: widgetSize,
|
||||
height: "auto",
|
||||
borderRadius: 24,
|
||||
boxShadow: "0 10px 40px rgba(0,0,0,0.3)",
|
||||
}}
|
||||
>
|
||||
Widget
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "66%",
|
||||
bottom: 0,
|
||||
height: widgetSize * 0.47,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
fontSize: 58,
|
||||
fontWeight: 700,
|
||||
color: "white",
|
||||
fontFamily: "system-ui, -apple-system, sans-serif",
|
||||
textShadow: "0 4px 20px rgba(0,0,0,0.3)",
|
||||
opacity: interpolate(widgetLabelProgress, [0, 1], [0, 1]),
|
||||
transform: `translateX(${interpolate(widgetLabelProgress, [0, 1], [30, 0])}px)`,
|
||||
}}
|
||||
>
|
||||
Widget
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user