Skip to content

Commit

Permalink
Clock: max_value to automatically stop the clock
Browse files Browse the repository at this point in the history
  • Loading branch information
fonsp committed Feb 24, 2021
1 parent e1e8fbb commit a8e0990
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 65 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PlutoUI"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
authors = ["Fons van der Plas <[email protected]>"]
version = "0.7.1"
version = "0.7.2"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
46 changes: 23 additions & 23 deletions assets/clock.css
Original file line number Diff line number Diff line change
@@ -1,86 +1,86 @@
clock {
plutoui-clock {
display: flex;
flex-direction: row;
}

clock>* {
plutoui-clock > * {
align-self: center;
margin-right: .3rem;
margin-right: 0.3rem;
}

analog {
plutoui-analog {
display: block;
position: relative;
overflow: hidden;
width: 20px;
height: 20px;
}

analog>* {
plutoui-analog > * {
display: block;
width: 100%;
height: 100%;
}

analog>*>svg {
plutoui-analog > * > svg {
width: 100%;
height: 100%;
}

clock analog front,
clock analog zoof {
plutoui-clock plutoui-analog plutoui-front,
plutoui-clock plutoui-analog plutoui-zoof {
position: absolute;
left: 0;
top: 0;
animation: 1s linear 🔁 infinite;
}

clock.stopped analog front {
plutoui-clock.stopped plutoui-analog plutoui-front {
animation-play-state: paused;
}

clock.stopped analog zoof {
plutoui-clock.stopped plutoui-analog plutoui-zoof {
display: none;
}

clock input {
plutoui-clock input {
width: 3rem;
}

clock span {
plutoui-clock span {
font-family: "Roboto Mono", monospace;
font-size: .75rem;
word-spacing: -.2rem;
font-size: 0.75rem;
word-spacing: -0.2rem;
}

clock span#unit {
plutoui-clock span#unit {
font-style: italic;
cursor: pointer;
}

clock span#unit::after {
plutoui-clock span#unit::after {
content: "secs / tick";
}

clock.inverted span#unit::after {
plutoui-clock.inverted span#unit::after {
content: "ticks / sec";
}

clock button {
plutoui-clock button {
margin-left: 1rem;
margin-right: 1rem;
}

clock button::after {
plutoui-clock button::after {
content: "Stop";
}

clock.stopped button::after {
plutoui-clock.stopped button::after {
content: "Start";
}

clock.fixed span,
clock.fixed input {
plutoui-clock.fixed span,
plutoui-clock.fixed input {
display: none;
}

Expand All @@ -91,4 +91,4 @@ clock.fixed input {
100% {
transform: rotate(360deg);
}
}
}
30 changes: 23 additions & 7 deletions assets/clock.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
// const clock = this.querySelector("clock")
const clock = (currentScript ? currentScript : this.currentScript).previousElementSibling
const clock = (currentScript ?? this.currentScript).previousElementSibling
const tpsInput = clock.querySelector("input")
const analogfront = clock.querySelector("analog front")
const analogzoof = clock.querySelector("analog zoof")
const analogfront = clock.querySelector("plutoui-analog plutoui-front")
const analogzoof = clock.querySelector("plutoui-analog plutoui-zoof")
const unit = clock.querySelector("span#unit")
const button = clock.querySelector("button")

const max_value = +clock.dataset.maxValue

var t = 1
var starttime = null
var dt = 1

tpsInput.oninput = (e) => {
var dt = tpsInput.valueAsNumber
dt = tpsInput.valueAsNumber
if (clock.classList.contains("inverted")) {
dt = 1.0 / dt
}
Expand All @@ -21,15 +25,27 @@ tpsInput.oninput = (e) => {
tpsInput.oninput()

analogfront.onanimationiteration = (e) => {
t++
clock.value = t
clock.dispatchEvent(new CustomEvent("input"))
if (!clock.classList.contains("stopped")) {
const running_time = (Date.now() - starttime) / 1000
t = Math.max(t + 1, Math.floor(running_time / dt))
if (!isNaN(max_value)) {
t = Math.min(t, max_value)
}
clock.value = t
clock.dispatchEvent(new CustomEvent("input"))
}

if (t >= max_value) {
clock.classList.add("stopped")
t = 0
}
}
unit.onclick = (e) => {
clock.classList.toggle("inverted")
tpsInput.oninput()
}
button.onclick = (e) => {
starttime = Date.now()
clock.classList.toggle("stopped")
if (!clock.classList.contains("stopped")) {
t = 1 - 1
Expand Down
172 changes: 138 additions & 34 deletions src/Clock.jl
Original file line number Diff line number Diff line change
@@ -1,40 +1,144 @@
export Clock
### A Pluto.jl notebook ###
# v0.12.20

struct Clock
interval::Real
fixed::Bool
start_running::Bool
Clock(interval=1, fixed=false, start_running=false) = interval >= 0 ? new(interval, fixed, start_running) : error("interval must be non-negative")
using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
quote
local el = $(esc(element))
global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
el
end
end

function show(io::IO, ::MIME"text/html", clock::Clock)
# We split the HTML string into multiple files, but you could also write all of this into a single (long) string 🎈
cb = read(joinpath(PKG_ROOT_DIR, "assets", "clock_back.svg"), String)
cf = read(joinpath(PKG_ROOT_DIR, "assets", "clock_front.svg"), String)
cz = read(joinpath(PKG_ROOT_DIR, "assets", "clock_zoof.svg"), String)
js = read(joinpath(PKG_ROOT_DIR, "assets", "clock.js"), String)
css = read(joinpath(PKG_ROOT_DIR, "assets", "clock.css"), String)
# ╔═╡ e7a070ab-67e7-444b-88d8-87c14aaef046
names(@__MODULE__)

# ╔═╡ b1491ca6-f791-41d8-96b5-28971084f34c


# ╔═╡ 05804305-cb1f-4c97-8937-f56289222bd7
md"""
Rerun the big cell after you edit one of the JS/CSS assets.
"""

# ╔═╡ 9be4d586-76d8-11eb-06ed-c53d3aef0469
begin
export Clock

Base.@kwdef struct Clock
interval::Real = 1
fixed::Bool = false
start_running::Bool = false
max_value::Union{Int64,Nothing} = nothing

Clock(interval, fixed, start_running, max_value) = interval >= 0 ? new(interval, fixed, start_running, max_value) : error("interval must be non-negative")
end

# for backwards compat
Clock(interval=1, fixed=false, start_running=false) = Clock(interval, fixed, start_running, nothing)

result = """
<clock class='$(clock.fixed ? " fixed" : "")$(clock.start_running ? "" : " stopped")'>
<analog>
<back>$(cb)</back>
<front>$(cf)</front>
<zoof style="opacity: 0">$(cz)</zoof>
</analog>
<button></button>
<span>speed: </span>
<input type="number" value="$(clock.interval)" min=0 step=any lang="en-001">
<span id="unit" title="Click to invert"></span>
</clock>
<script>
$(js)
</script>
<style>
$(css)
</style>
"""
write(io, result)
Clock(interval; kwargs...) = Clock(interval=interval; kwargs...)

function Base.show(io::IO, ::MIME"text/html", clock::Clock)
# We split the HTML string into multiple files, but you could also write all of this into a single (long) string 🎈
cb = read(joinpath(@__DIR__, "..", "assets", "clock_back.svg"), String)
cf = read(joinpath(@__DIR__, "..", "assets", "clock_front.svg"), String)
cz = read(joinpath(@__DIR__, "..", "assets", "clock_zoof.svg"), String)
js = read(joinpath(@__DIR__, "..", "assets", "clock.js"), String)
css = read(joinpath(@__DIR__, "..", "assets", "clock.css"), String)

result = """
<plutoui-clock class='$(clock.fixed ? " fixed" : "")$(clock.start_running ? "" : " stopped")' data-max-value=$(repr(clock.max_value))>
<plutoui-analog>
<plutoui-back>$(cb)</plutoui-back>
<plutoui-front>$(cf)</plutoui-front>
<plutoui-zoof style="opacity: 0">$(cz)</plutoui-zoof>
</plutoui-analog>
<button></button>
<span>speed: </span>
<input type="number" value="$(clock.interval)" min=0 step=any lang="en-001">
<span id="unit" title="Click to invert"></span>
</plutoui-clock>
<script>
$(js)
</script>
<style>
$(css)
</style>
"""
write(io, result)
end

Base.get(clock::Clock) = 1
end

get(clock::Clock) = 1
# ╔═╡ 06289ad2-9e2f-45b3-9d15-7c5a4167e138
@bind tick Clock()

# ╔═╡ 9ecd95f0-d7a5-4ee9-9e18-9d87e5d43ab7
tick; rand()

# ╔═╡ d82dae11-b2c6-42b5-8c52-67fbb6cc236a
tick

# ╔═╡ 80c6e80e-077a-4e31-9467-788a8c437bfc
@bind fasttick Clock(0.001, max_value=1000)

# ╔═╡ 63854404-e6a5-4dc6-a40e-b09b9f531465
fasttick

# ╔═╡ a5f8ed96-136c-4ff4-8275-bd569f0dae40
md"""
## Different constructors
"""

# ╔═╡ c3c07db2-bb9c-4521-83ab-e81fbb376b4e
Clock(3.0)

# ╔═╡ 83a021ab-7cca-47c7-a560-9cbf58b35ab7
Clock(3.0, true)

# ╔═╡ c96dfd13-ddd4-443f-ab09-30e15ea76785
Clock(3.0, true, true)

# ╔═╡ 78ee5465-ce3b-45f6-acec-aa69175807f5
Clock(3.0, true, true, 5)

# ╔═╡ 9115fbcd-1550-4439-a830-c69b83b774b3
Clock()

# ╔═╡ f4104cb3-7c07-4814-99f9-a00764ebadf6
@assert try

# this should error:
Clock(-5)

false
catch
true
end

# ╔═╡ 21cba3fb-7bb0-43ae-b4c4-5c1eb7241fec
Clock(2.0, max_value=123)

# ╔═╡ Cell order:
# ╠═06289ad2-9e2f-45b3-9d15-7c5a4167e138
# ╠═9ecd95f0-d7a5-4ee9-9e18-9d87e5d43ab7
# ╠═d82dae11-b2c6-42b5-8c52-67fbb6cc236a
# ╠═80c6e80e-077a-4e31-9467-788a8c437bfc
# ╠═63854404-e6a5-4dc6-a40e-b09b9f531465
# ╠═e7a070ab-67e7-444b-88d8-87c14aaef046
# ╠═b1491ca6-f791-41d8-96b5-28971084f34c
# ╟─05804305-cb1f-4c97-8937-f56289222bd7
# ╠═9be4d586-76d8-11eb-06ed-c53d3aef0469
# ╟─a5f8ed96-136c-4ff4-8275-bd569f0dae40
# ╠═c3c07db2-bb9c-4521-83ab-e81fbb376b4e
# ╠═83a021ab-7cca-47c7-a560-9cbf58b35ab7
# ╠═c96dfd13-ddd4-443f-ab09-30e15ea76785
# ╠═78ee5465-ce3b-45f6-acec-aa69175807f5
# ╠═9115fbcd-1550-4439-a830-c69b83b774b3
# ╠═f4104cb3-7c07-4814-99f9-a00764ebadf6
# ╠═21cba3fb-7bb0-43ae-b4c4-5c1eb7241fec

2 comments on commit a8e0990

@fonsp
Copy link
Member Author

@fonsp fonsp commented on a8e0990 Feb 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/30770

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.7.2 -m "<description of version>" a8e0990d60b76949f38f45482d72768a6f343725
git push origin v0.7.2

Please sign in to comment.