4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Victor Ribeiro
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Retro Synthwave
2 |
3 | 
4 |
5 | [live version](https://victorribeiro.com/random4)
6 | [alternative link](https://victorqribeiro.github.io/retroSynthwave/)
7 |
8 | ## About
9 |
10 | This is a project I've been working on for a while, one hour or less at at time. It involves a simple equation for calculating a perspective of a given point `FOV / (FOV + z)` Where FOV is the Field of View and z is the z coordinate of a given 3D point (x, y, z).
11 |
12 | ### Can I use it on my videos?
13 | Yes, set up a record screen software and capture away.
14 | E.g.: [https://www.youtube.com/watch?v=ztv--KzSGDc](https://www.youtube.com/watch?v=ztv--KzSGDc)
15 |
16 | ### Can I use it as a backgroud?
17 | Yes, press F11 to enter full screen mode, reload the page and take a screen shot.
18 |
19 | ### Can this turned into a endless GIF?
20 | Yes, comment out the part where I reset the y position last row of points after they are gone, capture the frames and you're all set.
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Victor Ribeiro
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/js/main.js:
--------------------------------------------------------------------------------
1 | let canvas, c, w, h, u, points, offset, spacing, gradient
2 |
3 | function init() {
4 | canvas = document.createElement('canvas')
5 | canvas.width = w = innerWidth
6 | canvas.height = h = innerHeight
7 | c = canvas.getContext('2d')
8 | c.translate(w / 2, h / 2)
9 | document.body.appendChild(canvas)
10 | spacing = 40
11 | points = Array(30).fill(0).map(_ => Array(60).fill(0))
12 | for (let i = 0; i < points.length; i++) {
13 | for (let j = 0; j < points[0].length; j++) {
14 | const dist = Math.abs(j - points[0].length / 2)
15 | points[i][j] = {
16 | x: j * spacing,
17 | y: Math.random() * -(dist*dist) + 30,
18 | z: -i * 10
19 | }
20 | }
21 | }
22 | offset = points[0].length * spacing / 2
23 | gradient = c.createLinearGradient(0, -150, 0, 100);
24 | gradient.addColorStop(0, 'gold')
25 | gradient.addColorStop(1, 'rgb(200, 0, 100)')
26 | update(0)
27 | }
28 |
29 | function update(time) {
30 | for (let i = 0; i < points.length; i++) {
31 | let gone = false
32 | for (let j = 0; j < points[0].length; j++) {
33 | points[i][j].z -= 0.5
34 | if (points[i][j].z < -300) {
35 | gone = true
36 | }
37 | }
38 | if (gone) {
39 | let arr = points.pop()
40 | for(let k = 0; k < arr.length; k++) {
41 | const dist = Math.abs(k - arr.length / 2)
42 | arr[k].z = 0
43 | arr[k].y = Math.random() * -(dist*dist) + 30
44 | }
45 | points.unshift( arr )
46 | }
47 | }
48 | show()
49 | u = requestAnimationFrame(update)
50 | }
51 |
52 | function show() {
53 | c.clearRect(-w / 2, -h / 2, w, h)
54 | c.beginPath()
55 | c.arc(0, 0, 200, 0, Math.PI * 2)
56 | c.closePath()
57 | c.shadowColor = "orange"
58 | c.shadowBlur = 100
59 | c.fillStyle = gradient
60 | c.fill()
61 | c.shadowBlur = 0
62 | for (let i = 0; i < points.length - 1; i++) {
63 | for (let j = 0; j < points[0].length - 1; j++) {
64 | const size = 300 / (300 + points[i][j].z)
65 | const nextSize = 300 / (300 + points[i+1][j].z)
66 | c.beginPath()
67 | c.moveTo((points[i][j].x - offset) * size, points[i][j].y * size)
68 | c.lineTo((points[i][j+1].x - offset) * size, points[i][j+1].y * size)
69 | c.lineTo((points[i+1][j+1].x - offset) * nextSize, points[i+1][j+1].y * nextSize)
70 | c.lineTo((points[i+1][j].x - offset) * nextSize, points[i+1][j].y * nextSize)
71 | c.closePath()
72 | const color = 300 + points[i][j].z
73 | c.fillStyle = `rgba(0, 0, 0, ${-points[i][j].z / 100})`
74 | c.strokeStyle = `rgba(${250 - color}, 0, ${50 + color}, ${1 - color / 300})`
75 | c.fill()
76 | c.stroke()
77 | }
78 | }
79 | }
80 |
81 | init()
82 |
--------------------------------------------------------------------------------