blob: 3d70f274458bf90d61af11b4e9b508635ddb8848 (
plain) (
blame)
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
|
package advanced
import org.scalajs.dom
import dom.html
import concurrent._
import async.Async._
import scalajs.js.annotation.JSExport
import scalajs.concurrent.JSExecutionContext.Implicits.queue
@JSExport
object Async {
def init(canvas: html.Canvas) = {
val renderer = canvas.getContext("2d")
.asInstanceOf[dom.CanvasRenderingContext2D]
canvas.style.backgroundColor = "#f8f8f8"
canvas.height = canvas.parentElement.clientHeight
canvas.width = canvas.parentElement.clientWidth
renderer.lineWidth = 5
renderer.strokeStyle = "red"
renderer.fillStyle = "cyan"
renderer
}
@JSExport
def main(canvas: html.Canvas) = {
val renderer = init(canvas)
// async
def rect = canvas.getBoundingClientRect()
type ME = dom.MouseEvent
val mousemove =
new Channel[ME](canvas.onmousemove = _)
val mouseup =
new Channel[ME](canvas.onmouseup = _)
val mousedown =
new Channel[ME](canvas.onmousedown = _)
// Disabled due to scala-js#1469
async{
while(true){
val start = await(mousedown())
renderer.beginPath()
renderer.moveTo(
start.clientX - rect.left,
start.clientY - rect.top
)
var res = await(mousemove | mouseup)
while(res.`type` == "mousemove"){
renderer.lineTo(
res.clientX - rect.left,
res.clientY - rect.top
)
renderer.stroke()
res = await(mousemove | mouseup)
}
renderer.fill()
await(mouseup())
renderer.clearRect(0, 0, 1000, 1000)
}
}
}
@JSExport
def main0(canvas: html.Canvas) = {
val renderer = init(canvas)
// traditional
def rect = canvas.getBoundingClientRect()
var dragState = 0
canvas.onmousemove ={(e: dom.MouseEvent) =>
if (dragState == 1) {
renderer.lineTo(
e.clientX - rect.left,
e.clientY - rect.top
)
renderer.stroke()
}
}
canvas.onmouseup = {(e: dom.MouseEvent) =>
if(dragState == 1) {
renderer.fill()
dragState = 2
}else if (dragState == 2){
renderer.clearRect(0, 0, 1000, 1000)
dragState = 0
}
}
canvas.onmousedown ={(e: dom.MouseEvent) =>
if (dragState == 0) {
dragState = 1
renderer.beginPath()
renderer.moveTo(
e.clientX - rect.left,
e.clientY - rect.top
)
}
}
}
}
class Channel[T](init: (T => Unit) => Unit){
init(update)
private[this] var value: Promise[T] = null
def apply(): Future[T] = {
value = Promise[T]()
value.future
}
def update(t: T): Unit = {
if (value != null && !value.isCompleted) value.success(t)
}
def |(other: Channel[T]): Future[T] = {
val p = Promise[T]()
for{
f <- Seq(other(), this())
t <- f
} p.trySuccess(t)
p.future
}
}
|