Current section

Files

Jump to
phoenix_duskmoon lib phoenix_duskmoon fun element.ex
Raw

lib/phoenix_duskmoon/fun/element.ex

defmodule PhoenixDuskmoon.Fun.Element do
@moduledoc """
Duskmoon UI Fun Element components
"""
use PhoenixDuskmoon.Component, :html
@doc """
Generates a eclipse effect
## Example
```heex
<PhoenixDuskmoon.Fun.Element.dmf_eclipse
/>
```
"""
@doc type: :component
attr(:id, :any,
default: nil,
doc: """
html attribute id
"""
)
attr(:class, :any,
default: "",
doc: """
html attribute class
"""
)
attr(:background, :string,
default: "#09090b",
doc: """
Background color
"""
)
attr(:size, :string,
default: "400px",
doc: """
size
"""
)
def dmf_eclipse(assigns) do
~H"""
<div
id={@id}
class={["dm-fun-eclipse", @class]}
style={"--bg-color: #{@background}; --size: #{@size};"}
>
<div class="layer layer-1"></div>
<div class="layer layer-2"></div>
<div class="layer layer-3"></div>
<div class="layer layer-4"></div>
<div class="layer layer-5"></div>
<div class="layer layer-6"></div>
</div>
"""
end
@doc """
Generates a plasma ball effect
## Example
```heex
<PhoenixDuskmoon.Fun.Element.dmf_plasma_ball />
```
"""
@doc type: :component
attr(:id, :any,
default: nil,
doc: """
html attribute id
"""
)
attr(:class, :any,
default: "",
doc: """
html attribute class
"""
)
attr(:size, :string,
default: "350px",
doc: """
size
"""
)
attr(:show_base, :boolean,
default: false,
doc: """
show base of plasma ball
"""
)
attr(:show_electrode, :boolean,
default: true,
doc: """
show electrode of plasma ball
"""
)
def dmf_plasma_ball(assigns) do
~H"""
<div class="dm-fun-plasma-ball" style={"--size: #{@size};"}>
<input type="checkbox" class={["switcher", if(@show_base, do: "", else: "hidden")]} checked="checked" />
<div class="glassball">
<div class={["electrode", if(!@show_electrode, do: "hide-electrode")]}></div>
<div class="rays">
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
</div>
<div class="rays">
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
</div>
<div class="rays">
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
</div>
<div class="rays">
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray bigwave"><span></span><span></span></div>
</div>
<div class="rays">
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
</div>
<div class="rays">
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
<div class="ray"><span></span><span></span><span></span></div>
</div>
</div>
<div :if={@show_base} class="base">
<div></div>
<div></div>
<span></span>
</div>
<div :if={@show_base} class="switch"></div>
</div>
"""
end
@doc """
Generates a atom effect
## Example
```heex
<PhoenixDuskmoon.Fun.Element.dmf_atom />
```
"""
@doc type: :component
attr(:id, :any,
default: nil,
doc: """
html attribute id
"""
)
attr(:class, :any,
default: "",
doc: """
html attribute class
"""
)
attr(:size, :string,
default: "200px",
doc: """
size
"""
)
attr(:atom_color, :string,
default: "#00d8ff",
doc: """
atom color
"""
)
attr(:electron_color, :string,
default: "#99f8ff",
doc: """
electron color
"""
)
def dmf_atom(assigns) do
~H"""
<div
id={@id}
class={["dm-fun-atom", @class]}
style={[
"--atom-size: #{@size}",
"--atom-color: #{@atom_color}",
"--electron-color: #{@electron_color};"
] |> Enum.join(";")}
>
<div class="electron"></div>
<div class="electron-alpha"></div>
<div class="electron-omega"></div>
</div>
"""
end
@doc """
Generates snowflakes, bubbles or unicode `❆`.
## Example
```heex
<PhoenixDuskmoon.Fun.Element.dmf_snow />
```
"""
@doc type: :component
attr(:class, :any,
default: "",
doc: """
html attribute class for each snowflake
"""
)
attr(:count, :integer,
default: 200,
doc: """
snowflake count
"""
)
attr(:color, :string,
default: "#fff",
doc: """
snowflake color
"""
)
attr(:size, :string,
default: "10px",
doc: """
snowflake size
"""
)
attr(:unicode, :boolean,
default: false,
doc: """
show snowflake by using unicode character [❆]
"""
)
def dmf_snow(assigns) do
~H"""
<style>
<%= for n <- 0..@count do %>
<% random_x = Enum.random(1..1000000) * 0.0001 %>
<% random_offset = Enum.random(-100000..100000) * 0.0001 %>
.dm-fun-snowflake-<%= n %> {
opacity: <%= Enum.random(1..10000) * 0.0001 %>;
transform: translate(<%= random_x %>vw, -10px) scale(<%= Enum.random(1..10000) * 0.0001 %>);
animation: dm-fun-snowflake-fall-<%= n %> <%= Enum.random(10..30) * 1 %>s <%= Enum.random(0..30) * -1 %>s linear infinite;
}
@keyframes dm-fun-snowflake-fall-<%= n %> {
<%= Enum.random(30000..80000) / 1000 %>% {
transform: translate(<%= if(random_x + random_offset > 100, do: random_x - random_offset, else: random_x + random_offset) %>vw, <%= Enum.random(30000..80000) / 1000 %>vh) scale(<%= Enum.random(1..10000) * 0.0001 %>);
}
to {
transform: translate(<%= if(random_x + random_offset / 2 > 100, do: random_x - random_offset / 2, else: random_x + random_offset / 2) %>vw, 100vh) scale(<%= Enum.random(1..10000) * 0.0001 %>);
}
}
<% end %>
</style>
<div
:for={n <- 0..@count}
class={["dm-fun-snowflake", "dm-fun-snowflake-#{n}", @class, if(@unicode, do: "snowflake-unicode")]}
style={"--snowflake-color: #{@color}; --snowflake-size: #{@size};"}
/>
"""
end
@doc """
Generates bubbles fly up from this element.
## Example
```heex
<PhoenixDuskmoon.Fun.Element.dmf_footer_bubbles />
```
"""
@doc type: :component
attr(:id, :any,
default: nil,
doc: """
html attribute id
"""
)
attr(:class, :any,
default: "",
doc: """
html attribute class for bubbles container
"""
)
attr(:color, :string,
default: "#fff",
doc: """
bubble color
"""
)
attr(:count, :integer,
default: 128,
doc: """
snowflake count
"""
)
def dmf_footer_bubbles(assigns) do
assigns =
assigns
|> assign_new(:blob_id, fn ->
"footer-bubbles-blob-#{Enum.random(0..999_999_999_999)}"
end)
~H"""
<div
id={@id}
class={["dm-fun-footer-bubbles", @class]}
style={"--footer-bg-color: #{@color}; filter: url(\"##{@blob_id}\");"}
>
<div
:for={_n <- 1..@count}
class="dm-fun-footer-bubble"
style={[
"--size: #{2 + Enum.random(0..999_999_999_999) * 1.0e-12 * 4}rem",
"--distance: #{6 + Enum.random(0..999_999_999_999) * 1.0e-12 * 4}rem",
"--position: min(calc(100% - var(--size) / 2), #{-5 + Enum.random(0..999_999_999_999) * 1.0e-12 * 110}%)",
"--time: #{2 + Enum.random(0..999_999_999_999) * 1.0e-12 * 2}s",
"--delay: #{-1 * (2 + Enum.random(0..999_999_999_999) * 1.0e-12 * 2)}s"
] |> Enum.join(";")}
></div>
</div>
<svg style="position: fixed; top: 100vh">
<defs>
<filter id={@blob_id}>
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur"></feGaussianBlur>
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="blob"></feColorMatrix>
</filter>
</defs>
</svg>
"""
end
@doc """
Generates Loading.
## Examples
```heex
<.dmf_loading_ex size={44} item_count={99} speed={"2s"} />
```
"""
@doc type: :component
attr(:id, :any,
default: false,
doc: """
html attribute id
"""
)
attr(:class, :any,
default: "",
doc: """
html attribute class
"""
)
attr(:item_count, :integer,
default: 88,
doc: """
loading effect bubble count
"""
)
attr(:speed, :string,
default: "4s",
doc: """
loading effect speed
"""
)
attr(:size, :string,
default: "20rem",
doc: """
loading size, css value
"""
)
def dmf_loading_ex(assigns) do
assigns = assigns |> assign(:random_inner, Enum.random(10_000..100_000))
~H"""
<style data-id={@random_inner}>
.dm-fun-loader-<%= @random_inner %> {
--duration: <%= @speed %>;
--size: <%= @size %>;
position: relative;
width: var(--size, 20rem);
height: var(--size, 20rem);
}
.dm-fun-loader-<%= @random_inner %> i {
position: absolute;
filter: blur(0.2em) contrast(2);
left: calc(var(--size, 21em) / 2.1);
top: calc(var(--size, 21em) / 2.1);
width: calc(var(--size, 21em) / 21);
height: calc(var(--size, 21em) / 21);
background-color: hsl(var(--hue, 0), 75%, 75%);
border-radius: 50%;
transform: rotateZ(var(--rz, 0)) translateY(calc(var(--size, 21em) / 2.1 / 2));
animation: dm-fun-item-move-<%= @random_inner %> var(--duration) var(--delay, 0s) infinite ease-in-out;
}
@keyframes dm-fun-item-move-<%= @random_inner %> {
0% { transform: rotateZ(var(--rz, 0)) translateY(calc(var(--size, 21em) / 21 * 4)) translate(0, 0) scale(0); }
2% { transform: rotateZ(var(--rz, 0)) translateY(calc(var(--size, 21em) / 21 * 4)) translate(0, 0) scale(1.25); }
20% { transform: rotateZ(var(--rz, 0)) translateY(calc(var(--size, 21em) / 21 * 4)) translate(0, 0) scale(1.25); }
90%, 100% { transform: rotateZ(var(--rz, 0)) translateY(calc(var(--size, 21em) / 21 * 4)) translate(var(--tx, 0), var(--ty, 0)) scale(0); }
}
<%= for i <- 0..(@item_count - 1) do %>
.dm-fun-loader-<%= @random_inner %> i:nth-child(<%= i + 1 %>) {
--rz: <%= i * (360 / @item_count) %>deg;
--delay: calc(var(--duration) / <%= @item_count %> * <%= i %> - var(--duration));
--tx: <%= Enum.random(1..1000) / 250 %>em;
--ty: <%= Enum.random(1..1000) / 125 - 2.5 %>em;
--hue: <%= i * (360 / @item_count) %>;
}
<% end %>
</style>
<div id={@id} class={["dm-fun-loader-#{@random_inner}", @class]}>
<i :for={_ <- 1..@item_count} />
</div>
"""
end
end