1 Commits
Author SHA1 Message Date
thepraandClaude Opus 5.5 3d6315fe1e "me-web?" 0.14.0: the first three cards, drawn again
Build / Desktop, server and tools (push) Successful in 1m15s
Release / Every platform, the server, the release (push) Successful in 10m13s
- The three pictures at the top are new: a small planet at dusk under twinkling stars, with town lights on its night
  side, drifting clouds, smoke from the chimney and trees that sway.
- The house and the block of flats now have lit walls, a tiled roof, glowing windows and soft shadows.
- The photo now flies like a little print and the visitor is a letter, because a letter needs an address. Each flies
  along its route with a glowing trail. At the house the door lights up green; at the block of flats the letter stops
  at the main door while the windows light up one by one, and a question mark appears.
- The path from your device to the internet glows in each step's colour. While a step is checked, an arc circles it
  and small lights travel along the wires, and a ring spreads out when its answer arrives.
- In right-to-left languages the small picture badge stays in its corner instead of covering the drawing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 01:49:41 +02:00
8 changed files with 1200 additions and 318 deletions

No files matched your search

+9 -2
View File
@@ -62,7 +62,7 @@ The Android release key: alias `meweb`, certificate SHA-256
|---|---| |---|---|
| `src/MeWeb.Shared` | `Endpoints.cs` (routes and hosts), wire contracts, `MeWebJsonContext`, generated `BuildInfo` | | `src/MeWeb.Shared` | `Endpoints.cs` (routes and hosts), wire contracts, `MeWebJsonContext`, generated `BuildInfo` |
| `src/MeWeb.Core` | the checks, no UI: `Net/` (address kinds, local network, TTL route, STUN, the probe's `Answerer`, DNS, speed, the device), `Router/` (UPnP IGD, NAT-PMP, PCP; `PortMapper` opens and removes mappings, `Leftovers` remembers them across a crash), `Mail/` (port 25, reverse name, blocklists through the user's resolver), `Knowledge/` (provider map and profiles), `History/` (checks, shared submissions), `Checks/` (`CheckRunner`, `Verdicts`, `Reach`, `Uses`, `ServerProbe`, `SharePayload`) | | `src/MeWeb.Core` | the checks, no UI: `Net/` (address kinds, local network, TTL route, STUN, the probe's `Answerer`, DNS, speed, the device), `Router/` (UPnP IGD, NAT-PMP, PCP; `PortMapper` opens and removes mappings, `Leftovers` remembers them across a crash), `Mail/` (port 25, reverse name, blocklists through the user's resolver), `Knowledge/` (provider map and profiles), `History/` (checks, shared submissions), `Checks/` (`CheckRunner`, `Verdicts`, `Reach`, `Uses`, `ServerProbe`, `SharePayload`) |
| `src/MeWeb.App` | Avalonia views and view models, `Services/Localizer.cs` (+ `{s:Tr Key}`), `Strings/<code>.json`, `Resources/Colors.axaml`; `Resources/Icons.axaml` (Lucide, 24 units, for cards and lists) and `Resources/Art.axaml` (the path's drawings, 48 units: `Art<Name>Base`, up to three `Beat`s that pulse in turn while the step is checked and take its verdict colour, and a `Spin` for the globe). The path is a vertical zig-zag of `PathNodeViewModel`s, and the same nodes carry the result cards (`Cards`, regrouped by `MainViewModel.Home`), so a step in the path and its group of cards are one object | | `src/MeWeb.App` | Avalonia views and view models, `Services/Localizer.cs` (+ `{s:Tr Key}`), `Strings/<code>.json`, `Resources/Colors.axaml`; `Resources/Icons.axaml` (Lucide, 24 units, for cards and lists) and `Resources/Art.axaml` (the path's drawings, 48 units: `Art<Name>Base`, up to three `Beat`s that pulse in turn while the step is checked and take its verdict colour, and a `Spin` for the globe; then the intro planet's still pieces as `DrawingImage`s with a fixed `Viewbox`: `ArtHouse`, `ArtBlock`, `ArtPine`, `ArtOak`, `ArtPhoto`, `ArtLetter`, `ArtServer`). The path is a vertical zig-zag of `PathNodeViewModel`s, and the same nodes carry the result cards (`Cards`, regrouped by `MainViewModel.Home`), so a step in the path and its group of cards are one object |
| `src/MeWeb.Desktop` | desktop head (`meweb` executable), Windows manifest | | `src/MeWeb.Desktop` | desktop head (`meweb` executable), Windows manifest |
| `src/MeWeb.Android` | Android head (`software.arasaka.meweb`), resources, manifest | | `src/MeWeb.Android` | Android head (`software.arasaka.meweb`), resources, manifest |
| `src/MeWeb.Server` | `meweb.arasaka.software`: `/api/info`, `/api/ip`, the download page `/` and `/privacy` (en, it), `/download/{platform}` from the latest Gitea release, the probe (`/api/probe/ticket`, `/api/probe/{id}`) and shared findings (`/api/share`, files under `/var/lib/meweb/shares`, swept after `KeepDays`) | | `src/MeWeb.Server` | `meweb.arasaka.software`: `/api/info`, `/api/ip`, the download page `/` and `/privacy` (en, it), `/download/{platform}` from the latest Gitea release, the probe (`/api/probe/ticket`, `/api/probe/{id}`) and shared findings (`/api/share`, files under `/var/lib/meweb/shares`, swept after `KeepDays`) |
@@ -205,7 +205,12 @@ The Android release key: alias `meweb`, certificate SHA-256
`Views/IntroScene` is one small planet in three `Step`s: 0, a phone far away sends a photo into the house and on to `Views/IntroScene` is one small planet in three `Step`s: 0, a phone far away sends a photo into the house and on to
the parents' tablet (heart); 1, a house with its own number and a small always-on computer in a callout lets a the parents' tablet (heart); 1, a house with its own number and a small always-on computer in a callout lets a
visitor in (green door, tick); 2, that house next to a block of flats with one number for all, where the visitor visitor in (green door, tick); 2, that house next to a block of flats with one number for all, where the visitor
stops at the main door (question mark). The third card asks whether the reader's home has an address of its own and stops at the main door (question mark). The visitor is a letter, because a letter needs an address; it and the photo
fly along the dotted routes with a comet trail (a gradient stroke whose ends are set each frame in
`RelativeUnit.Absolute`), and the world around them keeps moving (stars, town lights on the night side, clouds,
chimney smoke, swaying trees). The still drawings are `DrawingImage`s in `Art.axaml`; only what moves is a control,
and it moves through its `RenderTransform` (scale, rotate, translate), never `Canvas.SetLeft`, so a frame does not
lay the canvas out again. The third card asks whether the reader's home has an address of its own and
offers two answers: "Yes, let's find out" runs the check, "Not for me" shows `Goodbye` for two seconds and closes the offers two answers: "Yes, let's find out" runs the check, "Not for me" shows `Goodbye` for two seconds and closes the
app (`IPlatform.Quit`, the desktop lifetime's `Shutdown`). The six uses follow as chips, the QR codes wait folded app (`IPlatform.Quit`, the desktop lifetime's `Shutdown`). The six uses follow as chips, the QR codes wait folded
at the bottom. at the bottom.
@@ -216,6 +221,8 @@ The Android release key: alias `meweb`, certificate SHA-256
is the frame loop the scenes share; `Resting` parks a scene that is folded or off screen, so it starts again from the is the frame loop the scenes share; `Resting` parks a scene that is folded or off screen, so it starts again from the
beginning when it comes back. The screenshot tool calls `Hold()` to draw each at its `Poster` moment, because the beginning when it comes back. The screenshot tool calls `Hold()` to draw each at its `Poster` moment, because the
headless clock is real time. headless clock is real time.
- **A `Button` clips its content to its own bounds.** The path's node buttons (`Button.hop`) turn `ClipToBounds` off
on the button and its `ContentPresenter`, or the verdict aura and the running pulse are cut into a 90-pixel square.
- **Nothing that is being checked is left empty.** From the moment a check starts, every use has a card with its - **Nothing that is being checked is left empty.** From the moment a check starts, every use has a card with its
title, a "Checking" chip, two skeleton lines and a sweeping glint (`UseViewModel` with no finding), and every title, a "Checking" chip, two skeleton lines and a sweeping glint (`UseViewModel` with no finding), and every
running check card shows the same; the verdicts replace them as they arrive. While a check runs, the share card sits running check card shows the same; the verdicts replace them as they arrive. While a check runs, the share card sits
+1 -1
View File
@@ -1,6 +1,6 @@
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<Version>0.13.0</Version> <Version>0.14.0</Version>
<Product>“me-web?”</Product> <Product>“me-web?”</Product>
<Company>Arasaka di Hvozdikov Yevheniy</Company> <Company>Arasaka di Hvozdikov Yevheniy</Company>
<Copyright>© 2026 Arasaka di Hvozdikov Yevheniy</Copyright> <Copyright>© 2026 Arasaka di Hvozdikov Yevheniy</Copyright>
+261 -14
View File
@@ -33,24 +33,271 @@
<StreamGeometry x:Key="ArtGlobeBase">M 6 24 A 18 18 0 1 0 42 24 A 18 18 0 1 0 6 24 Z M 6 24 H 42 M 8.4 15 H 39.6 M 8.4 33 H 39.6</StreamGeometry> <StreamGeometry x:Key="ArtGlobeBase">M 6 24 A 18 18 0 1 0 42 24 A 18 18 0 1 0 6 24 Z M 6 24 H 42 M 8.4 15 H 39.6 M 8.4 33 H 39.6</StreamGeometry>
<StreamGeometry x:Key="ArtGlobeSpin">M 24 6 A 9 18 0 0 0 24 42 A 9 18 0 0 0 24 6 Z</StreamGeometry> <StreamGeometry x:Key="ArtGlobeSpin">M 24 6 A 9 18 0 0 0 24 42 A 9 18 0 0 0 24 6 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHouseFront">M 4 72 L 4 40 L 28 18 L 52 40 L 52 72 Z</StreamGeometry> <StreamGeometry x:Key="ArtHouseDoor">M 15 80 V 67 A 6 6 0 0 1 27 67 V 80 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHouseSide">M 52 40 L 76 30 L 76 62 L 52 72 Z</StreamGeometry> <StreamGeometry x:Key="ArtBlockGate">M 22.5 124 V 106.5 H 37.5 V 124 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHouseRoof">M 28 18 L 52 8 L 76 30 L 52 40 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHouseEdge">M 2 41.5 L 28 17 L 54 41.5</StreamGeometry>
<StreamGeometry x:Key="ArtHouseDoor">M 21 72 V 57 A 7 7 0 0 1 35 57 V 72 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHouseWindow">M 58 45 L 70 40 L 70 51 L 58 56 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHouseMullions">M 64 42.5 V 53.5 M 58 50.5 L 70 45.5</StreamGeometry>
<StreamGeometry x:Key="ArtBlockFront">M 4 110 V 14 H 52 V 110 Z</StreamGeometry>
<StreamGeometry x:Key="ArtBlockSide">M 52 14 L 68 7 V 103 L 52 110 Z</StreamGeometry>
<StreamGeometry x:Key="ArtBlockTop">M 4 14 L 20 7 H 68 L 52 14 Z</StreamGeometry>
<StreamGeometry x:Key="ArtBlockGate">M 22 110 V 100 A 6 6 0 0 1 34 100 V 110 Z</StreamGeometry>
<StreamGeometry x:Key="ArtDigitSeven">M 0 0 H 6 L 2 9</StreamGeometry> <StreamGeometry x:Key="ArtDigitSeven">M 0 0 H 6 L 2 9</StreamGeometry>
<StreamGeometry x:Key="ArtDigitFour">M 4.5 9 V 0 L 0 6 H 6.5</StreamGeometry> <StreamGeometry x:Key="ArtDigitFour">M 4.5 9 V 0 L 0 6 H 6.5</StreamGeometry>
<StreamGeometry x:Key="ArtQuestion">M 1 3.2 A 2.7 2.7 0 1 1 5.4 5.3 C 4.2 6.1 3.6 6.6 3.6 7.8 M 3.6 10.6 V 10.8</StreamGeometry> <StreamGeometry x:Key="ArtQuestion">M 1 3.2 A 2.7 2.7 0 1 1 5.4 5.3 C 4.2 6.1 3.6 6.6 3.6 7.8 M 3.6 10.6 V 10.8</StreamGeometry>
<StreamGeometry x:Key="ArtHeart">M 12 20.5 C 12 20.5 3 14.6 3 8.7 A 4.6 4.6 0 0 1 12 6.6 A 4.6 4.6 0 0 1 21 8.7 C 21 14.6 12 20.5 12 20.5 Z</StreamGeometry> <StreamGeometry x:Key="ArtHeart">M 12 20.5 C 12 20.5 3 14.6 3 8.7 A 4.6 4.6 0 0 1 12 6.6 A 4.6 4.6 0 0 1 21 8.7 C 21 14.6 12 20.5 12 20.5 Z</StreamGeometry>
<StreamGeometry x:Key="ArtHills">M 0 13 L 6 6 L 9.5 9.5 L 12.5 6.5 L 18 13 Z</StreamGeometry> <StreamGeometry x:Key="ArtSparkle">M 5 0 Q 5.7 4.3 10 5 Q 5.7 5.7 5 10 Q 4.3 5.7 0 5 Q 4.3 4.3 5 0 Z</StreamGeometry>
<StreamGeometry x:Key="ArtCloud">M 4 18 A 6 6 0 0 1 10 8.5 A 8.5 8.5 0 0 1 25 5 A 7 7 0 0 1 36 11 A 4.6 4.6 0 0 1 41 18 Z</StreamGeometry>
<StreamGeometry x:Key="ArtPhoneSheen">M 3.5 30 L 24.5 9 V 17 L 11.5 30 Z</StreamGeometry>
<StreamGeometry x:Key="ArtTabletSheen">M 5 25 L 26.5 3.5 H 36 L 11 29 Z</StreamGeometry>
<StreamGeometry x:Key="ArtOrbit">M 32 4 A 28 28 0 0 1 59.6 36.9</StreamGeometry>
<DrawingImage x:Key="ArtHouse" Viewbox="0,0,86,84">
<DrawingGroup>
<GeometryDrawing Geometry="M 8 80 V 44 L 31 21 L 54 44 V 80 Z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="30%,0%" EndPoint="60%,100%">
<GradientStop Offset="0" Color="{StaticResource WallLit}" />
<GradientStop Offset="1" Color="{StaticResource WallShade}" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Geometry="M 54 44 L 78 34 V 70 L 54 80 Z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Offset="0" Color="{StaticResource SideLit}" />
<GradientStop Offset="1" Color="{StaticResource SideShade}" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource EaveBrush}" Geometry="M 54 44 L 78 34 V 39 L 54 49 Z" />
<GeometryDrawing Brush="{StaticResource SideShadeBrush}" Geometry="M 8 80 V 76.5 H 54 V 80 Z M 54 80 V 76.5 L 78 66.5 V 70 Z" />
<GeometryDrawing Geometry="M 8 79 V 44 L 31 21">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource TrimSoftBrush}" Thickness="1.1" LineCap="Round" LineJoin="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource SideShadeBrush}" Geometry="M 13.5 80 V 67 A 7.5 7.5 0 0 1 28.5 67 V 80 Z" />
<GeometryDrawing Brush="{StaticResource DoorBrush}" Geometry="M 15 80 V 67 A 6 6 0 0 1 27 67 V 80 Z" />
<GeometryDrawing Brush="{StaticResource WindowCoreBrush}" Geometry="M 17.2 66.6 A 3.8 3.8 0 0 1 24.8 66.6 Z" />
<GeometryDrawing Brush="{StaticResource TrimBrush}" Geometry="M 23.4 74 A 0.9 0.9 0 1 0 25.2 74 A 0.9 0.9 0 1 0 23.4 74 Z" />
<GeometryDrawing Brush="{StaticResource WallLitBrush}" Geometry="M 12 78.6 H 30 V 80.6 H 12 Z" />
<GeometryDrawing Brush="{StaticResource SideShadeBrush}" Geometry="M 35 53 H 49 V 66 H 35 Z" />
<GeometryDrawing Geometry="M 36 54 H 48 V 65 H 36 Z">
<GeometryDrawing.Brush>
<RadialGradientBrush GradientOrigin="35%,30%" Center="35%,30%" RadiusX="90%" RadiusY="90%">
<GradientStop Offset="0" Color="{StaticResource WindowCore}" />
<GradientStop Offset="1" Color="{StaticResource Caution}" />
</RadialGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Geometry="M 42 54 V 65 M 36 59.5 H 48">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource SideShadeBrush}" Thickness="1.1" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource TrimBrush}" Geometry="M 34.4 65.6 H 49.6 V 67.2 H 34.4 Z" />
<GeometryDrawing Brush="{StaticResource DeviceShadeBrush}" Geometry="M 59 50.9 L 73 45.1 V 59.1 L 59 64.9 Z" />
<GeometryDrawing Geometry="M 60 51.5 L 72 46.5 V 58.5 L 60 63.5 Z">
<GeometryDrawing.Brush>
<RadialGradientBrush GradientOrigin="40%,45%" Center="40%,45%" RadiusX="80%" RadiusY="80%">
<GradientStop Offset="0" Color="{StaticResource WindowCore}" />
<GradientStop Offset="1" Color="{StaticResource Caution}" />
</RadialGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Geometry="M 66 49 V 61 M 60 57.5 L 72 52.5">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource DeviceShadeBrush}" Thickness="1.1" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource SideShadeBrush}" Geometry="M 25.5 34 A 5.5 5.5 0 1 0 36.5 34 A 5.5 5.5 0 1 0 25.5 34 Z" />
<GeometryDrawing Geometry="M 26.6 34 A 4.4 4.4 0 1 0 35.4 34 A 4.4 4.4 0 1 0 26.6 34 Z">
<GeometryDrawing.Brush>
<RadialGradientBrush GradientOrigin="35%,35%" Center="35%,35%" RadiusX="80%" RadiusY="80%">
<GradientStop Offset="0" Color="{StaticResource WindowCore}" />
<GradientStop Offset="1" Color="{StaticResource Caution}" />
</RadialGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Geometry="M 31 29.6 V 38.4 M 26.6 34 H 35.4">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource SideShadeBrush}" Thickness="1" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 31 19 L 55 9 L 82.5 36.5 L 58.5 46.5 Z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="40%,0%" EndPoint="60%,100%">
<GradientStop Offset="0" Color="{StaticResource BrandRedLight}" />
<GradientStop Offset="0.55" Color="{StaticResource BrandRed}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedDark}" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Geometry="M 37.9 25.9 L 61.9 15.9 M 44.8 32.8 L 68.8 22.8 M 51.6 39.6 L 75.6 29.6">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BrandRedDarkBrush}" Thickness="0.9" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 58.5 46.5 L 82.5 36.5">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BrandRedDarkBrush}" Thickness="2.4" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 4.5 45.5 L 31 19 L 58.5 46.5">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BrandRedDarkBrush}" Thickness="3.8" LineCap="Round" LineJoin="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 4.8 44 L 31 17.6 L 57.6 44.2">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BrandRedLightBrush}" Thickness="0.9" LineCap="Round" LineJoin="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 31 18.6 L 55 8.6">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BrandRedLightBrush}" Thickness="1.6" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource WallShadeBrush}" Geometry="M 50 5 H 56 V 25.3 L 50 19.3 Z" />
<GeometryDrawing Brush="{StaticResource SideShadeBrush}" Geometry="M 56 5 L 59.8 3.4 V 23.7 L 56 25.3 Z" />
<GeometryDrawing Brush="{StaticResource TrimBrush}" Geometry="M 49 3 L 53 1.3 H 61 L 57 3 Z" />
<GeometryDrawing Brush="{StaticResource WallLitBrush}" Geometry="M 49 3 H 57 V 5.6 H 49 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtBlock" Viewbox="0,-10,76,136">
<DrawingGroup>
<GeometryDrawing Geometry="M 20 13 V -6 M 17 -2 H 23 M 18 2.5 H 22">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource TrimSoftBrush}" Thickness="1" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 6 124 V 16 H 54 V 124 Z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="30%,0%" EndPoint="70%,100%">
<GradientStop Offset="0" Color="{StaticResource BlockLit}" />
<GradientStop Offset="1" Color="{StaticResource BlockShade}" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource BlockSideBrush}" Geometry="M 54 16 L 72 8 V 116 L 54 124 Z" />
<GeometryDrawing Brush="{StaticResource BlockTopBrush}" Geometry="M 6 16 L 24 8 H 72 L 54 16 Z" />
<GeometryDrawing Brush="{StaticResource SideLitBrush}" Geometry="M 41 12.5 V 4 A 5 1.6 0 0 0 51 4 V 12.5 A 5 1.6 0 0 1 41 12.5 Z" />
<GeometryDrawing Brush="{StaticResource WallLitBrush}" Geometry="M 41 4 A 5 1.6 0 0 1 51 4 A 5 1.6 0 0 1 41 4 Z" />
<GeometryDrawing Geometry="M 6 16 H 54 L 72 8">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource TrimSoftBrush}" Thickness="1.6" LineCap="Round" LineJoin="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 6 38.5 H 54 L 72 30.5 M 6 55.5 H 54 L 72 47.5 M 6 72.5 H 54 L 72 64.5 M 6 89.5 H 54 L 72 81.5">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BlockShadeBrush}" Thickness="1" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource WindowDarkBrush}" Geometry="M 57.6 22.4 L 61.56 20.64 V 31.64 L 57.6 33.4 Z M 57.6 39.4 L 61.56 37.64 V 48.64 L 57.6 50.4 Z M 64.44 36.36 L 68.4 34.6 V 45.6 L 64.44 47.36 Z M 57.6 56.4 L 61.56 54.64 V 65.64 L 57.6 67.4 Z M 64.44 53.36 L 68.4 51.6 V 62.6 L 64.44 64.36 Z M 64.44 70.36 L 68.4 68.6 V 79.6 L 64.44 81.36 Z" />
<GeometryDrawing Brush="{StaticResource CautionBrush}" Geometry="M 64.44 19.36 L 68.4 17.6 V 28.6 L 64.44 30.36 Z M 57.6 73.4 L 61.56 71.64 V 82.64 L 57.6 84.4 Z" />
<GeometryDrawing Brush="{StaticResource BlockSideBrush}" Geometry="M 6 124 V 120.5 H 54 V 124 Z M 54 124 V 120.5 L 72 112.5 V 116 Z" />
<GeometryDrawing Geometry="M 6 123 V 16">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource TrimSoftBrush}" Thickness="1.1" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource BlockShadeBrush}" Geometry="M 21 124 V 105 H 39 V 124 Z" />
<GeometryDrawing Geometry="M 22.5 124 V 106.5 H 37.5 V 124 Z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource WindowCore}" />
<GradientStop Offset="1" Color="{StaticResource Caution}" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Geometry="M 30 106.5 V 124">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BlockShadeBrush}" Thickness="1.3" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource WallLitBrush}" Geometry="M 17 101 L 20 99.6 H 46 L 43 101 Z" />
<GeometryDrawing Brush="{StaticResource TrimBrush}" Geometry="M 17 101 H 43 V 104 H 17 Z" />
<GeometryDrawing Brush="{StaticResource BlockTopBrush}" Geometry="M 43 101 L 46 99.6 V 102.6 L 43 104 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtPine" Viewbox="0,0,20,36">
<DrawingGroup>
<GeometryDrawing Brush="{StaticResource BarkBrush}" Geometry="M 9 26 H 11 V 36 H 9 Z" />
<GeometryDrawing Brush="{StaticResource LeafBrush}" Geometry="M 10 13 L 0 28 H 10 Z" />
<GeometryDrawing Brush="{StaticResource LeafShadeBrush}" Geometry="M 10 13 L 20 28 H 10 Z" />
<GeometryDrawing Brush="{StaticResource LeafBrush}" Geometry="M 10 6 L 1.5 21 H 10 Z" />
<GeometryDrawing Brush="{StaticResource LeafShadeBrush}" Geometry="M 10 6 L 18.5 21 H 10 Z" />
<GeometryDrawing Brush="{StaticResource LeafBrush}" Geometry="M 10 0 L 3.5 13 H 10 Z" />
<GeometryDrawing Brush="{StaticResource LeafShadeBrush}" Geometry="M 10 0 L 16.5 13 H 10 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtOak" Viewbox="0,0,26,36">
<DrawingGroup>
<GeometryDrawing Brush="{StaticResource BarkBrush}" Geometry="M 11.6 36 L 12.2 23 H 13.8 L 14.4 36 Z" />
<GeometryDrawing Geometry="M 13 30 L 17.5 25.5">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource BarkBrush}" Thickness="1.3" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource LeafShadeBrush}" Geometry="F1 M 1 20 A 8.5 8.5 0 1 1 18 20 A 8.5 8.5 0 1 1 1 20 Z M 9 15 A 8.5 8.5 0 1 1 26 15 A 8.5 8.5 0 1 1 9 15 Z M 4 10.5 A 7.5 7.5 0 1 1 19 10.5 A 7.5 7.5 0 1 1 4 10.5 Z" />
<GeometryDrawing Brush="{StaticResource LeafBrush}" Geometry="F1 M 2.4 18 A 7 7 0 1 1 16.4 18 A 7 7 0 1 1 2.4 18 Z M 5.4 10 A 6.2 6.2 0 1 1 17.8 10 A 6.2 6.2 0 1 1 5.4 10 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtHamlet" Viewbox="0,0,10,10">
<DrawingGroup>
<GeometryDrawing Brush="{StaticResource PlanetLitBrush}" Geometry="M 0.5 10 V 4.6 L 5 0.6 L 9.5 4.6 V 10 Z" />
<GeometryDrawing Brush="{StaticResource CautionBrush}" Geometry="M 3.8 5.6 H 6.2 V 8 H 3.8 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtPhoto" Viewbox="0,0,24,18">
<DrawingGroup>
<GeometryDrawing Geometry="M 0 0 H 24 V 18 H 0 Z">
<GeometryDrawing.Brush>
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource PhotoSky}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedLight}" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource WindowCoreBrush}" Geometry="M 13.2 5.6 A 2.9 2.9 0 1 0 19 5.6 A 2.9 2.9 0 1 0 13.2 5.6 Z" />
<GeometryDrawing Brush="{StaticResource BrandRedBrush}" Geometry="M 0 18 V 11 Q 5 6 10 10 Q 14 13 18 9 Q 21 7 24 9.5 V 18 Z" />
<GeometryDrawing Brush="{StaticResource BrandRedDarkBrush}" Geometry="M 0 18 V 14.5 Q 7 10.5 13 14 Q 18 16.5 24 13 V 18 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtLetter" Viewbox="0,0,22,15">
<DrawingGroup>
<GeometryDrawing Brush="{StaticResource TextStrongBrush}" Geometry="M 1.6 0.5 H 20.4 A 1.6 1.6 0 0 1 22 2.1 V 12.9 A 1.6 1.6 0 0 1 20.4 14.5 H 1.6 A 1.6 1.6 0 0 1 0 12.9 V 2.1 A 1.6 1.6 0 0 1 1.6 0.5 Z" />
<GeometryDrawing Geometry="M 1 13.8 L 8.6 7.6 M 21 13.8 L 13.4 7.6">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource TrimBrush}" Thickness="0.9" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource TrimBrush}" Geometry="M 0.9 1.2 L 11 9.2 L 21.1 1.2 Z" />
<GeometryDrawing Brush="{StaticResource BrandRedBrush}" Geometry="M 8.4 9 A 2.6 2.6 0 1 0 13.6 9 A 2.6 2.6 0 1 0 8.4 9 Z" />
<GeometryDrawing Brush="{StaticResource BrandRedLightBrush}" Geometry="M 9.6 8.4 A 0.9 0.9 0 1 0 11.4 8.4 A 0.9 0.9 0 1 0 9.6 8.4 Z" />
</DrawingGroup>
</DrawingImage>
<DrawingImage x:Key="ArtServer" Viewbox="0,0,40,30">
<DrawingGroup>
<GeometryDrawing Brush="{StaticResource DeviceEdgeBrush}" Geometry="M 6 11 L 20 5 L 34 11 L 20 17 Z" />
<GeometryDrawing Brush="{StaticResource DeviceLitBrush}" Geometry="M 6 11 L 20 17 V 26 L 6 20 Z" />
<GeometryDrawing Brush="{StaticResource DeviceShadeBrush}" Geometry="M 20 17 L 34 11 V 20 L 20 26 Z" />
<GeometryDrawing Geometry="M 23 20.2 L 31 16.8 M 23 23 L 31 19.6">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource DeviceLitBrush}" Thickness="1" LineCap="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M 6.2 11.2 L 20 17 L 33.8 11.2">
<GeometryDrawing.Pen>
<Pen Brush="{StaticResource TrimBrush}" Thickness="0.8" LineCap="Round" LineJoin="Round" />
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Brush="{StaticResource GoodBrush}" Geometry="M 8.6 15.6 A 1.2 1.2 0 1 0 11 15.6 A 1.2 1.2 0 1 0 8.6 15.6 Z" />
</DrawingGroup>
</DrawingImage>
<StreamGeometry x:Key="ArtNodeOrbit">M 45 -1 A 46 46 0 0 1 84.84 68 M 45 91 A 46 46 0 0 1 5.16 22</StreamGeometry>
<StreamGeometry x:Key="WireToEnd">M 0 0 C 0 0.62 1 0.38 1 1</StreamGeometry> <StreamGeometry x:Key="WireToEnd">M 0 0 C 0 0.62 1 0.38 1 1</StreamGeometry>
<StreamGeometry x:Key="WireToStart">M 1 0 C 1 0.62 0 0.38 0 1</StreamGeometry> <StreamGeometry x:Key="WireToStart">M 1 0 C 1 0.62 0 0.38 0 1</StreamGeometry>
+71
View File
@@ -25,6 +25,56 @@
<Color x:Key="Glint">#1FF0EAEF</Color> <Color x:Key="Glint">#1FF0EAEF</Color>
<Color x:Key="GlintClear">#00F0EAEF</Color> <Color x:Key="GlintClear">#00F0EAEF</Color>
<Color x:Key="SkyHigh">#0D0911</Color>
<Color x:Key="SkyLow">#2E1834</Color>
<Color x:Key="Dusk">#5CC2456F</Color>
<Color x:Key="DuskClear">#00C2456F</Color>
<Color x:Key="Atmosphere">#70EC7A82</Color>
<Color x:Key="AtmosphereClear">#00EC7A82</Color>
<Color x:Key="PlanetLit">#48324F</Color>
<Color x:Key="PlanetShade">#150E18</Color>
<Color x:Key="TownGlow">#4DF2C14E</Color>
<Color x:Key="Contact">#B30A070D</Color>
<Color x:Key="ContactClear">#000A070D</Color>
<Color x:Key="Vignette">#A60A070D</Color>
<Color x:Key="WallLit">#8E7695</Color>
<Color x:Key="WallShade">#5F4B67</Color>
<Color x:Key="SideLit">#4D3C56</Color>
<Color x:Key="SideShade">#352840</Color>
<Color x:Key="Trim">#D4C3D6</Color>
<Color x:Key="TrimSoft">#73D4C3D6</Color>
<Color x:Key="Eave">#661B141C</Color>
<Color x:Key="Door">#33202F</Color>
<Color x:Key="WindowCore">#FFE9AE</Color>
<Color x:Key="WindowDark">#231A29</Color>
<Color x:Key="WindowCool">#8DB6EE</Color>
<Color x:Key="BlockLit">#5C5779</Color>
<Color x:Key="BlockShade">#3F3A58</Color>
<Color x:Key="BlockSide">#2C283E</Color>
<Color x:Key="BlockTop">#746D93</Color>
<Color x:Key="Leaf">#3E8670</Color>
<Color x:Key="LeafShade">#1F4C44</Color>
<Color x:Key="Bark">#4C3137</Color>
<Color x:Key="DeviceLit">#4F4459</Color>
<Color x:Key="DeviceShade">#211B26</Color>
<Color x:Key="DeviceEdge">#A898AD</Color>
<Color x:Key="ScreenHigh">#41365A</Color>
<Color x:Key="ScreenLow">#16111C</Color>
<Color x:Key="Sheen">#26F0EAEF</Color>
<Color x:Key="PhotoSky">#F7B27A</Color>
<Color x:Key="Cloud">#26362848</Color>
<Color x:Key="CloudLit">#6B8A4470</Color>
<Color x:Key="Smoke">#80B3A6B2</Color>
<Color x:Key="SmokeClear">#00B3A6B2</Color>
<Color x:Key="Beam">#38F0EAEF</Color>
<Color x:Key="BeamClear">#0AF0EAEF</Color>
<Color x:Key="GoodLight">#B4F0CF</Color>
<Color x:Key="GoodGlow">#996FCF97</Color>
<Color x:Key="GoodClear">#006FCF97</Color>
<Color x:Key="CautionLight">#FBE3A1</Color>
<Color x:Key="BadGlow">#88F06B79</Color>
<Color x:Key="BadClear">#00F06B79</Color>
<SolidColorBrush x:Key="BrandRedBrush" Color="{StaticResource BrandRed}" /> <SolidColorBrush x:Key="BrandRedBrush" Color="{StaticResource BrandRed}" />
<SolidColorBrush x:Key="BrandRedDarkBrush" Color="{StaticResource BrandRedDark}" /> <SolidColorBrush x:Key="BrandRedDarkBrush" Color="{StaticResource BrandRedDark}" />
<SolidColorBrush x:Key="BrandRedLightBrush" Color="{StaticResource BrandRedLight}" /> <SolidColorBrush x:Key="BrandRedLightBrush" Color="{StaticResource BrandRedLight}" />
@@ -42,4 +92,25 @@
<SolidColorBrush x:Key="BadTintBrush" Color="{StaticResource BadTint}" /> <SolidColorBrush x:Key="BadTintBrush" Color="{StaticResource BadTint}" />
<SolidColorBrush x:Key="NeutralTintBrush" Color="{StaticResource NeutralTint}" /> <SolidColorBrush x:Key="NeutralTintBrush" Color="{StaticResource NeutralTint}" />
<SolidColorBrush x:Key="ScrimBrush" Color="{StaticResource Scrim}" /> <SolidColorBrush x:Key="ScrimBrush" Color="{StaticResource Scrim}" />
<SolidColorBrush x:Key="TrimBrush" Color="{StaticResource Trim}" />
<SolidColorBrush x:Key="TrimSoftBrush" Color="{StaticResource TrimSoft}" />
<SolidColorBrush x:Key="EaveBrush" Color="{StaticResource Eave}" />
<SolidColorBrush x:Key="DoorBrush" Color="{StaticResource Door}" />
<SolidColorBrush x:Key="WallLitBrush" Color="{StaticResource WallLit}" />
<SolidColorBrush x:Key="WallShadeBrush" Color="{StaticResource WallShade}" />
<SolidColorBrush x:Key="SideLitBrush" Color="{StaticResource SideLit}" />
<SolidColorBrush x:Key="SideShadeBrush" Color="{StaticResource SideShade}" />
<SolidColorBrush x:Key="WindowDarkBrush" Color="{StaticResource WindowDark}" />
<SolidColorBrush x:Key="WindowCoreBrush" Color="{StaticResource WindowCore}" />
<SolidColorBrush x:Key="BlockShadeBrush" Color="{StaticResource BlockShade}" />
<SolidColorBrush x:Key="BlockSideBrush" Color="{StaticResource BlockSide}" />
<SolidColorBrush x:Key="BlockTopBrush" Color="{StaticResource BlockTop}" />
<SolidColorBrush x:Key="LeafBrush" Color="{StaticResource Leaf}" />
<SolidColorBrush x:Key="LeafShadeBrush" Color="{StaticResource LeafShade}" />
<SolidColorBrush x:Key="BarkBrush" Color="{StaticResource Bark}" />
<SolidColorBrush x:Key="DeviceLitBrush" Color="{StaticResource DeviceLit}" />
<SolidColorBrush x:Key="DeviceShadeBrush" Color="{StaticResource DeviceShade}" />
<SolidColorBrush x:Key="DeviceEdgeBrush" Color="{StaticResource DeviceEdge}" />
<SolidColorBrush x:Key="PlanetLitBrush" Color="{StaticResource PlanetLit}" />
<SolidColorBrush x:Key="SheenBrush" Color="{StaticResource Sheen}" />
</ResourceDictionary> </ResourceDictionary>
+412 -110
View File
@@ -124,6 +124,11 @@
<Setter Property="Fill" Value="{StaticResource SurfaceRaisedBrush}" /> <Setter Property="Fill" Value="{StaticResource SurfaceRaisedBrush}" />
<Setter Property="Stroke" Value="{StaticResource LineBrush}" /> <Setter Property="Stroke" Value="{StaticResource LineBrush}" />
<Setter Property="StrokeThickness" Value="3" /> <Setter Property="StrokeThickness" Value="3" />
<Setter Property="Transitions">
<Transitions>
<BrushTransition Property="Stroke" Duration="0:0:0.5" />
</Transitions>
</Setter>
</Style> </Style>
<Style Selector="Ellipse.disc.good"> <Style Selector="Ellipse.disc.good">
<Setter Property="Stroke" Value="{StaticResource GoodBrush}" /> <Setter Property="Stroke" Value="{StaticResource GoodBrush}" />
@@ -208,6 +213,9 @@
<Setter Property="Cursor" Value="Hand" /> <Setter Property="Cursor" Value="Hand" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
</Style> </Style>
<Style Selector="Button.hop, Button.hop /template/ ContentPresenter">
<Setter Property="ClipToBounds" Value="False" />
</Style>
<Style Selector="Button.hop:pointerover /template/ ContentPresenter, Button.hop:pressed /template/ ContentPresenter"> <Style Selector="Button.hop:pointerover /template/ ContentPresenter, Button.hop:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="Transparent" /> <Setter Property="Background" Value="Transparent" />
</Style> </Style>
@@ -293,6 +301,127 @@
</Animation> </Animation>
</Style.Animations> </Style.Animations>
</Style> </Style>
<Style Selector="Ellipse.aura">
<Setter Property="Opacity" Value="0" />
<Setter Property="IsHitTestVisible" Value="False" />
<Setter Property="Transitions">
<Transitions>
<DoubleTransition Property="Opacity" Duration="0:0:0.6" />
</Transitions>
</Setter>
</Style>
<Style Selector="Ellipse.aura.good">
<Setter Property="Opacity" Value="0.55" />
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0.5" Color="{StaticResource GoodGlow}" />
<GradientStop Offset="1" Color="{StaticResource GoodClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.aura.caution">
<Setter Property="Opacity" Value="0.55" />
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0.5" Color="{StaticResource CautionGlow}" />
<GradientStop Offset="1" Color="{StaticResource CautionClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.aura.bad">
<Setter Property="Opacity" Value="0.55" />
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0.5" Color="{StaticResource BadGlow}" />
<GradientStop Offset="1" Color="{StaticResource BadClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.gloss">
<Setter Property="IsHitTestVisible" Value="False" />
<Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource Glint}" />
<GradientStop Offset="0.55" Color="{StaticResource GlintClear}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Path.spinner">
<Setter Property="StrokeThickness" Value="3" />
<Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="Stroke">
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Offset="0" Color="{StaticResource BrandRedLight}" />
<GradientStop Offset="0.5" Color="{StaticResource BrandRedClear}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedLight}" />
</LinearGradientBrush>
</Setter>
<Style.Animations>
<Animation Duration="0:0:1.6" IterationCount="Infinite">
<KeyFrame Cue="0%">
<Setter Property="RotateTransform.Angle" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="RotateTransform.Angle" Value="360" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="Ellipse.burst">
<Setter Property="Opacity" Value="0" />
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
<Style Selector="Ellipse.burst.good">
<Setter Property="Stroke" Value="{StaticResource GoodBrush}" />
</Style>
<Style Selector="Ellipse.burst.caution">
<Setter Property="Stroke" Value="{StaticResource CautionBrush}" />
</Style>
<Style Selector="Ellipse.burst.bad">
<Setter Property="Stroke" Value="{StaticResource BadBrush}" />
</Style>
<Style Selector="Ellipse.burst.good, Ellipse.burst.caution, Ellipse.burst.bad">
<Style.Animations>
<Animation Duration="0:0:1.1" Easing="CubicEaseOut" FillMode="Forward">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0" />
<Setter Property="ScaleTransform.ScaleX" Value="1" />
<Setter Property="ScaleTransform.ScaleY" Value="1" />
</KeyFrame>
<KeyFrame Cue="12%">
<Setter Property="Opacity" Value="0.9" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="0" />
<Setter Property="ScaleTransform.ScaleX" Value="1.5" />
<Setter Property="ScaleTransform.ScaleY" Value="1.5" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="Path.packets">
<Setter Property="Stretch" Value="Fill" />
<Setter Property="Opacity" Value="0" />
<Setter Property="IsHitTestVisible" Value="False" />
<Setter Property="Stroke" Value="{StaticResource WindowCoreBrush}" />
<Setter Property="StrokeThickness" Value="5" />
<Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="StrokeDashArray" Value="0.01,9" />
</Style>
<Style Selector="Path.packets.flowing">
<Setter Property="Opacity" Value="1" />
<Style.Animations>
<Animation Duration="0:0:1.1" IterationCount="Infinite">
<KeyFrame Cue="0%">
<Setter Property="StrokeDashOffset" Value="0" />
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="StrokeDashOffset" Value="-9.01" />
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
<Style Selector="Ellipse.disc.thin"> <Style Selector="Ellipse.disc.thin">
<Setter Property="StrokeThickness" Value="2" /> <Setter Property="StrokeThickness" Value="2" />
</Style> </Style>
@@ -478,14 +607,6 @@
<Setter Property="Width" Value="170" /> <Setter Property="Width" Value="170" />
<Setter Property="Height" Value="170" /> <Setter Property="Height" Value="170" />
</Style> </Style>
<Style Selector="Ellipse.glow">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource BrandRedGlow}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Border.statusChip"> <Style Selector="Border.statusChip">
<Setter Property="Background" Value="{StaticResource SurfaceRaisedBrush}" /> <Setter Property="Background" Value="{StaticResource SurfaceRaisedBrush}" />
<Setter Property="CornerRadius" Value="14" /> <Setter Property="CornerRadius" Value="14" />
@@ -578,81 +699,137 @@
<Style Selector="TextBlock.lead.strong"> <Style Selector="TextBlock.lead.strong">
<Setter Property="Foreground" Value="{StaticResource TextStrongBrush}" /> <Setter Property="Foreground" Value="{StaticResource TextStrongBrush}" />
</Style> </Style>
<Style Selector="Ellipse.star"> <Style Selector="Rectangle.sky">
<Setter Property="Fill" Value="{StaticResource TextStrongBrush}" />
</Style>
<Style Selector="Ellipse.planet">
<Setter Property="Fill"> <Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,22%"> <LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource SurfaceRaised}" /> <GradientStop Offset="0" Color="{StaticResource SkyHigh}" />
<GradientStop Offset="1" Color="{StaticResource Ground}" /> <GradientStop Offset="0.72" Color="{StaticResource SkyLow}" />
</LinearGradientBrush> </LinearGradientBrush>
</Setter> </Setter>
</Style> </Style>
<Style Selector="Ellipse.meridian"> <Style Selector="Ellipse.dusk">
<Setter Property="Stroke" Value="{StaticResource LineBrush}" /> <Setter Property="Fill">
<Setter Property="StrokeThickness" Value="1" /> <RadialGradientBrush>
<Setter Property="Opacity" Value="0.7" /> <GradientStop Offset="0" Color="{StaticResource Dusk}" />
<GradientStop Offset="1" Color="{StaticResource DuskClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.star, Path.sparkle">
<Setter Property="Fill" Value="{StaticResource TextStrongBrush}" />
</Style>
<Style Selector="Path.sparkle">
<Setter Property="Data" Value="{StaticResource ArtSparkle}" />
<Setter Property="Width" Value="10" />
<Setter Property="Height" Value="10" />
</Style>
<Style Selector="Border.meteor">
<Setter Property="CornerRadius" Value="1" />
<Setter Property="Background">
<LinearGradientBrush StartPoint="0%,50%" EndPoint="100%,50%">
<GradientStop Offset="0" Color="{StaticResource GlintClear}" />
<GradientStop Offset="1" Color="{StaticResource TextStrong}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Path.cloud">
<Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource Cloud}" />
<GradientStop Offset="1" Color="{StaticResource CloudLit}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.halo">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource BrandRedGlow}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.atmosphere">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0.86" Color="{StaticResource AtmosphereClear}" />
<GradientStop Offset="0.896" Color="{StaticResource Atmosphere}" />
<GradientStop Offset="1" Color="{StaticResource AtmosphereClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.planet">
<Setter Property="Fill">
<RadialGradientBrush Center="46%,0%" GradientOrigin="46%,0%" RadiusX="50%" RadiusY="50%">
<GradientStop Offset="0" Color="{StaticResource PlanetLit}" />
<GradientStop Offset="0.62" Color="{StaticResource PlanetShade}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.town">
<Setter Property="Fill" Value="{StaticResource WindowCoreBrush}" />
</Style>
<Style Selector="Ellipse.townGlow">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource TownGlow}" />
<GradientStop Offset="1" Color="{StaticResource CautionClear}" />
</RadialGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Ellipse.rim"> <Style Selector="Ellipse.rim">
<Setter Property="Stroke" Value="{StaticResource BrandRedLightBrush}" /> <Setter Property="StrokeThickness" Value="1.4" />
<Setter Property="StrokeThickness" Value="1.5" /> <Setter Property="Stroke">
<Setter Property="Opacity" Value="0.45" /> <LinearGradientBrush StartPoint="0%,50%" EndPoint="100%,50%">
<GradientStop Offset="0.12" Color="{StaticResource BrandRedClear}" />
<GradientStop Offset="0.5" Color="{StaticResource BrandRedLight}" />
<GradientStop Offset="0.88" Color="{StaticResource BrandRedClear}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.contact">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource Contact}" />
<GradientStop Offset="1" Color="{StaticResource ContactClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Rectangle.vignette">
<Setter Property="Fill">
<RadialGradientBrush Center="50%,42%" GradientOrigin="50%,42%" RadiusX="72%" RadiusY="85%">
<GradientStop Offset="0.55" Color="{StaticResource ContactClear}" />
<GradientStop Offset="1" Color="{StaticResource Vignette}" />
</RadialGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Path.trail"> <Style Selector="Path.trail">
<Setter Property="Stroke" Value="{StaticResource BrandRedLightBrush}" /> <Setter Property="Stroke" Value="{StaticResource BrandRedLightBrush}" />
<Setter Property="StrokeThickness" Value="1.5" /> <Setter Property="StrokeThickness" Value="1.6" />
<Setter Property="StrokeDashArray" Value="2,4" /> <Setter Property="StrokeDashArray" Value="0.1,3.2" />
<Setter Property="StrokeLineCap" Value="Round" /> <Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="Opacity" Value="0.55" /> <Setter Property="Opacity" Value="0.6" />
</Style> </Style>
<Style Selector="Ellipse.shadow"> <Style Selector="Path.comet">
<Setter Property="Fill" Value="{StaticResource GroundBrush}" /> <Setter Property="StrokeThickness" Value="2.6" />
<Setter Property="Opacity" Value="0.7" />
</Style>
<Style Selector="Path.wall">
<Setter Property="Fill" Value="{StaticResource SurfaceRaisedBrush}" />
<Setter Property="Stroke" Value="{StaticResource LineBrush}" />
<Setter Property="StrokeThickness" Value="1.2" />
<Setter Property="StrokeJoin" Value="Round" />
</Style>
<Style Selector="Path.wall.side">
<Setter Property="Fill" Value="{StaticResource SurfaceBrush}" />
</Style>
<Style Selector="Path.roof">
<Setter Property="Fill" Value="{StaticResource BrandRedBrush}" />
<Setter Property="Stroke" Value="{StaticResource BrandRedDarkBrush}" />
<Setter Property="StrokeThickness" Value="1" />
<Setter Property="StrokeJoin" Value="Round" />
</Style>
<Style Selector="Path.roofEdge">
<Setter Property="Stroke" Value="{StaticResource BrandRedBrush}" />
<Setter Property="StrokeThickness" Value="3" />
<Setter Property="StrokeLineCap" Value="Round" /> <Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="StrokeJoin" Value="Round" />
</Style> </Style>
<Style Selector="Path.flatRoof"> <Style Selector="Ellipse.spark">
<Setter Property="Fill" Value="{StaticResource LineBrush}" /> <Setter Property="Fill" Value="{StaticResource WindowCoreBrush}" />
<Setter Property="Stroke" Value="{StaticResource LineBrush}" />
<Setter Property="StrokeThickness" Value="1" />
</Style> </Style>
<Style Selector="Path.door"> <Style Selector="Ellipse.ripple">
<Setter Property="Fill" Value="{StaticResource GroundBrush}" /> <Setter Property="Stroke" Value="{StaticResource TextStrongBrush}" />
<Setter Property="Stroke" Value="{StaticResource LineBrush}" /> <Setter Property="StrokeThickness" Value="1.4" />
<Setter Property="StrokeThickness" Value="1" />
</Style> </Style>
<Style Selector="Path.doorLight"> <Style Selector="Ellipse.smoke">
<Setter Property="Fill" Value="{StaticResource GoodBrush}" /> <Setter Property="Fill">
<Setter Property="Opacity" Value="0" /> <RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource Smoke}" />
<GradientStop Offset="1" Color="{StaticResource SmokeClear}" />
</RadialGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Path.window, Ellipse.window, Rectangle.flat"> <Style Selector="Ellipse.windowGlow">
<Setter Property="Fill" Value="{StaticResource CautionBrush}" /> <Setter Property="IsHitTestVisible" Value="False" />
</Style>
<Style Selector="Path.mullion">
<Setter Property="Stroke" Value="{StaticResource SurfaceBrush}" />
<Setter Property="StrokeThickness" Value="1" />
</Style>
<Style Selector="Ellipse.warmGlow">
<Setter Property="Fill"> <Setter Property="Fill">
<RadialGradientBrush> <RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource CautionGlow}" /> <GradientStop Offset="0" Color="{StaticResource CautionGlow}" />
@@ -660,57 +837,159 @@
</RadialGradientBrush> </RadialGradientBrush>
</Setter> </Setter>
</Style> </Style>
<Style Selector="Ellipse.doorSpill">
<Setter Property="Opacity" Value="0" />
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource GoodGlow}" />
<GradientStop Offset="1" Color="{StaticResource GoodClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Path.doorLight">
<Setter Property="Opacity" Value="0" />
<Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource GoodLight}" />
<GradientStop Offset="1" Color="{StaticResource Good}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Path.gateLight">
<Setter Property="Opacity" Value="0" />
<Setter Property="Fill" Value="{StaticResource WindowCoreBrush}" />
</Style>
<Style Selector="Rectangle.flat">
<Setter Property="Fill" Value="{StaticResource CautionBrush}" />
</Style>
<Style Selector="Rectangle.flat.dark">
<Setter Property="Fill" Value="{StaticResource WindowDarkBrush}" />
</Style>
<Style Selector="Rectangle.flat.cool">
<Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource WindowCool}" />
<GradientStop Offset="1" Color="{StaticResource BlockShade}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Rectangle.scan">
<Setter Property="Fill" Value="{StaticResource WindowCoreBrush}" />
</Style>
<Style Selector="Ellipse.beacon">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource BrandRedLight}" />
<GradientStop Offset="0.45" Color="{StaticResource BrandRed}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Border.plate"> <Style Selector="Border.plate">
<Setter Property="Background" Value="{StaticResource TextStrongBrush}" /> <Setter Property="Background" Value="{StaticResource TextStrongBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource BrandRedDarkBrush}" />
<Setter Property="BorderThickness" Value="0.8" />
<Setter Property="CornerRadius" Value="2" /> <Setter Property="CornerRadius" Value="2" />
</Style> </Style>
<Style Selector="Path.digit"> <Style Selector="Path.digit">
<Setter Property="Stroke" Value="{StaticResource GroundBrush}" /> <Setter Property="Stroke" Value="{StaticResource GroundBrush}" />
<Setter Property="StrokeThickness" Value="1.5" /> <Setter Property="StrokeThickness" Value="1.25" />
<Setter Property="StrokeLineCap" Value="Round" /> <Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="StrokeJoin" Value="Round" /> <Setter Property="StrokeJoin" Value="Round" />
<Setter Property="Width" Value="6.5" /> <Setter Property="Stretch" Value="Uniform" />
<Setter Property="Height" Value="9" /> <Setter Property="Width" Value="4.8" />
<Setter Property="Height" Value="6.6" />
<Setter Property="HorizontalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
</Style> </Style>
<Style Selector="Border.device"> <Style Selector="Border.device">
<Setter Property="Background" Value="{StaticResource SurfaceRaisedBrush}" /> <Setter Property="BorderBrush" Value="{StaticResource DeviceEdgeBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource TextSoftBrush}" /> <Setter Property="BorderThickness" Value="1.2" />
<Setter Property="BorderThickness" Value="1.5" /> <Setter Property="Background">
<LinearGradientBrush StartPoint="0%,0%" EndPoint="100%,100%">
<GradientStop Offset="0" Color="{StaticResource DeviceLit}" />
<GradientStop Offset="1" Color="{StaticResource DeviceShade}" />
</LinearGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Border.screen"> <Style Selector="Border.screen">
<Setter Property="Background" Value="{StaticResource GroundBrush}" /> <Setter Property="ClipToBounds" Value="True" />
<Setter Property="Background">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource ScreenHigh}" />
<GradientStop Offset="1" Color="{StaticResource ScreenLow}" />
</LinearGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Border.flash"> <Style Selector="Border.flash">
<Setter Property="Background" Value="{StaticResource TextStrongBrush}" /> <Setter Property="Background" Value="{StaticResource TextStrongBrush}" />
<Setter Property="Opacity" Value="0" /> <Setter Property="Opacity" Value="0" />
</Style> </Style>
<Style Selector="Border.photoFrame"> <Style Selector="Path.sheen">
<Setter Property="Fill" Value="{StaticResource SheenBrush}" />
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
<Style Selector="Ellipse.lens">
<Setter Property="Fill" Value="{StaticResource GroundBrush}" />
<Setter Property="Stroke" Value="{StaticResource DeviceEdgeBrush}" />
<Setter Property="StrokeThickness" Value="0.5" />
</Style>
<Style Selector="Rectangle.homeBar">
<Setter Property="Fill" Value="{StaticResource DeviceEdgeBrush}" />
</Style>
<Style Selector="Ellipse.screenGlow">
<Setter Property="Opacity" Value="0" />
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource BrandRedGlow}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Border.polaroid">
<Setter Property="Background" Value="{StaticResource TextStrongBrush}" /> <Setter Property="Background" Value="{StaticResource TextStrongBrush}" />
<Setter Property="CornerRadius" Value="2" /> <Setter Property="CornerRadius" Value="1.5" />
<Setter Property="Padding" Value="2" /> <Setter Property="Padding" Value="2,2,2,5" />
</Style> </Style>
<Style Selector="Canvas.photo"> <Style Selector="Path.heart, Path.heartlet">
<Setter Property="Background" Value="{StaticResource BrandRedLightBrush}" /> <Setter Property="Fill">
</Style> <LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<Style Selector="Path.hills"> <GradientStop Offset="0" Color="{StaticResource BrandRedLight}" />
<Setter Property="Fill" Value="{StaticResource BrandRedDarkBrush}" /> <GradientStop Offset="1" Color="{StaticResource BrandRed}" />
</Style> </LinearGradientBrush>
<Style Selector="Ellipse.sun"> </Setter>
<Setter Property="Fill" Value="{StaticResource CautionBrush}" />
</Style>
<Style Selector="Ellipse.packet">
<Setter Property="Fill" Value="{StaticResource TextStrongBrush}" />
</Style>
<Style Selector="Path.heart">
<Setter Property="Fill" Value="{StaticResource BrandRedBrush}" />
</Style> </Style>
<Style Selector="Ellipse.badge.good"> <Style Selector="Ellipse.badge.good">
<Setter Property="Fill" Value="{StaticResource GoodBrush}" /> <Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource GoodLight}" />
<GradientStop Offset="1" Color="{StaticResource Good}" />
</LinearGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Ellipse.badge.caution"> <Style Selector="Ellipse.badge.caution">
<Setter Property="Fill" Value="{StaticResource CautionBrush}" /> <Setter Property="Fill">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="50%,100%">
<GradientStop Offset="0" Color="{StaticResource CautionLight}" />
<GradientStop Offset="1" Color="{StaticResource Caution}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.badgeGlow.good">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource GoodGlow}" />
<GradientStop Offset="1" Color="{StaticResource GoodClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.badgeGlow.caution">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0" Color="{StaticResource CautionGlow}" />
<GradientStop Offset="1" Color="{StaticResource CautionClear}" />
</RadialGradientBrush>
</Setter>
</Style> </Style>
<Style Selector="Path.badgeMark"> <Style Selector="Path.badgeMark">
<Setter Property="Stroke" Value="{StaticResource GroundBrush}" /> <Setter Property="Stroke" Value="{StaticResource GroundBrush}" />
@@ -718,6 +997,46 @@
<Setter Property="StrokeLineCap" Value="Round" /> <Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="StrokeJoin" Value="Round" /> <Setter Property="StrokeJoin" Value="Round" />
</Style> </Style>
<Style Selector="Path.beam">
<Setter Property="Opacity" Value="0" />
<Setter Property="Fill">
<LinearGradientBrush StartPoint="0%,100%" EndPoint="100%,0%">
<GradientStop Offset="0" Color="{StaticResource Beam}" />
<GradientStop Offset="1" Color="{StaticResource BeamClear}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.callout">
<Setter Property="StrokeThickness" Value="1.2" />
<Setter Property="Stroke" Value="{StaticResource TrimSoftBrush}" />
<Setter Property="Fill">
<RadialGradientBrush Center="40%,30%" GradientOrigin="40%,30%" RadiusX="70%" RadiusY="70%">
<GradientStop Offset="0" Color="{StaticResource SurfaceRaised}" />
<GradientStop Offset="1" Color="{StaticResource Ground}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.calloutGlow">
<Setter Property="Fill">
<RadialGradientBrush>
<GradientStop Offset="0.6" Color="{StaticResource BrandRedGlow}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedClear}" />
</RadialGradientBrush>
</Setter>
</Style>
<Style Selector="Path.orbit">
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="StrokeLineCap" Value="Round" />
<Setter Property="Stroke">
<LinearGradientBrush StartPoint="50%,0%" EndPoint="100%,100%">
<GradientStop Offset="0" Color="{StaticResource BrandRedClear}" />
<GradientStop Offset="1" Color="{StaticResource BrandRedLight}" />
</LinearGradientBrush>
</Setter>
</Style>
<Style Selector="Ellipse.led">
<Setter Property="Fill" Value="{StaticResource CautionBrush}" />
</Style>
<Style Selector="Border.story"> <Style Selector="Border.story">
<Setter Property="Background" Value="{StaticResource SurfaceBrush}" /> <Setter Property="Background" Value="{StaticResource SurfaceBrush}" />
@@ -734,7 +1053,6 @@
<Setter Property="Background" Value="{StaticResource GroundBrush}" /> <Setter Property="Background" Value="{StaticResource GroundBrush}" />
<Setter Property="CornerRadius" Value="21,21,0,0" /> <Setter Property="CornerRadius" Value="21,21,0,0" />
<Setter Property="ClipToBounds" Value="True" /> <Setter Property="ClipToBounds" Value="True" />
<Setter Property="Padding" Value="0,8,0,0" />
</Style> </Style>
<Style Selector="Border.storyMark"> <Style Selector="Border.storyMark">
<Setter Property="Width" Value="44" /> <Setter Property="Width" Value="44" />
@@ -780,22 +1098,6 @@
<Setter Property="Fill" Value="{StaticResource BrandRedLightBrush}" /> <Setter Property="Fill" Value="{StaticResource BrandRedLightBrush}" />
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
</Style> </Style>
<Style Selector="Ellipse.callout">
<Setter Property="Fill" Value="{StaticResource SurfaceBrush}" />
<Setter Property="Stroke" Value="{StaticResource TextSoftBrush}" />
<Setter Property="StrokeThickness" Value="1.2" />
</Style>
<Style Selector="Path.calloutLine">
<Setter Property="Stroke" Value="{StaticResource TextSoftBrush}" />
<Setter Property="StrokeThickness" Value="1.2" />
<Setter Property="StrokeDashArray" Value="2,3" />
</Style>
<Style Selector="Rectangle.slot">
<Setter Property="Fill" Value="{StaticResource LineBrush}" />
</Style>
<Style Selector="Ellipse.led">
<Setter Property="Fill" Value="{StaticResource GoodBrush}" />
</Style>
<Style Selector="Border.farewell"> <Style Selector="Border.farewell">
<Setter Property="Background" Value="{StaticResource GroundBrush}" /> <Setter Property="Background" Value="{StaticResource GroundBrush}" />
</Style> </Style>
+105 -62
View File
@@ -5,102 +5,145 @@
FlowDirection="LeftToRight" FlowDirection="LeftToRight"
Width="360" Height="212" ClipToBounds="True"> Width="360" Height="212" ClipToBounds="True">
<Canvas Width="360" Height="212"> <Canvas Width="360" Height="212">
<Rectangle Classes="sky" Width="360" Height="212" />
<Ellipse Classes="dusk" Canvas.Left="-90" Canvas.Top="30" Width="540" Height="240" />
<Canvas x:Name="Sky" /> <Canvas x:Name="Sky" />
<Ellipse x:Name="Halo" Classes="glow" Width="240" Height="170" /> <Border x:Name="Meteor" Classes="meteor" Width="54" Height="1.6" Canvas.Left="-27" Canvas.Top="-0.8" />
<Canvas x:Name="Clouds">
<Path Classes="cloud" Data="{StaticResource ArtCloud}" Canvas.Left="-21" Canvas.Top="-10" />
<Path Classes="cloud" Data="{StaticResource ArtCloud}" Canvas.Left="-21" Canvas.Top="-10" />
<Path Classes="cloud" Data="{StaticResource ArtCloud}" Canvas.Left="-21" Canvas.Top="-10" />
</Canvas>
<Ellipse x:Name="Halo" Classes="halo" Width="260" Height="190" />
<Ellipse Classes="atmosphere" Canvas.Left="-144" Canvas.Top="96" Width="648" Height="648" />
<Ellipse Classes="planet" Canvas.Left="-110" Canvas.Top="130" Width="580" Height="580" /> <Ellipse Classes="planet" Canvas.Left="-110" Canvas.Top="130" Width="580" Height="580" />
<Ellipse Classes="meridian" Canvas.Left="58" Canvas.Top="130" Width="244" Height="580" /> <Canvas x:Name="Towns" />
<Ellipse Classes="meridian" Canvas.Left="-57" Canvas.Top="130" Width="474" Height="580" />
<Ellipse Classes="meridian" Canvas.Left="25" Canvas.Top="161" Width="310" Height="28" />
<Ellipse Classes="meridian" Canvas.Left="-35" Canvas.Top="207" Width="430" Height="36" />
<Ellipse Classes="rim" Canvas.Left="-110" Canvas.Top="130" Width="580" Height="580" /> <Ellipse Classes="rim" Canvas.Left="-110" Canvas.Top="130" Width="580" Height="580" />
<Canvas x:Name="Hamlets">
<Image Source="{StaticResource ArtHamlet}" Width="10" Height="10" />
<Image Source="{StaticResource ArtHamlet}" Width="10" Height="10" />
<Image Source="{StaticResource ArtHamlet}" Width="10" Height="10" />
<Image Source="{StaticResource ArtHamlet}" Width="10" Height="10" />
</Canvas>
<Canvas x:Name="Trees">
<Image Source="{StaticResource ArtPine}" Width="20" Height="36" />
<Image Source="{StaticResource ArtPine}" Width="20" Height="36" />
<Image Source="{StaticResource ArtOak}" Width="26" Height="36" />
</Canvas>
<Path x:Name="TrailOne" Classes="trail" /> <Path x:Name="TrailOne" Classes="trail" />
<Path x:Name="TrailTwo" Classes="trail" /> <Path x:Name="TrailTwo" Classes="trail" />
<Canvas x:Name="Block" Width="72" Height="112"> <Canvas x:Name="Block" Width="76" Height="126">
<Ellipse Classes="shadow" Canvas.Left="-4" Canvas.Top="105" Width="80" Height="10" /> <Ellipse Classes="contact" Canvas.Left="-8" Canvas.Top="114" Width="94" Height="18" />
<Path Classes="wall" Data="{StaticResource ArtBlockFront}" /> <Image Source="{StaticResource ArtBlock}" Canvas.Top="-10" Width="76" Height="136" />
<Path Classes="wall side" Data="{StaticResource ArtBlockSide}" />
<Path Classes="flatRoof" Data="{StaticResource ArtBlockTop}" />
<Canvas x:Name="Flats" /> <Canvas x:Name="Flats" />
<Path Classes="door" Data="{StaticResource ArtBlockGate}" /> <Ellipse x:Name="ScanGlow" Classes="windowGlow" Canvas.Left="-11" Canvas.Top="-10.5" Width="30" Height="32" />
<Border Classes="plate" Canvas.Left="21" Canvas.Top="86" Width="14" Height="11"> <Rectangle x:Name="Scan" Classes="scan" Width="8" Height="11" RadiusX="1" RadiusY="1" />
<Path x:Name="GateLight" Classes="gateLight" Data="{StaticResource ArtBlockGate}" />
<Ellipse x:Name="Beacon" Classes="beacon" Canvas.Left="17.5" Canvas.Top="-9.5" Width="5" Height="5" />
<Ellipse x:Name="BlockPlateGlow" Classes="windowGlow" Canvas.Left="12" Canvas.Top="76" Width="36" Height="36" />
<Border Classes="plate" Canvas.Left="23" Canvas.Top="89" Width="14" Height="10">
<Path Classes="digit" Data="{StaticResource ArtDigitFour}" /> <Path Classes="digit" Data="{StaticResource ArtDigitFour}" />
</Border> </Border>
</Canvas> </Canvas>
<Canvas x:Name="House" Width="80" Height="76"> <Canvas x:Name="Smoke" />
<Ellipse Classes="shadow" Canvas.Left="-6" Canvas.Top="67" Width="92" Height="10" />
<Ellipse x:Name="WindowGlow" Classes="warmGlow" Canvas.Left="14" Canvas.Top="6" Width="86" Height="64" /> <Canvas x:Name="House" Width="86" Height="84">
<Path Classes="wall" Data="{StaticResource ArtHouseFront}" /> <Ellipse Classes="contact" Canvas.Left="-6" Canvas.Top="70" Width="98" Height="18" />
<Path Classes="wall side" Data="{StaticResource ArtHouseSide}" /> <Ellipse x:Name="DoorSpill" Classes="doorSpill" Canvas.Left="-2" Canvas.Top="70" Width="46" Height="16" />
<Path Classes="roof" Data="{StaticResource ArtHouseRoof}" /> <Ellipse x:Name="Pool" Classes="windowGlow" Canvas.Left="44" Canvas.Top="66" Width="56" Height="20" />
<Path Classes="roofEdge" Data="{StaticResource ArtHouseEdge}" /> <Image Source="{StaticResource ArtHouse}" Width="86" Height="84" />
<Path Classes="door" Data="{StaticResource ArtHouseDoor}" /> <Ellipse x:Name="WindowGlow" Classes="windowGlow" Canvas.Left="44" Canvas.Top="33" Width="44" Height="44" />
<Path x:Name="DoorLight" Classes="doorLight" Data="{StaticResource ArtHouseDoor}" /> <Path x:Name="DoorLight" Classes="doorLight" Data="{StaticResource ArtHouseDoor}" />
<Path Classes="window" Data="{StaticResource ArtHouseWindow}" /> <Ellipse x:Name="PlateGlow" Classes="windowGlow" Canvas.Left="12" Canvas.Top="15" Width="38" Height="38" />
<Path Classes="mullion" Data="{StaticResource ArtHouseMullions}" /> <Border x:Name="Plate" Classes="plate" Canvas.Left="24" Canvas.Top="28.5" Width="14" Height="11">
<Ellipse x:Name="Round" Classes="window" Canvas.Left="23.5" Canvas.Top="28.5" Width="9" Height="9" />
<Ellipse x:Name="PlateGlow" Classes="warmGlow" Canvas.Left="8" Canvas.Top="15" Width="40" Height="35" />
<Border x:Name="Plate" Classes="plate" Canvas.Left="21" Canvas.Top="27" Width="14" Height="11">
<Path Classes="digit" Data="{StaticResource ArtDigitSeven}" /> <Path Classes="digit" Data="{StaticResource ArtDigitSeven}" />
</Border> </Border>
</Canvas> </Canvas>
<Path x:Name="CalloutLine" Classes="calloutLine" /> <Path x:Name="Beam" Classes="beam" />
<Grid x:Name="Callout" Width="58" Height="58"> <Grid x:Name="Callout" Width="64" Height="64" Canvas.Left="-32" Canvas.Top="-32">
<Ellipse Classes="calloutGlow" Margin="-12" />
<Ellipse Classes="callout" /> <Ellipse Classes="callout" />
<Canvas Width="32" Height="22" HorizontalAlignment="Center" VerticalAlignment="Center"> <Canvas Width="40" Height="30" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,4,0,0" RenderTransform="scale(1.2)">
<Border Classes="device" Width="32" Height="22" CornerRadius="4" /> <Ellipse Classes="contact" Canvas.Left="3" Canvas.Top="20" Width="34" Height="10" />
<Rectangle Classes="slot" Canvas.Left="6" Canvas.Top="7" Width="13" Height="2" /> <Image Source="{StaticResource ArtServer}" Width="40" Height="30" />
<Rectangle Classes="slot" Canvas.Left="6" Canvas.Top="13" Width="13" Height="2" /> <Ellipse x:Name="Led" Classes="led" Canvas.Left="12" Canvas.Top="16.2" Width="2.6" Height="2.6" />
<Ellipse x:Name="Led" Classes="led" Canvas.Left="23" Canvas.Top="9" Width="4.5" Height="4.5" />
</Canvas> </Canvas>
<Path x:Name="Orbit" Classes="orbit" Data="{StaticResource ArtOrbit}" />
</Grid> </Grid>
<Canvas x:Name="Phone" Width="24" Height="40"> <Canvas x:Name="Phone" Width="28" Height="58">
<Border Classes="device" Width="24" Height="40" CornerRadius="5" /> <Ellipse Classes="contact" Canvas.Left="1" Canvas.Top="50" Width="26" Height="7" />
<Border Classes="screen" Canvas.Left="3" Canvas.Top="5" Width="18" Height="29" CornerRadius="1.5" /> <Canvas x:Name="PhoneBody" Width="28" Height="48">
<Border x:Name="Flash" Classes="flash" Canvas.Left="3" Canvas.Top="5" Width="18" Height="29" CornerRadius="1.5" /> <Border Classes="device" Canvas.Left="1" Width="26" Height="46" CornerRadius="6" />
<Border Classes="screen" Canvas.Left="3.5" Canvas.Top="5" Width="21" Height="34" CornerRadius="2.5">
<Grid>
<Image x:Name="Viewfinder" Source="{StaticResource ArtPhoto}" Stretch="UniformToFill" />
<Image x:Name="Outbox" Source="{StaticResource ArtLetter}" Width="13" Height="9" Margin="0,4,0,0" />
</Grid>
</Border>
<Border x:Name="Flash" Classes="flash" Canvas.Left="3.5" Canvas.Top="5" Width="21" Height="34" CornerRadius="2.5" />
<Path Classes="sheen" Data="{StaticResource ArtPhoneSheen}" />
<Ellipse Classes="lens" Canvas.Left="12.8" Canvas.Top="1.8" Width="2.4" Height="2.4" />
<Rectangle Classes="homeBar" Canvas.Left="10" Canvas.Top="41.6" Width="8" Height="1.4" RadiusX="0.7" RadiusY="0.7" />
</Canvas>
</Canvas> </Canvas>
<Canvas x:Name="Tablet" Width="44" Height="32"> <Canvas x:Name="Tablet" Width="54" Height="48">
<Border Classes="device" Width="44" Height="32" CornerRadius="4" /> <Ellipse Classes="contact" Canvas.Left="3" Canvas.Top="40" Width="48" Height="8" />
<Border Classes="screen" Canvas.Left="3" Canvas.Top="3" Width="38" Height="26" CornerRadius="1.5" /> <Canvas x:Name="TabletBody" Width="54" Height="40">
<Viewbox x:Name="Received" Canvas.Left="3" Canvas.Top="3" Width="38" Height="26" Stretch="Fill"> <Ellipse x:Name="TabletGlow" Classes="screenGlow" Canvas.Left="-14" Canvas.Top="-16" Width="82" Height="68" />
<Canvas Classes="photo" Width="18" Height="13"> <Border Classes="device" Canvas.Left="2" Width="50" Height="35" CornerRadius="5" />
<Ellipse Classes="sun" Canvas.Left="11" Canvas.Top="2" Width="4" Height="4" /> <Border Classes="screen" Canvas.Left="5" Canvas.Top="3.5" Width="44" Height="28" CornerRadius="2">
<Path Classes="hills" Data="{StaticResource ArtHills}" /> <Image x:Name="Received" Source="{StaticResource ArtPhoto}" Stretch="UniformToFill" />
</Canvas> </Border>
</Viewbox> <Path Classes="sheen" Data="{StaticResource ArtTabletSheen}" />
</Canvas>
</Canvas> </Canvas>
<Border x:Name="Photo" Classes="photoFrame" Width="24" Height="19"> <Path x:Name="Comet" Classes="comet">
<Viewbox Stretch="Fill"> <Path.Stroke>
<Canvas Classes="photo" Width="18" Height="13"> <LinearGradientBrush>
<Ellipse Classes="sun" Canvas.Left="11" Canvas.Top="2" Width="4" Height="4" /> <GradientStop Offset="0" Color="{StaticResource BrandRedClear}" />
<Path Classes="hills" Data="{StaticResource ArtHills}" /> <GradientStop Offset="0.7" Color="{StaticResource BrandRedLight}" />
</Canvas> <GradientStop Offset="1" Color="{StaticResource TextStrong}" />
</Viewbox> </LinearGradientBrush>
</Path.Stroke>
</Path>
<Canvas x:Name="Sparks" />
<Ellipse x:Name="RippleOne" Classes="ripple" Canvas.Left="-20" Canvas.Top="-20" Width="40" Height="40" />
<Ellipse x:Name="RippleTwo" Classes="ripple" Canvas.Left="-20" Canvas.Top="-20" Width="40" Height="40" />
<Border x:Name="Photo" Classes="polaroid" Canvas.Left="-13" Canvas.Top="-12" Width="26" Height="24">
<Image Source="{StaticResource ArtPhoto}" Stretch="UniformToFill" />
</Border> </Border>
<Image x:Name="Letter" Source="{StaticResource ArtLetter}" Canvas.Left="-11" Canvas.Top="-7.5" Width="22" Height="15" />
<Grid x:Name="Packet" Width="22" Height="22"> <Path x:Name="Heart" Classes="heart" Data="{StaticResource ArtHeart}" Canvas.Left="-12" Canvas.Top="-12" Width="24" Height="24" />
<Ellipse Classes="glow" /> <Canvas x:Name="Hearts">
<Ellipse Classes="packet" Width="8" Height="8" /> <Path Classes="heartlet" Data="{StaticResource ArtHeart}" Canvas.Left="-12" Canvas.Top="-12" Width="24" Height="24" />
</Grid> <Path Classes="heartlet" Data="{StaticResource ArtHeart}" Canvas.Left="-12" Canvas.Top="-12" Width="24" Height="24" />
<Path Classes="heartlet" Data="{StaticResource ArtHeart}" Canvas.Left="-12" Canvas.Top="-12" Width="24" Height="24" />
</Canvas>
<Path x:Name="Heart" Classes="heart" Data="{StaticResource ArtHeart}" Width="24" Height="24" /> <Grid x:Name="Yes" Canvas.Left="-12" Canvas.Top="-12" Width="24" Height="24">
<Ellipse Classes="badgeGlow good" Margin="-10" />
<Grid x:Name="Yes" Width="22" Height="22">
<Ellipse Classes="badge good" /> <Ellipse Classes="badge good" />
<Viewbox Width="13" Height="13"> <Viewbox Width="14" Height="14">
<Path Classes="badgeMark" Data="{StaticResource IconCheck}" /> <Path Classes="badgeMark" Data="{StaticResource IconCheck}" />
</Viewbox> </Viewbox>
</Grid> </Grid>
<Grid x:Name="Unsure" Canvas.Left="-12" Canvas.Top="-12" Width="24" Height="24">
<Grid x:Name="Unsure" Width="22" Height="22"> <Ellipse Classes="badgeGlow caution" Margin="-10" />
<Ellipse Classes="badge caution" /> <Ellipse Classes="badge caution" />
<Path Classes="badgeMark" Data="{StaticResource ArtQuestion}" Width="7" Height="11" <Path Classes="badgeMark" Data="{StaticResource ArtQuestion}" Width="7" Height="11"
HorizontalAlignment="Center" VerticalAlignment="Center" /> HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid> </Grid>
<Rectangle Classes="vignette" Width="360" Height="212" IsHitTestVisible="False" />
</Canvas> </Canvas>
</v:Animated> </v:Animated>
+327 -127
View File
@@ -14,54 +14,96 @@ public partial class IntroScene : Animated
const double Radius = 290; const double Radius = 290;
const double Loop = 8; const double Loop = 8;
static readonly (double X, double Y, double Pace)[] StarSpots = static readonly double[] Hamlet = [9, 23, 337, 351];
[ static readonly int[] Search = [5, 0, 10, 3, 8, 1, 11, 6, 2, 9, 4, 7];
(22, 18, 1.1), (64, 46, 0.7), (98, 12, 1.4), (140, 34, 0.9), (205, 14, 1.2), (250, 42, 0.8), (292, 16, 1.3), static readonly int[] Television = [3, 10];
(334, 50, 1.0), (318, 94, 0.6), (30, 88, 1.2), (110, 72, 0.9), (268, 86, 1.1), (350, 20, 0.7), (176, 8, 1.0), static readonly double[][] Groves = [[112, 126, 244], [104, 117, 284], [292, 306, 186]];
]; static readonly double[][] Growth = [[1, 0.72, 0.95], [1, 0.72, 0.95], [1, 0.72, 0.8]];
static readonly double[] FlatLight = [0.9, 0.25, 0.7, 0.35, 0.85, 0.2, 0.6, 0.9, 0.3, 0.75, 0.4, 0.8]; readonly (Control Star, double Pace, double Shift, double Glow)[] stars;
readonly (Control Light, double Pace, double Shift)[] lights;
readonly Ellipse[] stars;
readonly Rectangle[] flats; readonly Rectangle[] flats;
readonly Ellipse[] puffs;
readonly Ellipse[] sparks;
readonly double[] lean = new double[3];
Point from; Point from;
Point home; Point home;
Point to; Point to;
Point bend; Point bend;
Point turn; Point turn;
double heartTop; Point chimney;
Point heart;
Point badge;
Point doubt;
Point plate;
Point callout;
public IntroScene() public IntroScene()
{ {
InitializeComponent(); InitializeComponent();
stars = StarSpots.Select(spot => stars = Enumerable.Range(1, 56)
.Select(i => new Point(Fraction(i * 0.7548776662) * 356 + 2, Fraction(i * 0.5698402910) * 160 + 3))
.Where(spot => spot.Y < Ground(spot.X) - 16)
.Select((spot, i) =>
{
var bright = i % 6 == 2;
var size = bright ? 10 : 0.9 + 1.5 * Fraction(i * 0.381966) * Fraction(i * 0.381966);
var star = bright ? (Control)new Avalonia.Controls.Shapes.Path() : new Ellipse { Width = size, Height = size };
star.Classes.Add(bright ? "sparkle" : "star");
star.RenderTransform = new ScaleTransform();
Canvas.SetLeft(star, spot.X - size / 2);
Canvas.SetTop(star, spot.Y - size / 2);
Sky.Children.Add(star);
return (star, 0.6 + 1.6 * Fraction(i * 0.2763932), i * 2.39996, 0.3 + 0.7 * Fraction(i * 0.6180339887));
})
.ToArray();
lights = Enumerable.Range(0, 7).SelectMany(town =>
{ {
var star = new Ellipse { Width = 2.4, Height = 2.4 }; var x = 22 + town * 53 + 10 * Math.Sin(town * 2.1);
star.Classes.Add("star"); var y = Math.Min(Ground(x) + 24 + 26 * Fraction(town * 0.618034), 204);
Canvas.SetLeft(star, spot.X); var glow = new Ellipse { Width = 46, Height = 16 };
Canvas.SetTop(star, spot.Y); glow.Classes.Add("townGlow");
Sky.Children.Add(star); Canvas.SetLeft(glow, x - 23);
return star; Canvas.SetTop(glow, y - 8);
Towns.Children.Add(glow);
return Enumerable.Range(1, 6).Select(i =>
{
var size = 0.9 + 1.1 * Fraction((town * 6 + i) * 0.381966);
var light = new Ellipse { Width = size, Height = size };
light.Classes.Add("town");
Canvas.SetLeft(light, x + 30 * (Fraction((town * 6 + i) * 0.7548776662) - 0.5));
Canvas.SetTop(light, y + 9 * (Fraction((town * 6 + i) * 0.5698402910) - 0.5));
Towns.Children.Add(light);
return ((Control)light, 0.4 + 0.9 * Fraction(i * 0.2763932), town * 1.3 + i * 2.39996);
});
}).ToArray(); }).ToArray();
flats = Enumerable.Range(0, 12).Select(i => flats = Enumerable.Range(0, 12).Select(i =>
{ {
var flat = new Rectangle { Width = 8, Height = 9 }; var flat = new Rectangle { Width = 8, Height = 11, RadiusX = 1, RadiusY = 1 };
flat.Classes.Add("flat"); flat.Classes.Add("flat");
Canvas.SetLeft(flat, 10 + i % 3 * 14); if (i is 1 or 5 or 8) flat.Classes.Add("dark");
Canvas.SetTop(flat, 22 + i / 3 * 16); if (Television.Contains(i)) flat.Classes.Add("cool");
Canvas.SetLeft(flat, 12 + i % 3 * 14);
Canvas.SetTop(flat, 24 + i / 3 * 17);
Flats.Children.Add(flat); Flats.Children.Add(flat);
return flat; return flat;
}).ToArray(); }).ToArray();
foreach (var mover in new Control[] { Photo, Packet, Heart, Yes, Unsure, Callout }) puffs = Enumerable.Range(0, 5).Select(_ => Speck(Smoke, "smoke", 10)).ToArray();
{ sparks = Enumerable.Range(0, 7).Select(_ => Speck(Sparks, "spark", 3.4)).ToArray();
mover.RenderTransform = new ScaleTransform(); foreach (var mover in new Control[] { Photo, Letter, Heart, Yes, Unsure, Callout, RippleOne, RippleTwo, Meteor }
mover.RenderTransformOrigin = RelativePoint.Center; .Concat(Clouds.Children).Concat(Hearts.Children)) mover.RenderTransform = Mobile();
} Orbit.RenderTransform = new RotateTransform();
PhoneBody.RenderTransform = new TranslateTransform();
TabletBody.RenderTransform = new TranslateTransform();
Received.RenderTransform = new ScaleTransform();
Outbox.RenderTransform = new TranslateTransform();
Scan.RenderTransform = new TranslateTransform();
ScanGlow.RenderTransform = new TranslateTransform();
Lay(); Lay();
Place(Poster); Place(Poster);
} }
protected override double Poster => Step switch { 0 => 4.5, 1 => 5.0, _ => 5.2 }; protected override double Poster => Step switch { 0 => 4.7, 1 => 5.0, _ => 5.3 };
public int Step public int Step
{ {
@@ -81,50 +123,87 @@ public partial class IntroScene : Animated
{ {
var sharing = Step == 0; var sharing = Step == 0;
var single = Step == 1; var single = Step == 1;
Tablet.IsVisible = Photo.IsVisible = Heart.IsVisible = Round.IsVisible = sharing; Tablet.IsVisible = Photo.IsVisible = Heart.IsVisible = Hearts.IsVisible = Viewfinder.IsVisible = sharing;
Packet.IsVisible = Yes.IsVisible = Plate.IsVisible = !sharing; Letter.IsVisible = Yes.IsVisible = Plate.IsVisible = Outbox.IsVisible = DoorLight.IsVisible = DoorSpill.IsVisible = !sharing;
Callout.IsVisible = CalloutLine.IsVisible = PlateGlow.IsVisible = single; Callout.IsVisible = Beam.IsVisible = PlateGlow.IsVisible = single;
Block.IsVisible = Unsure.IsVisible = Step == 2; Block.IsVisible = Unsure.IsVisible = Step == 2;
TrailTwo.IsVisible = !single; TrailTwo.IsVisible = !single;
var phone = Stand(Phone, sharing ? 56 : 44, 12, 40, 1.25); for (var i = 0; i < Hamlet.Length; i++) Stand(Hamlets.Children[i], Hamlet[i], 5, 10, 1);
var house = Stand(House, Step switch { 0 => 180, 1 => 204, _ => 128 }, 40, 72, Step switch { 0 => 1.5, 1 => 1.6, _ => 1.25 }); for (var i = 0; i < lean.Length; i++) lean[i] = Stand(Trees.Children[i], Groves[Step][i], i == 2 ? 13 : 10, 36, Growth[Step][i]).Degrees;
from = Turn(phone, 0, -44); var phone = Stand(Phone, sharing ? 60 : 48, 14, 56, 1.2, 0.5);
Canvas.SetLeft(Halo, house.At.X - 120); var house = Stand(House, Step switch { 0 => 180, 1 => 194, _ => 128 }, 42, 80, Step switch { 0 => 1.45, 1 => 1.5, _ => 1.2 });
Canvas.SetTop(Halo, house.At.Y - 130); from = Turn(phone, 0, -54);
chimney = Turn(house, 12, -80);
var glow = Turn(house, 12, -42);
Canvas.SetLeft(Halo, glow.X - Halo.Width / 2);
Canvas.SetTop(Halo, glow.Y - Halo.Height / 2);
if (sharing) if (sharing)
{ {
var tablet = Stand(Tablet, 304, 22, 32, 1.25); var tablet = Stand(Tablet, 300, 27, 46, 1.15, 0.5);
home = Turn(house, -6, -30); home = Turn(house, 24, -25);
to = Turn(tablet, 0, -16); to = Turn(tablet, 0, -27);
bend = new Point((from.X + home.X) / 2, 18); bend = new Point((from.X + home.X) / 2, 4);
turn = new Point((home.X + to.X) / 2, 18); turn = new Point((home.X + to.X) / 2, 10);
Put(Heart, Turn(tablet, 10, -44)); heart = Turn(tablet, 16, -58);
TrailOne.Data = Curve(from, bend, home); TrailOne.Data = Arc(from, bend, home);
TrailTwo.Data = Curve(home, turn, to); TrailTwo.Data = Arc(home, turn, to);
return; return;
} }
home = Turn(house, -12, -8); home = Turn(house, -21, -9);
bend = new Point((from.X + home.X) / 2, 40); bend = new Point((from.X + home.X) / 2, single ? 22 : 40);
Put(Yes, Turn(house, -4, single ? -73 : -82)); badge = Turn(house, -43, -34);
TrailOne.Data = Curve(from, bend, home); TrailOne.Data = Arc(from, bend, home);
if (single) if (single)
{ {
var window = Turn(house, 24, -26); plate = Turn(house, -11, -46);
var bubble = new Point(318, 46); callout = new Point(310, 56);
Put(Callout, bubble); Beam.Data = Funnel(Turn(house, 24, -25), callout);
CalloutLine.Data = Geometry.Parse(FormattableString.Invariant($"M {window.X:0.##} {window.Y:0.##} L {bubble.X - 22:0.##} {bubble.Y + 18:0.##}"));
return; return;
} }
var block = Stand(Block, 240, 34, 110, 0.95); var block = Stand(Block, 248, 38, 124, 0.95);
to = Turn(block, -6, -5); to = Turn(block, -8, -9);
turn = new Point((from.X + to.X) / 2, -14); turn = new Point((from.X + to.X) / 2 + 20, -18);
Put(Unsure, Turn(block, 2, -122)); doubt = Turn(block, -48, -42);
TrailTwo.Data = Curve(from, turn, to); TrailTwo.Data = Arc(from, turn, to);
} }
protected override void Place(double seconds) protected override void Place(double seconds)
{ {
for (var i = 0; i < stars.Length; i++) stars[i].Opacity = 0.2 + 0.45 * (0.5 + 0.5 * Math.Sin(seconds * StarSpots[i].Pace + i * 1.7)); foreach (var (star, pace, shift, glow) in stars)
{
var shine = 0.5 + 0.5 * Math.Sin(seconds * pace + shift);
star.Opacity = glow * (0.3 + 0.7 * shine);
if (star is Ellipse) continue;
var scale = (ScaleTransform)star.RenderTransform;
scale.ScaleX = scale.ScaleY = 0.35 + 0.45 * shine;
}
foreach (var (light, pace, shift) in lights) light.Opacity = 0.55 + 0.45 * Math.Sin(seconds * pace + shift);
for (var i = 0; i < Clouds.Children.Count; i++)
{
var drift = Fraction(i * 0.41 + seconds * (0.004 + 0.0025 * i)) * 470 - 55;
Move(Clouds.Children[i], new Point(drift, 46 + i * 24), 1.5 - 0.3 * i, 0, 0.55 + 0.2 * i);
}
for (var k = 0; k < puffs.Length; k++)
{
var rise = Fraction(seconds / 3.6 + (double)k / puffs.Length);
var at = new Point(chimney.X + rise * 11 + Math.Sin(rise * 5 + k) * 1.8, chimney.Y - rise * 32);
Move(puffs[k], at, 0.35 + 1.15 * rise, 0, 0.8 * Math.Sin(Math.PI * rise));
}
for (var i = 0; i < lean.Length; i++)
{
var sway = (RotateTransform)((TransformGroup)Trees.Children[i].RenderTransform).Children[1];
sway.Angle = lean[i] + 1.6 * Math.Sin(seconds * 1.15 + i * 2.1);
}
foreach (var i in Television) flats[i].Opacity = 0.55 + 0.45 * Math.Abs(Math.Sin(seconds * 5.3 + i) * Math.Sin(seconds * 2.9));
((TranslateTransform)PhoneBody.RenderTransform).Y = -2.5 - 1.8 * Math.Sin(seconds * 1.7);
((TranslateTransform)TabletBody.RenderTransform).Y = -2.5 - 1.8 * Math.Sin(seconds * 1.7 + 2);
((RotateTransform)Orbit.RenderTransform).Angle = seconds * 110 % 360;
Led.Opacity = Math.Sin(seconds * 13) * Math.Sin(seconds * 4.7) > 0.05 ? 1 : 0.25;
Beacon.Opacity = Math.Pow(0.5 + 0.5 * Math.Cos(seconds * 3.4), 6);
var streak = Fraction((seconds + 5) / 17) * 17 / 0.8;
Move(Meteor, new Point(310 - 140 * streak, 10 + 48 * streak), 1, 161, streak < 1 ? Math.Sin(Math.PI * streak) : 0);
Comet.Opacity = Photo.Opacity = Letter.Opacity = 0;
foreach (var spark in sparks) spark.Opacity = 0;
var t = seconds % Loop; var t = seconds % Loop;
if (Step == 0) Share(t); if (Step == 0) Share(t);
else if (Step == 1) Explain(t); else if (Step == 1) Explain(t);
@@ -133,68 +212,169 @@ public partial class IntroScene : Animated
void Share(double t) void Share(double t)
{ {
Flash.Opacity = 0.9 * Envelope(t, 0.25, 0.08, 0.35, 0.45); Flash.Opacity = 0.95 * Envelope(t, 0.3, 0.06, 0.36, 0.45);
var glow = Envelope(t, 2.05, 0.25, 2.7, 1.8); Ripple(RippleOne, t < 2 ? from : to, t < 2 ? (t - 0.32) / 0.8 : (t - 4.1) / 0.9);
WindowGlow.Opacity = 0.35 + 0.65 * glow; Ripple(RippleTwo, home, (t - 1.95) / 0.8);
Halo.Opacity = 0.55 + 0.45 * glow; var inside = Envelope(t, 1.95, 0.2, 2.6, 1.6);
Received.Opacity = Envelope(t, 4.05, 0.3, 7.3, 0.5); WindowGlow.Opacity = 0.35 + 0.65 * inside;
if (t is >= 0.5 and < 2.0) Halo.Opacity = 0.45 + 0.55 * inside;
if (t is >= 0.55 and < 2.0) Fly(Photo, from, bend, home, (t - 0.55) / 1.45, 0.3, true);
else if (t is >= 2.6 and < 4.15) Fly(Photo, home, turn, to, (t - 2.6) / 1.55, 0.3, true);
var shown = Envelope(t, 4.1, 0.3, 7.3, 0.5);
Received.Opacity = shown;
var reveal = (ScaleTransform)Received.RenderTransform;
reveal.ScaleX = reveal.ScaleY = 1.3 - 0.3 * EaseOut(Clamp((t - 4.1) / 0.7));
TabletGlow.Opacity = shown * (0.75 + 0.25 * Math.Sin(t * 2.4));
var love = t - 4.2;
Move(Heart, new Point(heart.X, heart.Y - 3 * Math.Sin(love * 2)), Spring(love), 10 * Math.Sin(love * 4) * Math.Exp(-love * 1.6),
Envelope(t, 4.2, 0.05, 6.9, 0.5));
for (var k = 0; k < Hearts.Children.Count; k++)
{ {
var u = (t - 0.5) / 1.5; var rise = (t - 4.5 - k * 0.45) / 1.9;
Show(Photo, Along(from, bend, home, Smooth(u)), 0.6 + 0.55 * Math.Sin(Math.PI * u), 1); var little = Hearts.Children[k];
if (rise is < 0 or > 1)
{
little.Opacity = 0;
continue;
}
Move(little, new Point(heart.X + (k - 1) * 10 + Math.Sin(rise * 7 + k) * 3, heart.Y - 12 - rise * 30),
0.3 + 0.12 * Math.Sin(Math.PI * rise), 0, 0.9 * Math.Sin(Math.PI * rise));
} }
else if (t is >= 2.0 and < 2.3) Show(Photo, home, 0.6 * (1 - (t - 2.0) / 0.3), 1);
else if (t is >= 2.55 and < 4.1)
{
var u = (t - 2.55) / 1.55;
Show(Photo, Along(home, turn, to, Smooth(u)), 0.45 + 0.6 * Math.Sin(Math.PI * u), 1);
}
else Photo.Opacity = 0;
var heart = (t - 4.15) / 1.7;
if (heart is < 0 or > 1)
{
Heart.Opacity = 0;
return;
}
Grow(Heart, Pop(heart * 3), heart < 0.6 ? 1 : 1 - (heart - 0.6) / 0.4);
Canvas.SetTop(Heart, heartTop - 16 * heart);
} }
void Explain(double t) void Explain(double t)
{ {
Led.Opacity = 0.35 + 0.65 * (0.5 + 0.5 * Math.Sin(t * 2 * Math.PI / 1.4)); var open = Envelope(t, 0.2, 0.05, 7.2, 0.5);
Grow(Callout, Pop((t - 0.2) / 0.5), Envelope(t, 0.2, 0.1, 7.3, 0.5)); Move(Callout, callout, Spring(t - 0.2), 0, open);
CalloutLine.Opacity = 0.8 * Envelope(t, 0.5, 0.3, 7.3, 0.5); Beam.Opacity = Envelope(t, 0.5, 0.4, 7.2, 0.5);
WindowGlow.Opacity = 0.35 + 0.65 * Envelope(t, 0.2, 0.4, 7.3, 0.5); WindowGlow.Opacity = 0.4 + 0.6 * open;
PlateGlow.Opacity = Envelope(t, 1.2, 0.3, 7.2, 0.6) * (0.75 + 0.25 * Math.Sin((t - 1.2) * 5)); Halo.Opacity = 0.5 + 0.3 * open;
DoorLight.Opacity = 0.8 * Envelope(t, 3.7, 0.25, 7.2, 0.5); PlateGlow.Opacity = Envelope(t, 1.2, 0.3, 7.2, 0.6) * (0.75 + 0.25 * Math.Sin((t - 1.2) * 4));
Grow(Yes, Pop((t - 3.75) / 0.45), Envelope(t, 3.75, 0.1, 7.2, 0.5)); Ripple(RippleTwo, plate, (t - 1.25) / 0.9);
if (t is >= 2.2 and < 3.7) Show(Packet, Along(from, bend, home, Smooth((t - 2.2) / 1.5)), 1, 1); Send(t, 2.2);
else Packet.Opacity = 0; if (t is >= 2.2 and < 3.7) Fly(Letter, from, bend, home, (t - 2.2) / 1.5, 0.5, true);
var admitted = Envelope(t, 3.6, 0.2, 7.2, 0.5);
DoorLight.Opacity = 0.9 * admitted;
DoorSpill.Opacity = admitted;
Ripple(RippleOne, home, (t - 3.6) / 0.8);
Badge(Yes, badge, t - 3.75, Envelope(t, 3.75, 0.05, 7.2, 0.5));
} }
void Knock(double t) void Knock(double t)
{ {
DoorLight.Opacity = 0.8 * Envelope(t, 1.8, 0.25, 7.2, 0.5); Halo.Opacity = 0.5;
Grow(Yes, Pop((t - 1.85) / 0.45), Envelope(t, 1.85, 0.1, 7.2, 0.5)); WindowGlow.Opacity = 0.45;
Grow(Unsure, Pop((t - 4.45) / 0.45), Envelope(t, 4.45, 0.1, 7.2, 0.5)); Send(t, t < 2 ? 0.3 : 2.3);
if (t is >= 0.4 and < 1.8) Show(Packet, Along(from, bend, home, Smooth((t - 0.4) / 1.4)), 1, 1); if (t is >= 0.3 and < 1.6) Fly(Letter, from, bend, home, (t - 0.3) / 1.3, 0.5, true);
else if (t is >= 2.6 and < 4.2) Show(Packet, Along(from, turn, to, Smooth((t - 2.6) / 1.6)), 1, 1); else if (t is >= 2.3 and < 3.9) Fly(Letter, from, turn, to, (t - 2.3) / 1.6, 0.5, false);
else if (t is >= 4.2 and < 4.9) else if (t is >= 3.9 and < 6.9)
{ {
var u = (t - 4.2) / 0.7; var wait = t - 3.9;
Show(Packet, new Point(to.X - 7 * Math.Sin(Math.PI * u), to.Y - 3 * Math.Sin(Math.PI * u)), 1 - 0.5 * u, 1 - u); var shake = Math.Sin(wait * 12) * Math.Exp(-wait * 1.1);
Move(Letter, new Point(to.X + 3 * shake, to.Y - 3 - 2 * Math.Sin(wait * 2.4)), 0.8, 8 * shake, 1 - Smooth((t - 6.3) / 0.5));
} }
else Packet.Opacity = 0; var admitted = Envelope(t, 1.55, 0.2, 7.2, 0.5);
var searching = t is >= 4.45 and < 6.6 ? (int)((t - 4.45) / 0.16) % flats.Length : -1; DoorLight.Opacity = 0.9 * admitted;
for (var i = 0; i < flats.Length; i++) flats[i].Opacity = i == searching ? 1 : FlatLight[i] * 0.8; DoorSpill.Opacity = admitted;
Ripple(RippleOne, home, (t - 1.55) / 0.8);
Badge(Yes, badge, t - 1.7, Envelope(t, 1.7, 0.05, 7.2, 0.5));
Ripple(RippleTwo, to, (t - 3.9) / 0.8);
var waiting = Envelope(t, 3.9, 0.2, 6.6, 0.6);
GateLight.Opacity = 0.7 * waiting * (0.6 + 0.4 * Math.Sin(t * 6));
BlockPlateGlow.Opacity = waiting;
var look = t is >= 4.2 and < 6.6 ? Search[(int)((t - 4.2) / 0.2) % Search.Length] : -1;
Scan.Opacity = ScanGlow.Opacity = look < 0 ? 0 : 1;
if (look >= 0)
{
var x = 12 + look % 3 * 14;
var y = 24 + look / 3 * 17;
foreach (var lit in new[] { (TranslateTransform)Scan.RenderTransform, (TranslateTransform)ScanGlow.RenderTransform })
{
lit.X = x;
lit.Y = y;
}
}
Badge(Unsure, doubt, t - 4.4, Envelope(t, 4.4, 0.05, 7.2, 0.5));
} }
(Point At, double Degrees, double Size) Stand(Control art, double x, double baseX, double baseY, double size) void Send(double t, double leaving)
{ {
var dx = x - CenterX; var gone = Smooth((t - leaving + 0.25) / 0.3);
var at = new Point(x, CenterY - Math.Sqrt(Radius * Radius - dx * dx) + 1); var back = Smooth((t - leaving - 0.6) / 0.4);
var degrees = Math.Asin(dx / Radius) * 180 / Math.PI; ((TranslateTransform)Outbox.RenderTransform).Y = back > 0 ? 8 * (1 - back) : -14 * gone;
Outbox.Opacity = back > 0 ? back : 1 - gone;
}
void Fly(Control mover, Point a, Point c, Point b, double u, double tilt, bool enters)
{
var e = Ease(u);
var at = Along(a, c, b, e);
var heading = (c - a) * (1 - e) + (b - c) * e;
var degrees = Math.Clamp(Math.Atan2(heading.Y, heading.X) * 180 / Math.PI, -70, 70) * tilt;
var lift = 0.9 + 0.3 * Math.Sin(Math.PI * u);
var land = enters ? 1 - 0.65 * Smooth((u - 0.82) / 0.18) : 1 - 0.2 * Smooth((u - 0.8) / 0.2);
Move(mover, at, (0.45 + 0.55 * Smooth(u / 0.15)) * land * lift, degrees, enters ? 1 - Smooth((u - 0.92) / 0.08) : 1);
var tail = Math.Max(0, e - 0.32);
var start = Along(a, c, b, tail);
Comet.Data = Arc(start, Blossom(a, c, b, tail, e), at);
var brush = (LinearGradientBrush)Comet.Stroke;
brush.StartPoint = new RelativePoint(start, RelativeUnit.Absolute);
brush.EndPoint = new RelativePoint(at, RelativeUnit.Absolute);
var trail = Smooth(u / 0.1) * (1 - Smooth((u - 0.8) / 0.2));
Comet.Opacity = trail;
for (var k = 0; k < sparks.Length; k++)
{
var back = e - 0.045 * (k + 1);
if (back < 0) break;
var dust = Along(a, c, b, back);
var jitter = new Vector(Math.Sin(k * 2.3 + u * 17) * 2.6, Math.Cos(k * 1.7 + u * 13) * 2.6);
Move(sparks[k], dust + jitter, 1 - 0.11 * k, 0, trail * (1 - (double)k / sparks.Length));
}
}
static void Ripple(Control ring, Point at, double u)
{
if (u is < 0 or > 1)
{
ring.Opacity = 0;
return;
}
Move(ring, at, 0.2 + 1.1 * EaseOut(u), 0, 0.85 * (1 - u) * (1 - u));
}
static void Badge(Control badge, Point at, double since, double opacity) =>
Move(badge, new Point(at.X, at.Y - 2 * Math.Sin(since * 2.2)), Spring(since), 0, opacity);
static Ellipse Speck(Canvas layer, string kind, double size)
{
var speck = new Ellipse { Width = size, Height = size, RenderTransform = Mobile(), Opacity = 0 };
speck.Classes.Add(kind);
Canvas.SetLeft(speck, -size / 2);
Canvas.SetTop(speck, -size / 2);
layer.Children.Add(speck);
return speck;
}
static TransformGroup Mobile() => new() { Children = { new ScaleTransform(), new RotateTransform(), new TranslateTransform() } };
static void Move(Control mover, Point at, double size, double degrees, double opacity)
{
var group = (TransformGroup)mover.RenderTransform;
var scale = (ScaleTransform)group.Children[0];
scale.ScaleX = scale.ScaleY = Math.Max(0, size);
((RotateTransform)group.Children[1]).Angle = degrees;
var shift = (TranslateTransform)group.Children[2];
shift.X = at.X;
shift.Y = at.Y;
mover.Opacity = opacity;
}
static double Ground(double x) => CenterY - Math.Sqrt(Radius * Radius - (x - CenterX) * (x - CenterX));
static (Point At, double Degrees, double Size) Stand(Control art, double x, double baseX, double baseY, double size, double tilt = 1)
{
var at = new Point(x, Ground(x) + 1);
var degrees = tilt * Math.Asin((x - CenterX) / Radius) * 180 / Math.PI;
Canvas.SetLeft(art, at.X - baseX); Canvas.SetLeft(art, at.X - baseX);
Canvas.SetTop(art, at.Y - baseY); Canvas.SetTop(art, at.Y - baseY);
art.RenderTransformOrigin = new RelativePoint(baseX, baseY, RelativeUnit.Absolute); art.RenderTransformOrigin = new RelativePoint(baseX, baseY, RelativeUnit.Absolute);
@@ -210,13 +390,55 @@ public partial class IntroScene : Animated
return new Point(stand.At.X + x * Math.Cos(radians) - y * Math.Sin(radians), stand.At.Y + x * Math.Sin(radians) + y * Math.Cos(radians)); return new Point(stand.At.X + x * Math.Cos(radians) - y * Math.Sin(radians), stand.At.Y + x * Math.Sin(radians) + y * Math.Cos(radians));
} }
static Geometry Curve(Point a, Point c, Point b) => static Geometry Arc(Point a, Point c, Point b)
Geometry.Parse(FormattableString.Invariant($"M {a.X:0.##} {a.Y:0.##} Q {c.X:0.##} {c.Y:0.##} {b.X:0.##} {b.Y:0.##}")); {
var geometry = new StreamGeometry();
using var context = geometry.Open();
context.BeginFigure(a, false);
context.QuadraticBezierTo(c, b);
context.EndFigure(false);
return geometry;
}
static Geometry Funnel(Point from, Point to)
{
var along = (Vector)(to - from);
var across = new Vector(-along.Y, along.X) / along.Length;
var geometry = new StreamGeometry();
using var context = geometry.Open();
context.BeginFigure(from + across * 3, true);
context.LineTo(to + across * 30);
context.LineTo(to - across * 30);
context.LineTo(from - across * 3);
context.EndFigure(true);
return geometry;
}
static Point Along(Point a, Point c, Point b, double u) => static Point Along(Point a, Point c, Point b, double u) =>
new((1 - u) * (1 - u) * a.X + 2 * (1 - u) * u * c.X + u * u * b.X, (1 - u) * (1 - u) * a.Y + 2 * (1 - u) * u * c.Y + u * u * b.Y); new((1 - u) * (1 - u) * a.X + 2 * (1 - u) * u * c.X + u * u * b.X, (1 - u) * (1 - u) * a.Y + 2 * (1 - u) * u * c.Y + u * u * b.Y);
static double Smooth(double u) => u * u * (3 - 2 * u); static Point Blossom(Point a, Point c, Point b, double s, double u) =>
new((1 - s) * (1 - u) * a.X + ((1 - s) * u + s * (1 - u)) * c.X + s * u * b.X, (1 - s) * (1 - u) * a.Y + ((1 - s) * u + s * (1 - u)) * c.Y + s * u * b.Y);
static double Fraction(double x) => x - Math.Floor(x);
static double Clamp(double u) => Math.Clamp(u, 0, 1);
static double Smooth(double u)
{
u = Clamp(u);
return u * u * (3 - 2 * u);
}
static double Ease(double u)
{
u = Clamp(u);
return u < 0.5 ? 4 * u * u * u : 1 - Math.Pow(2 - 2 * u, 3) / 2;
}
static double EaseOut(double u) => 1 - Math.Pow(1 - Clamp(u), 3);
static double Spring(double since) => since <= 0 ? 0 : 1 - Math.Exp(-7 * since) * Math.Cos(13 * since);
static double Envelope(double t, double start, double rise, double end, double fall) static double Envelope(double t, double start, double rise, double end, double fall)
{ {
@@ -224,26 +446,4 @@ public partial class IntroScene : Animated
if (t < start + rise) return (t - start) / rise; if (t < start + rise) return (t - start) / rise;
return t <= end ? 1 : 1 - (t - end) / fall; return t <= end ? 1 : 1 - (t - end) / fall;
} }
static double Pop(double u) => u <= 0 ? 0 : u >= 1 ? 1 : u < 0.6 ? 1.18 * u / 0.6 : 1.18 - 0.18 * (u - 0.6) / 0.4;
void Put(Control mover, Point at)
{
Canvas.SetLeft(mover, at.X - mover.Width / 2);
Canvas.SetTop(mover, at.Y - mover.Height / 2);
if (mover == Heart) heartTop = at.Y - mover.Height / 2;
}
void Show(Control mover, Point at, double size, double opacity)
{
Put(mover, at);
Grow(mover, size, opacity);
}
static void Grow(Control mover, double size, double opacity)
{
mover.Opacity = opacity;
var scale = (ScaleTransform)mover.RenderTransform;
scale.ScaleX = scale.ScaleY = Math.Max(0, size);
}
} }
+14 -2
View File
@@ -114,7 +114,7 @@
<Border x:Name="WishCard" Classes="story"> <Border x:Name="WishCard" Classes="story">
<StackPanel> <StackPanel>
<Border Classes="scene"> <Border Classes="scene">
<Grid> <Grid FlowDirection="LeftToRight">
<Viewbox Stretch="Uniform"> <Viewbox Stretch="Uniform">
<v:IntroScene x:Name="WishScene" Step="0" /> <v:IntroScene x:Name="WishScene" Step="0" />
</Viewbox> </Viewbox>
@@ -133,7 +133,7 @@
<Border x:Name="WayCard" Classes="story"> <Border x:Name="WayCard" Classes="story">
<StackPanel> <StackPanel>
<Border Classes="scene"> <Border Classes="scene">
<Grid> <Grid FlowDirection="LeftToRight">
<Viewbox Stretch="Uniform"> <Viewbox Stretch="Uniform">
<v:IntroScene x:Name="WayScene" Step="1" /> <v:IntroScene x:Name="WayScene" Step="1" />
</Viewbox> </Viewbox>
@@ -234,6 +234,10 @@
Classes.flowing="{Binding IsRunning}" Classes.lit="{Binding IsLit}" /> Classes.flowing="{Binding IsRunning}" Classes.lit="{Binding IsLit}" />
<Path Classes="wire" Data="{StaticResource WireToStart}" IsVisible="{Binding WireToStart}" <Path Classes="wire" Data="{StaticResource WireToStart}" IsVisible="{Binding WireToStart}"
Classes.flowing="{Binding IsRunning}" Classes.lit="{Binding IsLit}" /> Classes.flowing="{Binding IsRunning}" Classes.lit="{Binding IsLit}" />
<Path Classes="packets" Data="{StaticResource WireToEnd}" IsVisible="{Binding WireToEnd}"
Classes.flowing="{Binding IsRunning}" />
<Path Classes="packets" Data="{StaticResource WireToStart}" IsVisible="{Binding WireToStart}"
Classes.flowing="{Binding IsRunning}" />
<StackPanel Spacing="6" Margin="0,12" HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel Spacing="6" Margin="0,12" HorizontalAlignment="Center" VerticalAlignment="Center">
<Border Classes="linkTag" IsVisible="{Binding ShowLink}"> <Border Classes="linkTag" IsVisible="{Binding ShowLink}">
<StackPanel Orientation="Horizontal" Spacing="6"> <StackPanel Orientation="Horizontal" Spacing="6">
@@ -269,10 +273,18 @@
AutomationProperties.AutomationId="{Binding AutomationId}" AutomationProperties.AutomationId="{Binding AutomationId}"
AutomationProperties.Name="{Binding Title}"> AutomationProperties.Name="{Binding Title}">
<Grid Width="90" Height="90" Classes="node" Classes.lit="{Binding IsLit}"> <Grid Width="90" Height="90" Classes="node" Classes.lit="{Binding IsLit}">
<Ellipse Classes="aura" Margin="-18"
Classes.good="{Binding IsGood}" Classes.caution="{Binding IsCaution}"
Classes.bad="{Binding IsBad}" />
<Ellipse Classes="pulse" Width="90" Height="90" IsVisible="{Binding IsRunning}" /> <Ellipse Classes="pulse" Width="90" Height="90" IsVisible="{Binding IsRunning}" />
<Ellipse Classes="disc" Width="90" Height="90" <Ellipse Classes="disc" Width="90" Height="90"
Classes.good="{Binding IsGood}" Classes.caution="{Binding IsCaution}" Classes.good="{Binding IsGood}" Classes.caution="{Binding IsCaution}"
Classes.bad="{Binding IsBad}" Classes.unknown="{Binding IsUnknown}" /> Classes.bad="{Binding IsBad}" Classes.unknown="{Binding IsUnknown}" />
<Ellipse Classes="gloss" Margin="5" />
<Path Classes="spinner" Data="{StaticResource ArtNodeOrbit}" IsVisible="{Binding IsRunning}" />
<Ellipse Classes="burst" Width="90" Height="90"
Classes.good="{Binding IsGood}" Classes.caution="{Binding IsCaution}"
Classes.bad="{Binding IsBad}" />
<Viewbox Width="58" Height="58"> <Viewbox Width="58" Height="58">
<Grid Classes="art" Width="48" Height="48" Classes.running="{Binding IsRunning}" <Grid Classes="art" Width="48" Height="48" Classes.running="{Binding IsRunning}"
Classes.good="{Binding IsGood}" Classes.caution="{Binding IsCaution}" Classes.good="{Binding IsGood}" Classes.caution="{Binding IsCaution}"