-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy path07b_dynamic_to_an_array_of_values.html
157 lines (130 loc) · 4.34 KB
/
07b_dynamic_to_an_array_of_values.html
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<!doctype html>
<html lang="en">
<head>
<title>Tween.js / dynamic to large interpolation array</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body {
margin: 0px;
}
#scene1,
#scene2 {
display: inline-block;
font-size: 13px;
padding-right: 32px;
}
</style>
<link href="css/style.css" media="screen" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="info" style="position: relative">
<h1><a href="http://github.com/tweenjs/tween.js">tween.js</a></h1>
<h2>07b _ dynamic to large interpolation array</h2>
<p>tweening towards many random moving targets</p>
<div id="scene1">
<p><code>.dynamic(false)</code></p>
</div>
<div id="scene2">
<p><code>.dynamic(true)</code></p>
</div>
</div>
<script type="module">
import * as TWEEN from '../dist/tween.esm.js'
import {drawRabbit, drawFox} from './js/drawings.js'
const width = 480
const height = 320
const rabbitValues = {x: [], y: [], eatenCounter: []}
// generate random rabbits
const rabbitCount = 20
for (let i = 0; i < rabbitCount; i++) {
rabbitValues.x.push(50 + getRandomInt(width - 100))
rabbitValues.y.push(50 + getRandomInt(height - 100))
rabbitValues.eatenCounter.push(i + 1)
}
// or use static population
// const rabbitCount = 2
// rabbitValues.x = [Math.random() * width, width - 50]
// rabbitValues.y = [height - 50, Math.random() * height]
// rabbitValues.eatenCounter = [1, 2]
const bunnyDestinations = []
for (let i = 0; i < rabbitCount; i++) {
bunnyDestinations.push({x: Math.random() * width, y: Math.random() * height})
}
const bunnyColors = []
const maxColor = 200 // avoiding pale colors
for (let i = 0; i < rabbitCount; i++) {
bunnyColors.push(`rgb(${getRandomInt(maxColor)}, ${getRandomInt(maxColor)}, ${getRandomInt(maxColor)})`)
}
startScene('scene1', false)
startScene('scene2', true)
function startScene(id, dynamic) {
const group = new TWEEN.Group()
const duration = 8000
const scene = document.getElementById(id)
const canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
scene.appendChild(canvas)
const context = canvas.getContext('2d')
const rabbitTweens = []
const rabbits = []
// clone rabbitValues so it won't be modified (that way it will be unique for each scene)
const _rabbitValues = {
x: [...rabbitValues.x],
y: [...rabbitValues.y],
eatenCounter: [...rabbitValues.eatenCounter],
}
for (let i = 0; i < rabbitCount; i++) {
const rabbit = {
x: _rabbitValues.x[i],
y: _rabbitValues.y[i],
color: bunnyColors[i],
alive: true,
}
rabbits.push(rabbit)
rabbitTweens.push(createRabbitTween(i, rabbit))
}
function createRabbitTween(index, rabbit) {
return new TWEEN.Tween(rabbit, group)
.to(bunnyDestinations[index], duration)
.onUpdate(function (object) {
// We need `index + 1` because Tween modifies the arrays and adds the fox start values to it.
// TODO this is confusing. Better if Tween simply never modified the input object.
_rabbitValues.x[index + 1] = object.x
_rabbitValues.y[index + 1] = object.y
})
.start()
}
const fox = {x: 50, y: 50, eatenCounter: 0}
let rabbitsEaten = 0
new TWEEN.Tween(fox, group)
.to(_rabbitValues, duration)
.dynamic(dynamic)
.onUpdate(function (object) {
rabbitsEaten = Math.floor(object.eatenCounter)
if (rabbitsEaten > 0) {
// A dead rabbit stops moving.
rabbitTweens[rabbitsEaten - 1].stop()
rabbits[rabbitsEaten - 1].alive = false
}
})
.start()
animate()
function animate(time) {
group.update(time)
const stillRunning = !group.allStopped()
// draw background
context.fillStyle = 'rgb(240,250,240)'
context.fillRect(0, 0, width, height)
for (const rabbit of rabbits) drawRabbit(context, rabbit.x, rabbit.y, rabbit.color, rabbit.alive ? 1 : 0.1)
drawFox(context, fox.x, fox.y, 'rgb(200,80,80)')
if (stillRunning) requestAnimationFrame(animate)
else console.log('Done with animation, stopped rendering.')
}
}
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max + 1))
}
</script>
</body>
</html>