-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcanvas.ex
123 lines (106 loc) · 3.13 KB
/
canvas.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
defmodule CollabarativeCanvasWeb.Canvas do
import CollabarativeCanvasWeb.Colors
alias CollabarativeCanvasWeb.Presence
use CollabarativeCanvasWeb, :live_view
@topic "canvasview"
def mount(_params, %{"user" => user}, socket) do
color = get_color(user)
if connected?(socket) do
Presence.track(self(), @topic, socket.id, %{
socket_id: socket.id,
# x, y should be retrieved from client on connect.\
# the next props should ideally be one object
x: 50,
y: 50,
name: user,
color: color
})
CollabarativeCanvasWeb.Endpoint.subscribe(@topic)
end
updated =
assign(socket, %{
users: list_users(),
socket_id: socket.id,
user: %{
name: user,
color: color
}
})
{:ok, updated}
end
def mount(_params, _session, socket) do
{:ok, socket |> redirect(to: "/")}
end
def handle_event("mouse-move", params, socket) do
metas =
Presence.get_by_key(@topic, socket.id)[:metas]
|> hd
|> Map.merge(
Map.new(params, fn {k, v} ->
{String.to_existing_atom(k), v}
end)
)
Presence.update(self(), @topic, socket.id, metas)
{:noreply, socket}
end
def handle_event("mouse-up", _, socket) do
{:noreply, socket}
end
def handle_event("draw-segment", params, socket) do
CollabarativeCanvasWeb.Endpoint.broadcast_from(
self(),
@topic,
"new-draw-segment",
params
)
{:noreply, socket}
end
def handle_info(%{event: "new-draw-segment", payload: payload}, socket) do
socket = push_event(socket, "new-draw-segment", payload)
{:noreply, socket}
end
def handle_info(%{event: "presence_diff", payload: _payload}, socket) do
socket = assign(socket, users: list_users())
{:noreply, socket}
end
def render(assigns) do
~H"""
<div
id="canvas-page"
class="touch-none"
phx-hook="Canvas"
data-user-color={@user.color}
data-user-name={@user.name}
>
<canvas phx-update="ignore" class="cursor-none" id="c" />
<ul class="list-none" id="cursors">
<%= for user <- @users do %>
<li
style={"color: #{user.color}; left: #{user.x}%; top: #{user.y}%;"}
class="flex flex-col absolute pointer-events-none whitespace-nowrap overflow-hidden"
>
<svg
version="1.1"
width="25px"
height="25px"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="8 3 21 21"
>
<polygon fill="black" points="8.2,20.9 8.2,4.9 19.8,16.5 13,16.5 12.6,16.6" />
<polygon fill="currentColor" points="9.2,7.3 9.2,18.5 12.2,15.6 12.6,15.5 17.4,15.5" />
</svg>
<span style={"color: #{user.color};"} class="mt-1 ml-4 px-1 text-sm text-white">
<%= user.name %>
</span>
</li>
<% end %>
</ul>
</div>
"""
end
defp list_users do
Presence.list(@topic)
|> Enum.map(fn {_, data} -> hd(data.metas) end)
end
end