├── animation
├── spiral
│ ├── .gitignore
│ ├── render.py
│ ├── spiral.html
│ ├── tutorial.html
│ └── spiral-with-cursor.html
├── repomen.jpg
├── simple.html
└── bounce
│ ├── bounce.html
│ └── bounce-guide.html
├── spicy
├── game.css
├── game.html
└── game.js
├── big-picture
├── README.md
├── pruebas
├── finder-old.py
├── bigpicture.py
└── mexico-flag.py
├── vectors
├── cat.jpg
├── beads.jpg
├── curved-lines.html
├── google-logo.html
├── mask.html
├── pixels.html
├── polygon-editable.html
└── resize.html
├── composition
├── 1.jpg
├── 2.jpg
└── composition-preliminar.html
├── graphics
├── korean.png
├── background.jpg
└── mask-alpha.html
├── tint-image
├── tint.png
└── tint-png.html
├── mapa-cuadros
├── ave.jpg
├── index.html
└── with-images.html
├── filtro-canvas
├── imagen.jpg
├── pajarini.jpg
├── filtros.html
└── filtros2.html
├── rotate-image
├── luigi.jpeg
└── rotate.html
├── blanco-y-negro
├── sample.jpg
└── blanco-y-negro.html
├── fondo-movimiento
├── imagen.jpg
└── fondo-mov.html
├── circulos-de-colores
├── sample.png
├── README.md
└── index.html
├── circunferencia
├── arco-sample.png
├── poly-sample.png
├── README.md
├── arco.html
├── poly.html
├── orbita.html
├── click-circle.html
├── stars.html
└── progress.html
├── tutorials
├── green-screen
│ ├── target1.jpeg
│ ├── background.jpeg
│ ├── preview.html
│ └── green-screen.html
└── squares-and-triangles-spinning
│ └── preview.html
├── README.md
├── thumbnail-optim
└── doit.py
├── template-canvas.html
├── estrellas
└── estrellas.html
├── matrix-canvas
└── matrix.html
├── interactive
├── video-progress.html
├── mover-objetos.html
└── polygon-editable.html
├── cuadros
├── rounded-draft.html
└── rounded.html
├── paint
└── drawing.html
├── lineas
├── euclides-guide.html
└── euclides.html
├── 3d
└── sphere.html
├── snake
└── snake.html
├── foto-stat
└── photos.py
├── lluvia-azul
└── index.html
└── espacio-y-planetas
└── index.html
/animation/spiral/.gitignore:
--------------------------------------------------------------------------------
1 | env/*
2 |
--------------------------------------------------------------------------------
/spicy/game.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | }
--------------------------------------------------------------------------------
/big-picture/README.md:
--------------------------------------------------------------------------------
1 | Takes a list of many many pictures and join them as one.
2 |
--------------------------------------------------------------------------------
/vectors/cat.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/vectors/cat.jpg
--------------------------------------------------------------------------------
/composition/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/composition/1.jpg
--------------------------------------------------------------------------------
/composition/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/composition/2.jpg
--------------------------------------------------------------------------------
/graphics/korean.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/graphics/korean.png
--------------------------------------------------------------------------------
/tint-image/tint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/tint-image/tint.png
--------------------------------------------------------------------------------
/vectors/beads.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/vectors/beads.jpg
--------------------------------------------------------------------------------
/animation/repomen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/animation/repomen.jpg
--------------------------------------------------------------------------------
/mapa-cuadros/ave.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/mapa-cuadros/ave.jpg
--------------------------------------------------------------------------------
/filtro-canvas/imagen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/filtro-canvas/imagen.jpg
--------------------------------------------------------------------------------
/graphics/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/graphics/background.jpg
--------------------------------------------------------------------------------
/rotate-image/luigi.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/rotate-image/luigi.jpeg
--------------------------------------------------------------------------------
/blanco-y-negro/sample.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/blanco-y-negro/sample.jpg
--------------------------------------------------------------------------------
/filtro-canvas/pajarini.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/filtro-canvas/pajarini.jpg
--------------------------------------------------------------------------------
/fondo-movimiento/imagen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/fondo-movimiento/imagen.jpg
--------------------------------------------------------------------------------
/circulos-de-colores/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/circulos-de-colores/sample.png
--------------------------------------------------------------------------------
/circunferencia/arco-sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/circunferencia/arco-sample.png
--------------------------------------------------------------------------------
/circunferencia/poly-sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/circunferencia/poly-sample.png
--------------------------------------------------------------------------------
/tutorials/green-screen/target1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/tutorials/green-screen/target1.jpeg
--------------------------------------------------------------------------------
/tutorials/green-screen/background.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gamikun/cosas-raras/HEAD/tutorials/green-screen/background.jpeg
--------------------------------------------------------------------------------
/circulos-de-colores/README.md:
--------------------------------------------------------------------------------
1 | This is how it looks...
2 | 
3 |
--------------------------------------------------------------------------------
/big-picture/pruebas:
--------------------------------------------------------------------------------
1 | 1, 2, 5
2 | 5, 7, 10
3 | 2, 27, 354
4 |
5 | Modo progresivo
6 | 3, 4.50, 7.5
7 | 2.5, 15.75, 180.75 = 66.03
8 |
9 | Modo global
10 | 2.6, 12, 123 = 45.86
--------------------------------------------------------------------------------
/circunferencia/README.md:
--------------------------------------------------------------------------------
1 | ## arco.html
2 | 
3 |
4 | ## poly.html
5 | 
6 |
--------------------------------------------------------------------------------
/spicy/game.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Spicyx
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # cosas-raras
2 | Some experiments I make, most of them in HTML5 canvas.
3 |
4 | # Lista de experimentos
5 |
6 | ## Spiral dots
7 | Many dots falling in spiral to the center of thescreen.
8 | * Running: https://github.com/gamikun/cosas-raras/blob/master/animation/spiral
9 | * Code: https://gamikun.github.io/cosas-raras/animation/spiral/spiral.html
10 |
--------------------------------------------------------------------------------
/thumbnail-optim/doit.py:
--------------------------------------------------------------------------------
1 | import os
2 | import subprocess as sp
3 |
4 |
5 | path = '/Users/gama/Pictures/Fototeca.photoslibrary/Thumbnails/2015/08'
6 | counter = 0
7 |
8 | for root, dirs, files in os.walk(path):
9 | for file in files:
10 | fname = os.path.join(root, file)
11 | if file.endswith('.jpg'):
12 | sp.call(['jpegoptim', '-m', '85', fname])
13 |
14 | counter += 1
15 |
16 | print("found {} files".format(counter))
--------------------------------------------------------------------------------
/template-canvas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | You're gonna carry that wheight!
5 |
15 |
16 |
17 |
18 |
19 |
24 |
--------------------------------------------------------------------------------
/animation/simple.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
26 |
--------------------------------------------------------------------------------
/vectors/curved-lines.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
14 |
34 |
35 |
--------------------------------------------------------------------------------
/fondo-movimiento/fondo-mov.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mi fondo se mueve!
5 |
14 |
27 |
28 |
29 |
30 | ¡El fondo se mueve!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/filtro-canvas/filtros.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Filtros en CANVAS
5 |
6 |
7 |
8 |
9 |
27 |
28 |
--------------------------------------------------------------------------------
/circunferencia/arco.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Arco
5 |
8 |
9 |
10 |
11 |
12 |
13 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/circunferencia/poly.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Poly
5 |
9 |
10 |
11 |
12 |
13 |
14 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/graphics/mask-alpha.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Alpha Mask
5 |
9 |
10 |
11 |
12 |
13 |
14 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/circunferencia/orbita.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Órbita
5 |
12 |
13 |
14 |
15 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/mapa-cuadros/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mapa de Cuadros
5 |
6 |
7 |
8 |
44 |
--------------------------------------------------------------------------------
/circunferencia/click-circle.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Click on circles
5 |
6 |
10 |
11 |
12 |
13 |
14 |
54 |
55 |
--------------------------------------------------------------------------------
/vectors/google-logo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
40 |
41 |
--------------------------------------------------------------------------------
/tint-image/tint-png.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PNG
5 |
10 |
11 |
12 |
13 |
14 |
44 |
45 |
--------------------------------------------------------------------------------
/vectors/mask.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Masked Cat
5 |
10 |
11 |
12 |
13 |
14 |
56 |
57 |
--------------------------------------------------------------------------------
/tutorials/green-screen/preview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Green screen
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/animation/bounce/bounce.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bounce
5 |
9 |
10 |
11 |
12 |
54 |
55 |
--------------------------------------------------------------------------------
/vectors/pixels.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
14 |
54 |
55 |
--------------------------------------------------------------------------------
/circunferencia/stars.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Stars from circle
5 |
15 |
16 |
17 |
18 |
19 |
77 |
--------------------------------------------------------------------------------
/mapa-cuadros/with-images.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mapa de Cuadros
5 |
6 |
7 |
8 |
58 |
--------------------------------------------------------------------------------
/tutorials/green-screen/green-screen.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Green Screen
5 |
20 |
21 |
22 |
23 |
24 |

25 |
27 |
28 |
29 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/estrellas/estrellas.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Estrellas
5 |
6 |
7 |
8 |
62 |
63 |
--------------------------------------------------------------------------------
/animation/bounce/bounce-guide.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bounce
5 |
12 |
13 |
14 |
15 |
16 |
17 |
60 |
61 |
--------------------------------------------------------------------------------
/matrix-canvas/matrix.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
60 |
61 |
--------------------------------------------------------------------------------
/interactive/video-progress.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Video progress
5 |
10 |
11 |
12 |
13 |
14 |
15 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/cuadros/rounded-draft.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Rounded Corners
4 |
7 |
8 |
9 |
10 |
11 |
12 |
61 |
62 |
--------------------------------------------------------------------------------
/cuadros/rounded.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Rounded Corners
5 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
64 |
65 |
--------------------------------------------------------------------------------
/blanco-y-negro/blanco-y-negro.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Black & White
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/animation/spiral/render.py:
--------------------------------------------------------------------------------
1 | from wand.drawing import Drawing
2 | from wand.image import Image
3 | from wand.color import Color
4 | from random import Random
5 | from binascii import hexlify
6 | from struct import pack
7 | import subprocess
8 | import math
9 |
10 | ffmpeg = subprocess.Popen([
11 | 'ffmpeg',
12 | '-f', 'image2pipe',
13 | '-framerate', '60',
14 | '-probesize', '20M',
15 | '-vcodec', 'bmp',
16 | '-y',
17 | '-i', '-',
18 | 'salida.mp4'
19 | ], stdin=subprocess.PIPE)
20 |
21 | W = 1920.0
22 | H = 1080.0
23 | CX = W / 2
24 | CY = H / 2
25 |
26 | random = Random()
27 |
28 | class Dot:
29 | def __init__(self):
30 | self.r = random.random() * W * 2
31 | self.x = 0
32 | self.y = 0
33 | self.speed = 1
34 | self.rotation = random.random() * math.pi * 2
35 | self.rotation_speed = random.random() * 0.04
36 | #self.color = hexlify(pack('>I', random.randrange(0, 0xFFFFFF)))
37 | self.color = Color('#{}'.format(
38 | hexlify(pack('>I', random.randrange(0, 0xFFFFFF))[1:]).decode()
39 | ))
40 |
41 | dots = [Dot() for x in range(10000)]
42 |
43 | def compute():
44 | for dot in dots:
45 | dot.r -= dot.speed
46 | dot.rotation += dot.rotation_speed
47 |
48 | if dot.r < 0:
49 | dot.r = random.random() * (W / 2) + W / 2
50 |
51 | dot.x = dot.r * math.cos(dot.rotation) + CX
52 | dot.y = dot.r * math.sin(dot.rotation) + CY
53 |
54 | def draw_all(draw):
55 | draw.fill_color = Color('#222222')
56 | draw.rectangle(left=0, top=0, right=W, bottom=H)
57 | for dot in dots:
58 | draw.fill_color = dot.color
59 | draw.circle(
60 | (dot.x, dot.y),
61 | (dot.x + (dot.r * 0.03 + 1), dot.y + (dot.r * 0.03 + 1))
62 | )
63 |
64 | seconds = 10
65 |
66 | with Image(width=int(W), height=int(H), background='#222222') as image:
67 | for index in range(60 * seconds):
68 | with Drawing() as draw:
69 | compute()
70 | draw_all(draw)
71 | draw(image)
72 | image.format = 'bmp'
73 | #image.save(filename="hola.png")
74 | image.save(file=ffmpeg.stdin)
75 |
76 |
--------------------------------------------------------------------------------
/circunferencia/progress.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Progreso circular
5 |
14 |
15 |
16 |
17 |
18 |
19 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/interactive/mover-objetos.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
72 |
73 |
--------------------------------------------------------------------------------
/composition/composition-preliminar.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Composition
5 |
6 |
7 |
8 |
9 |
10 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/animation/spiral/spiral.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Espirales
5 |
15 |
16 |
17 |
18 |
85 |
86 |
--------------------------------------------------------------------------------
/circulos-de-colores/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
87 |
88 |
--------------------------------------------------------------------------------
/vectors/polygon-editable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Polígon editable
5 |
10 |
11 |
12 |
13 |
84 |
85 |
--------------------------------------------------------------------------------
/interactive/polygon-editable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Polígon editable
5 |
10 |
11 |
12 |
13 |
84 |
85 |
--------------------------------------------------------------------------------
/paint/drawing.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Mi paint
5 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/animation/spiral/tutorial.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Spiral
5 |
15 |
16 |
17 |
18 |
86 |
87 |
--------------------------------------------------------------------------------
/animation/spiral/spiral-with-cursor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Spiral
5 |
15 |
16 |
17 |
18 |
91 |
92 |
--------------------------------------------------------------------------------
/big-picture/finder-old.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf8 -*-
2 | #
3 | # Encontrar fotos y juntarla en una sola.
4 | # Author: Gamaliel Espinoza Macedo
5 | # Date: March 24th, 2016
6 | #
7 | from __future__ import division
8 | import os
9 | import math
10 | import re
11 | from PIL import Image
12 | from PIL import ImageDraw
13 | from PIL import ImageFont
14 |
15 |
16 | path = '/Users/gama/Pictures/Fototeca.photoslibrary/Thumbnails'
17 |
18 | width = 1920
19 | height = 1080
20 | perrow = 205
21 | limit = 100000
22 |
23 | canvas = Image.new('RGB', (width, height))
24 |
25 | iwidth = int(math.ceil(width / perrow))
26 | iheight = iwidth
27 |
28 | print("width: {}".format(iwidth))
29 |
30 | counter = 0
31 | colors = []
32 | allfiles = []
33 | images = []
34 |
35 | # encontrar todos los archivos
36 | if not os.path.isfile('./db.data'):
37 | with open('./db.data', 'w+') as fp:
38 | for root, dirs, files in os.walk(path):
39 | for file in files:
40 | fname = os.path.join(root, file)
41 | if file.endswith('.jpg') and not file.endswith('_1024.jpg')\
42 | and not file.startswith('thumb_'):
43 | fp.write(fname + '\n')
44 |
45 |
46 | dbfile = open('./db.data', 'r')
47 | averages = {}
48 | colorines = {}
49 | saturation = {}
50 |
51 | for fname in dbfile:
52 | with open(fname[:-1], 'rb') as fp:
53 | img = Image.open(fp)
54 | image = img.resize((iwidth, int(iheight)),
55 | resample=Image.NEAREST)
56 | data = image.getdata()
57 |
58 | average = [0, 0, 0]
59 | first = True
60 | maxvalue = 0
61 | color_indexer = {}
62 | for color in data:
63 | r, g, b = color
64 | if color not in color_indexer:
65 | color_indexer[color] = 1
66 | else:
67 | color_indexer[color] += 1
68 | if first:
69 | average[0] = r
70 | average[1] = g
71 | average[2] = g
72 | first = False
73 | else:
74 | average[0] = (average[0] + r) / 2
75 | average[1] = (average[1] + g) / 2
76 | average[2] = (average[2] + b) / 2
77 |
78 | avgsum = reduce(lambda x, y: x + y, average)
79 | averages[counter] = avgsum / len(average)
80 | colorines[counter] = max(color_indexer)
81 | images.append(image)
82 |
83 | if counter == limit:
84 | break
85 |
86 | counter += 1
87 |
88 | # method types: complex
89 | # darkness
90 | # saturation
91 | method = 'darkness'
92 |
93 | if method == 'complex':
94 | # Ordernar por cantidad de colores
95 | sorted_indexes = sorted(colorines, key=lambda x: colorines[x])
96 | elif method == 'darkness':
97 | # Ordernar por averages RGB
98 | sorted_indexes = sorted(averages, key=lambda x: averages[x])
99 |
100 | # Hacer el despliegue
101 | index = 0
102 | for im_index in sorted_indexes:
103 | im = images[im_index]
104 |
105 | raw_index = index / perrow
106 | flr_index = math.floor(raw_index)
107 | y = int(flr_index * iheight)
108 | x = int((raw_index - flr_index) * width)
109 |
110 | canvas.paste(im, (x, y))
111 |
112 | index += 1
113 |
114 | print("files found: {}".format(counter))
115 |
116 | canvas.save('/Users/gama/Desktop/global.jpeg')
117 |
--------------------------------------------------------------------------------
/big-picture/bigpicture.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf8 -*-
2 | #
3 | # Encontrar fotos y juntarla en una sola.
4 | # Author: Gamaliel Espinoza Macedo
5 | # Date: March 24th, 2016
6 | #
7 | from __future__ import division
8 | import os
9 | import math
10 | import re
11 | from PIL import Image
12 | from PIL import ImageDraw
13 | from PIL import ImageFont
14 |
15 |
16 | path = '/Users/gama/Pictures/Fototeca.photoslibrary/Thumbnails'
17 |
18 | width = 3840
19 | height = 2160
20 | perrow = 219
21 | limit = 50000
22 |
23 | canvas = Image.new('RGB', (width, height))
24 |
25 | iwidth = int(math.ceil(width / perrow))
26 | iheight = iwidth
27 |
28 | print("width: {}".format(iwidth))
29 |
30 | counter = 0
31 | colors = []
32 | allfiles = []
33 | images = []
34 |
35 | # encontrar todos los archivos
36 | if not os.path.isfile('./db.data'):
37 | with open('./db.data', 'w+') as fp:
38 | for root, dirs, files in os.walk(path):
39 | for file in files:
40 | fname = os.path.join(root, file)
41 | if file.endswith('.jpg') and not file.endswith('_1024.jpg'):
42 | fp.write(fname + '\n')
43 |
44 |
45 | dbfile = open('./db.data', 'r')
46 | averages = {}
47 | colorines = {}
48 | saturation = {}
49 |
50 | for fname in dbfile:
51 | with open(fname[:-1], 'rb') as fp:
52 | img = Image.open(fp)
53 | image = img.resize((iwidth, int(iheight)),
54 | resample=Image.NEAREST)
55 | data = image.getdata()
56 |
57 | average = [0, 0, 0]
58 | maxvalue = 0
59 | avg_r = []
60 | avg_g = []
61 | avg_b = []
62 | color_indexer = {}
63 | for color in data:
64 | r, g, b = color
65 | if color not in color_indexer:
66 | color_indexer[color] = 1
67 | else:
68 | color_indexer[color] += 1
69 |
70 | avg_r.append(r)
71 | avg_g.append(g)
72 | avg_b.append(b)
73 |
74 | avgsum = (sum(avg_r) / len(avg_r) \
75 | + sum(avg_g) / len(avg_g) \
76 | + sum(avg_b) / len(avg_b)
77 | ) / 3
78 | averages[counter] = avgsum
79 | colorines[counter] = max(color_indexer)
80 |
81 | images.append(image)
82 |
83 | if counter == limit:
84 | break
85 |
86 | counter += 1
87 |
88 | # method types: complex
89 | # darkness
90 | # saturation
91 | method = 'darkness'
92 |
93 | if method == 'complex':
94 | # Ordernar por cantidad de colores
95 | sorted_indexes = sorted(colorines, key=lambda x: colorines[x])
96 | elif method == 'darkness':
97 | # Ordernar por averages RGB
98 | sorted_indexes = sorted(averages, key=lambda x: averages[x])
99 |
100 | # Hacer el despliegue
101 | index = 0
102 | for im_index in sorted_indexes:
103 | im = images[im_index]
104 |
105 | raw_index = index / perrow
106 | flr_index = math.floor(raw_index)
107 | y = int(flr_index * iheight)
108 | x = int((raw_index - flr_index) * width)
109 |
110 | canvas.paste(im, (x, y))
111 |
112 | index += 1
113 |
114 | print("files found: {}".format(counter))
115 |
116 | canvas.save('/Users/gama/Desktop/global.jpeg')
117 |
--------------------------------------------------------------------------------
/lineas/euclides-guide.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Lineas
5 |
22 |
23 |
24 |
25 |
100 |
101 |
102 |
107 |
108 |
113 |
114 |
115 |
Radio de puntos
116 |
118 |
119 |
120 |
121 |
Ancho de línea
122 |
124 |
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/lineas/euclides.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Lines
5 |
22 |
23 |
24 |
25 |
109 |
110 |
111 |
116 |
117 |
122 |
123 |
124 |
Radios de puntos
125 |
127 |
128 |
129 |
130 |
Line width
131 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/rotate-image/rotate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Rotate
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/vectors/resize.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Resize Images
5 |
8 |
9 |
10 |
11 |
12 |
13 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/filtro-canvas/filtros2.html:
--------------------------------------------------------------------------------
1 |
74 |
75 |
76 |
Blanco y Negro:
77 |
78 |
--------------------------------------------------------------------------------
/big-picture/mexico-flag.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf8 -*-
2 | #
3 | # Bandera de México con imágenes
4 | # Author: Gamaliel Espinoza Macedo
5 | # Date: 24-feb-2017
6 | #
7 | from __future__ import division
8 | import os
9 | import math
10 | import re
11 | import sys
12 | from PIL import Image
13 | from PIL import ImageDraw
14 | from PIL import ImageFont
15 |
16 |
17 | path = '/directorio/para/buscar/imagenes'
18 | save_to = '/donde/se/guardara/la/imagen.jpg'
19 |
20 | width = 1280
21 | cwidth = 1280 / 3
22 | height = 600
23 | perrow = 17
24 | limit = 30000
25 |
26 | canvas = Image.new('RGB', (width, height))
27 |
28 | iwidth = int(math.ceil(cwidth / perrow))
29 | max_per_block = perrow * height / iwidth
30 | iheight = iwidth
31 |
32 | print("iniciando...")
33 |
34 | counter = 0
35 | green_images = []
36 | red_images = []
37 | white_images = []
38 |
39 | re_file = re.compile(r'_mini_[a-f0-9]{4}\.jpg$')
40 |
41 | # encontrar todos los archivos
42 | if not os.path.isfile('./db.data'):
43 | file_counter = 0
44 | with open('./db.data', 'w+') as fp:
45 | for root, dirs, files in os.walk(path):
46 | for file in files:
47 | fname = os.path.join(root, file)
48 | if re_file.search(file):
49 | fp.write(fname + '\n')
50 | file_counter += 1
51 | print("files found: {}".format(file_counter))
52 |
53 | dbfile = open('./db.data', 'r')
54 |
55 | total_green = 0
56 | total_red = 0
57 | total_white = 0
58 |
59 | for fname in dbfile:
60 | with open(fname[:-1], 'rb') as fp:
61 | img = Image.open(fp)
62 | total_pixels = iwidth * iheight
63 | green_pixels = 0
64 | white_pixels = 0
65 | red_pixels = 0
66 |
67 | image = img.resize((iwidth, int(iheight)),
68 | resample=Image.NEAREST)
69 | data = image.getdata()
70 |
71 | for color in data:
72 | r, g, b = color
73 |
74 | if (g > (b + 10) and g > (r + 10)):
75 | green_pixels += 1
76 |
77 | elif (r > (b + 55) and r > (g + 55)):
78 | red_pixels += 1
79 |
80 | elif r > 190 and g > 190 and b > 190:
81 | white_pixels += 1
82 |
83 | if green_pixels > red_pixels and green_pixels > white_pixels:
84 | if green_pixels > total_pixels / 3:
85 | if total_green <= max_per_block:
86 | green_images.append(image)
87 | total_green += 1
88 |
89 | elif red_pixels > green_pixels and red_pixels > white_pixels:
90 | if red_pixels > total_pixels / 3:
91 | if total_red <= max_per_block:
92 | red_images.append(image)
93 | total_red += 1
94 |
95 | elif white_pixels > red_pixels and white_pixels > green_pixels:
96 | if white_pixels > total_pixels / 4:
97 | if total_white <= max_per_block:
98 | white_images.append(image)
99 | total_white += 1
100 |
101 |
102 | if counter == limit:
103 | break
104 |
105 | if not (counter % 350):
106 | print(counter)
107 |
108 | counter += 1
109 |
110 | print("images found: {}".format(len(red_images) + len(green_images)))
111 |
112 | def putgroup(group, offset=0):
113 | index = 0
114 | for im in group:
115 | if not im:
116 | continue
117 |
118 | raw_index = index / perrow
119 | flr_index = math.floor(raw_index)
120 | y = int(flr_index * iheight)
121 | x = int((raw_index - flr_index) * cwidth)
122 |
123 | canvas.paste(im, (int(x + offset), y))
124 |
125 | index += 1
126 |
127 | # Hacer el despliegue
128 | putgroup(green_images, offset=0)
129 | putgroup(white_images, offset=cwidth)
130 | putgroup(red_images, offset=cwidth * 2)
131 |
132 | print("files found: {}".format(counter))
133 | canvas.save(save_to)
134 |
135 | print("listo :D")
--------------------------------------------------------------------------------
/3d/sphere.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
150 |
151 |
--------------------------------------------------------------------------------
/snake/snake.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Snake
5 |
20 |
21 |
22 |
23 |
24 |
25 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/tutorials/squares-and-triangles-spinning/preview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Rotating dots
5 |
6 |
20 |
21 |
22 |
23 |
24 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/foto-stat/photos.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function, division
2 | from argparse import ArgumentParser
3 | from StringIO import StringIO
4 | from struct import unpack
5 | import sqlite3
6 | import sys
7 |
8 |
9 | parser = ArgumentParser(
10 | description='Generate stats from a Apple Photos Db'
11 | )
12 | parser.add_argument('entity')
13 | parser.add_argument('action')
14 | parser.add_argument('-d', dest='db', type=str)
15 | parser.add_argument('-i', dest='ignore_nameless',
16 | default=False, action='store_const',
17 | const=True)
18 | parser.add_argument('-l', dest='limit', type=int)
19 |
20 |
21 | args = parser.parse_args()
22 |
23 | db = sqlite3.connect(args.db)
24 |
25 |
26 | if args.entity == 'face':
27 | if args.action == 'top':
28 | cursor = db.cursor()
29 | query = """
30 | select faceCount, name
31 | from RKPerson
32 | order by faceCount desc
33 | """
34 |
35 | if args.limit:
36 | query += ' limit {}'.format(args.limit)
37 |
38 | cursor.execute(query)
39 |
40 | for person in cursor:
41 | count, name = person
42 |
43 | if name and count:
44 | print('{} {}'.format(count, name.encode('utf8')))
45 |
46 | elif args.entity == 'photo':
47 | if args.action == 'stats':
48 | try:
49 | from bplist import BPListReader
50 |
51 | counter = 0
52 | allsum = 0
53 | avg = 0
54 | total_pixels = 0
55 | pixel_unit = 'mpx'
56 | printed_cm = 15.24
57 | printed_unit = 'cm'
58 | size_printed = 0
59 | lens_models = {}
60 | total_exposure = 0
61 |
62 | cursor = db.cursor()
63 | cursor.execute("""
64 | select note.value
65 | from RKMaster as master
66 | inner join RKMaster_dataNote as note
67 | on master.modelId = note.attachedToId
68 | limit 15000
69 | -- where master.fileName = 'IMG_5886.JPG'
70 | """)
71 |
72 | for row in cursor:
73 | value, = row
74 | reader = BPListReader(value)
75 | datos = reader.parse()
76 |
77 | if not datos:
78 | continue
79 |
80 | exif = datos.get('{Exif}')
81 |
82 | if not exif:
83 | continue
84 |
85 | if 'FNumber' in exif:
86 | _, fvalue = exif.get('FNumber')
87 | counter += 1
88 | allsum += fvalue
89 |
90 | if 'PixelXDimension' in exif:
91 | w = exif['PixelXDimension']
92 | h = exif['PixelYDimension']
93 | total_pixels += w * h
94 |
95 | if 'LensModel' in exif:
96 | if exif['LensModel'] not in lens_models:
97 | lens_models[exif['LensModel']] = 1
98 | else:
99 | lens_models[exif['LensModel']] += 1
100 |
101 | if 'ExposureTime' in exif:
102 | num, den = exif['ExposureTime']
103 | if den != 0:
104 | total_exposure += 1 / num / den
105 |
106 |
107 | print(exif)
108 | raw_input()
109 |
110 | if counter > 0:
111 | avg = allsum / counter
112 |
113 | if total_pixels >= 1000000000000:
114 | total_mpx = total_pixels / 1000 / 1000 / 1000 / 1000
115 | pixel_unit = 'tpx'
116 |
117 | elif total_pixels >= 1000000000:
118 | total_mpx = total_pixels / 1000 / 1000 / 1000
119 | pixel_unit = 'gpx'
120 |
121 | else:
122 | total_mpx = total_pixels / 1000 / 1000
123 |
124 | total_printed = printed_cm * counter
125 |
126 | if total_printed > 100000:
127 | size_printed = total_printed / 100000
128 | printed_unit = 'km'
129 |
130 | elif total_printed > 100:
131 | size_printed = total_printed / 100
132 | printed_unit = 'm'
133 |
134 | else:
135 | size_printed = total_printed
136 |
137 | print("total: {}".format(counter))
138 | print("exposure: {} seconds".format(total_exposure))
139 | print("average: f/{:.01f}".format(avg))
140 | print("total pixels: {:.02f} {}".format(total_mpx, pixel_unit))
141 | print("your photo printed in 6-inch: {:.01f} {}".format(size_printed, printed_unit))
142 |
143 | print('\nCAMERA LENSES\n--------------')
144 | for lens in lens_models:
145 | print("{:>5} {}".format(lens_models[lens], lens))
146 |
147 | except ImportError:
148 | print("bplist module is not installed", file=sys.stderr)
149 | print("to install use:", file=sys.stderr)
150 | sys.exit(1)
151 |
152 |
153 |
--------------------------------------------------------------------------------
/lluvia-azul/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Círculos Azules
5 |
6 |
7 |
8 |
161 |
162 |
--------------------------------------------------------------------------------
/espacio-y-planetas/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Espacio
5 |
6 |
7 |
8 |
214 |
215 |
--------------------------------------------------------------------------------
/spicy/game.js:
--------------------------------------------------------------------------------
1 | var STROKE_STYLE = '#fff solid';
2 | var KEY_SPACE = 32;
3 | var KEY_B = 66;
4 | var GROW_RATE = 1.8;
5 | var WPN_BOMB = 1;
6 |
7 | var keymap = [];
8 | var mousemap = [false, false, false];
9 | var shoots = [];
10 | var enemies = [];
11 | var lvlups = [];
12 |
13 | var levelsexp = [
14 | 0, 0,
15 | 150, // level 2
16 | 400, // level 3
17 | 700, // level 4
18 | ];
19 |
20 | var TICK = 25;
21 | var ship = {
22 | loc: {x: 0, y: 0},
23 | killed: false,
24 | level: 1,
25 | exp: 0,
26 | shield: {
27 | capacity: 100,
28 | hp: 100,
29 | radio: 30
30 | }
31 | };
32 |
33 | var Shoot = function() {
34 | this.x = 0;
35 | this.y = 0;
36 | };
37 |
38 | var currentWeapon = {
39 | shootRate: 500, // milliseconds
40 | timeToShoot: 0,
41 | ready: true,
42 | damage: 20,
43 | level: 1
44 | };
45 |
46 | var currentBomb = {
47 | damage: 300,
48 | radio: 15,
49 | shootRate: 2000,
50 | timeToShoot: 0,
51 | ammo: 10
52 | };
53 |
54 | function timeit() {
55 | var shoot, enemy;
56 | var cx = canvas.width / 2;
57 | var by = canvas.height - 100;
58 |
59 | for (var i = 0; i < enemies.length; i++) {
60 | enemy = enemies[i];
61 | if (enemy.dead) {
62 | continue;
63 | }
64 |
65 | enemy.loc.y += enemy.speed;
66 | if (enemy.loc.y > canvas.height) {
67 | enemy.loc.y = -enemy.size.h;
68 | enemy.hp = enemy.maxhp * GROW_RATE;
69 | enemy.beingShot = false;
70 | // enemies.splice(i, 1);
71 | continue;
72 | }
73 |
74 | // validte if it's coliding with shield
75 | if (false) {
76 |
77 | }
78 |
79 | // validate if it's colliding with ship
80 | if (!enemy.dead && ship.loc.y < (enemy.loc.y + enemy.size.h)
81 | && ship.loc.y > enemy.loc.y
82 | && ship.loc.x > enemy.loc.x
83 | && ship.loc.x < (enemy.loc.x + enemy.size.w)) {
84 | ship.killed = true;
85 | }
86 | }
87 |
88 | // Move the shoots
89 | var nextLevel = 0;
90 | for (var i = 0; i < shoots.length; i++) {
91 | shoot = shoots[i];
92 | shoot.loc.y -= shoot.speed;
93 | // check if the shoot is touching an enemy
94 | for (var j = 0; j < enemies.length; j++) {
95 | enemy = enemies[j];
96 | if (!enemy.dead && shoot.loc.y >= enemy.loc.y
97 | && shoot.loc.y <= (enemy.loc.y + enemy.size.h)
98 | && shoot.loc.x >= enemy.loc.x
99 | && shoot.loc.x <= (enemy.loc.x + enemy.size.w))
100 | {
101 | if (!shoot.fromEnemy) {
102 | if (shoot.type == WPN_BOMB) {
103 | if (shoot.dead) {
104 | shoots.splice(i, 1);
105 | // Search for affected enemies
106 | for (var i = 0; i < enemies.length; i++) {
107 | var enemy = enemies[i];
108 | var dtl = Math.hypot(
109 | shoot.loc.x - enemy.loc.x,
110 | shoot.loc.y - enemy.loc.y
111 | );
112 | if (dtl < shoot.expRadio) {
113 | console.log(shoot.damage);
114 | enemy.hp -= shoot.damage;
115 | enemy.beingShot = true;
116 | }
117 |
118 | if (enemy.hp <= 0) {
119 | ship.exp += enemy.exp;
120 | nextLevel = currentWeapon.level + 1;
121 | if (nextLevel < levelsexp.length) {
122 | if (ship.exp >= levelsexp[nextLevel]) {
123 | currentWeapon.level += 1;
124 | }
125 | }
126 | //enemy.loc.y = -enemy.size.h;
127 | enemy.dead = true;
128 | enemy.hp = enemy.maxhp * GROW_RATE;
129 | }
130 | }
131 | } else if (shoot.exploding) {
132 | shoot.radio += shoot.expSpeed;
133 | if (shoot.radio >= shoot.expRadio) {
134 | shoot.radio = shoot.expRadio;
135 | shoot.dead = true;
136 | }
137 | } else {
138 | shoot.speed = -1;
139 | shoot.exploding = true;
140 | }
141 | if (shoot.exploding === false) {
142 |
143 | }
144 | } else {
145 | shoots.splice(i, 1);
146 | enemy.hp -= shoot.damage;
147 | enemy.beingShot = true;
148 |
149 | if (enemy.hp <= 0) {
150 | ship.exp += enemy.exp;
151 | nextLevel = currentWeapon.level + 1;
152 | if (nextLevel < levelsexp.length) {
153 | if (ship.exp >= levelsexp[nextLevel]) {
154 | currentWeapon.level += 1;
155 | }
156 | }
157 | //enemies.splice(j, 1);
158 | //enemy.loc.y = -enemy.size.h;
159 | enemy.hp = enemy.maxhp * GROW_RATE;
160 | }
161 | }
162 |
163 |
164 | break;
165 | }
166 | }
167 | }
168 | }
169 |
170 | // Increment weapon transcurred time
171 | currentWeapon.timeToShoot -= TICK;
172 | currentBomb.timeToShoot -= TICK;
173 |
174 |
175 | if (currentBomb.timeToShoot <= 0 && currentBomb.ammo > 0) {
176 | if (keymap[KEY_B]) {
177 | currentBomb.ammo -= 1;
178 | currentBomb.timeToShoot = currentBomb.shootRate;
179 | shoots.push({
180 | type: WPN_BOMB,
181 | radio: currentBomb.radio,
182 | expSpeed: 15,
183 | expRadio: 100,
184 | exploding: false,
185 | died: false,
186 | loc: {x: ship.loc.x - 30, y: ship.loc.y},
187 | speed: 2,
188 | damage: currentBomb.damage
189 | });
190 | }
191 | }
192 |
193 | if (currentWeapon.timeToShoot <= 0) {
194 | currentWeapon.timeToShoot = currentWeapon.shootRate;
195 | currentWeapon.ready = true;
196 | if (keymap[KEY_SPACE] === true || mousemap[0] === true) {
197 | var nshoot;
198 |
199 | if (currentWeapon.level == 4) {
200 | shoots.push({
201 | length: 30,
202 | loc: {x: ship.loc.x - 30, y: ship.loc.y},
203 | speed: 5,
204 | damage: 20
205 | });
206 | shoots.push({
207 | length: 30,
208 | loc: {x: ship.loc.x + 30, y: ship.loc.y},
209 | speed: 5,
210 | damage: 20
211 | });
212 | shoots.push({
213 | length: 30,
214 | loc: {x: ship.loc.x - 15, y: ship.loc.y},
215 | speed: 5,
216 | damage: 20
217 | });
218 | shoots.push({
219 | length: 30,
220 | loc: {x: ship.loc.x + 15, y: ship.loc.y},
221 | speed: 5,
222 | damage: 20
223 | });
224 | }
225 | if (currentWeapon.level == 3) {
226 | shoots.push({
227 | length: 30,
228 | loc: {x: ship.loc.x - 20, y: ship.loc.y},
229 | speed: 5,
230 | damage: 20
231 | });
232 | shoots.push({
233 | length: 30,
234 | loc: {x: ship.loc.x + 20, y: ship.loc.y},
235 | speed: 5,
236 | damage: 20
237 | });
238 | shoots.push({
239 | length: 30,
240 | loc: {x: ship.loc.x, y: ship.loc.y},
241 | speed: 5,
242 | damage: 20
243 | });
244 | } else if (currentWeapon.level == 2) {
245 | shoots.push({
246 | length: 30,
247 | loc: {x: ship.loc.x - 15, y: ship.loc.y},
248 | speed: 5,
249 | damage: 20
250 | });
251 | shoots.push({
252 | length: 30,
253 | loc: {x: ship.loc.x + 15, y: ship.loc.y},
254 | speed: 5,
255 | damage: 20
256 | });
257 | } else {
258 | shoots.push({
259 | length: 30,
260 | loc: {x: ship.loc.x, y: ship.loc.y},
261 | speed: 5,
262 | damage: 20
263 | });
264 | }
265 |
266 | currentWeapon.ready = false;
267 | }
268 | }
269 |
270 | // enemy fire
271 | for (var i = 0; i < enemies.length; i++) {
272 | var enemy = enemies[i];
273 | if (enemy.dead) {
274 | continue;
275 | }
276 | enemy.weapon.timeToShoot -= TICK;
277 | if (enemy.weapon.timeToShoot <= 0) {
278 | shoots.push({
279 | length: 30,
280 | loc: {
281 | x: enemy.size.w / 2 + enemy.loc.x,
282 | y: enemy.loc.y + enemy.size.h
283 | },
284 | speed: -5,
285 | damage: 20,
286 | fromEnemy: true
287 | });
288 | enemy.weapon.timeToShoot = enemy.weapon.shootRate;
289 | }
290 | }
291 |
292 | context.fillStyle = '#000';
293 | context.fillRect(0, 0, canvas.width, canvas.height);
294 |
295 | // Draw al shoots in the space
296 | for(var i = 0; i < shoots.length; i++) {
297 | shoot = shoots[i];
298 | drawShoot(shoot);
299 | }
300 |
301 | // Draw enemies
302 | for (var i = 0; i < enemies.length; i++) {
303 | enemy = enemies[i];
304 | if (enemy.dead == false) {
305 | drawEnemy(enemy);
306 | }
307 | }
308 |
309 | // Draw level
310 | context.fillStyle = '#fff';
311 | context.fillText('LVL ' + ship.level
312 | + ' (exp: ' + ship.exp + ')',
313 | 10, canvas.height - 10);
314 |
315 | // Barra de energía
316 | drawHPBar();
317 |
318 | drawShip(ship.loc.x, ship.loc.y);
319 | if (ship.killed === false) {
320 | drawShield(ship.loc.x, ship.loc.y, 50);
321 | }
322 | //drawShoot(cx, by);
323 | //drawShoot(cx, by - 30);
324 | //drawShoot(cx, by - 60);
325 |
326 | if (!ship.killed) {
327 | requestAnimationFrame(timeit);
328 | }
329 | }
330 |
331 | function drawShip(x, y) {
332 | context.strokeStyle = '#fff';
333 | context.beginPath();
334 | if (ship.killed === false) {
335 | context.moveTo(x, y);
336 | context.lineTo(x + 10, y + 40);
337 | context.lineTo(x - 10, y + 40);
338 | context.closePath();
339 | } else {
340 | context.moveTo(x - 30, y);
341 | context.lineTo(x + 30, y + 40);
342 | context.moveTo(x + 30, y);
343 | context.lineTo(x - 30, y + 40)
344 | }
345 |
346 | context.stroke();
347 | }
348 |
349 | function drawShield(x, y, radio) {
350 | context.beginPath();
351 | context.arc(x, y, radio, Math.PI, Math.PI * 2);
352 | context.stroke();
353 | }
354 |
355 | function drawShoot(shoot) {
356 | context.beginPath();
357 | if (shoot.radio) {
358 | context.arc(shoot.loc.x, shoot.loc.y,
359 | shoot.radio, 0, Math.PI * 2);
360 | } else {
361 | context.moveTo(shoot.loc.x, shoot.loc.y - 10);
362 | context.lineTo(shoot.loc.x, shoot.loc.y - 30);
363 | }
364 |
365 | context.stroke();
366 | }
367 |
368 | function drawHPBar() {
369 | context.strokeStyle = '#fff 2px';
370 | context.strokeRect(16, 16, 100, 30);
371 | context.fillStyle = '#fff';
372 | context.strokeStyle = null;
373 | context.fillRect(20, 20, 92, 22);
374 | }
375 |
376 | function drawEnemy(enemy) {
377 | var strokeColor;
378 | var fillColor;
379 |
380 | if (enemy.beingShot) {
381 | strokeColor = '#f00';
382 | fillColor = '#f00';
383 | enemy.beingShot = false;
384 | damaged = true;
385 | } else {
386 | strokeColor = '#fff';
387 | }
388 | context.beginPath();
389 | context.moveTo(enemy.loc.x, enemy.loc.y);
390 | context.lineTo(enemy.loc.x + enemy.size.w, enemy.loc.y);
391 | context.lineTo(enemy.loc.x + enemy.size.w / 2,
392 | enemy.loc.y + enemy.size.h)
393 | context.closePath();
394 | if (fillColor) {
395 | context.fillStyle = fillColor;
396 | context.fill();
397 | } else {
398 | context.stroke();
399 | }
400 |
401 | context.fillStyle = '#fff';
402 | var perc = Math.round(enemy.hp) + '%';
403 | var s = context.measureText(perc);
404 | /*context.fillText(perc,
405 | enemy.loc.x + (enemy.size.w / 2 - s.width / 2),
406 | enemy.loc.y + (enemy.size.h / 2)
407 | );*/
408 | }
409 |
410 | window.onload = function() {
411 | canvas = document.getElementById('space');
412 |
413 | // Force to resize the canvas and then
414 | // return the context of it.
415 | window.onresize();
416 | context = canvas.getContext('2d');
417 |
418 | // Add some enemies
419 | var enemy, hp;
420 | for (var i = 0; i < 10; i++) {
421 | hp = Math.random() * 300;
422 | enemy = {
423 | loc: {
424 | x: Math.random() * canvas.width,
425 | y: Math.random() * canvas.height - canvas.height
426 | },
427 | hp: hp,
428 | maxhp: hp,
429 | size: {
430 | w: 100 * Math.random() + 15,
431 | h: 30 * Math.random() + 30
432 | },
433 | dead: false,
434 | speed: Math.random() + 1.5,
435 | exp: 5,
436 | weapon: {
437 | shootRate: 5000,
438 | timeToShoot: 0
439 | }
440 | };
441 | enemies.push(enemy);
442 | }
443 |
444 | // Define defaults colors
445 | //context.clearStyle = CLEAR_STYLE;
446 | context.strokeStyle = STROKE_STYLE;
447 |
448 | // Prepares the ship position
449 | ship.loc.x = canvas.width / 2;
450 | ship.loc.y = canvas.height - 100;
451 |
452 | // Prepare keymap
453 | for(var i = 0; i < 256; i++) {
454 | keymap.push(false);
455 | }
456 |
457 | window.onkeydown = function(event) {
458 | keymap[event.keyCode] = true;
459 | }
460 |
461 | window.onkeyup = function(event) {
462 | keymap[event.keyCode] = false;
463 | }
464 |
465 | window.onmousemove = function(event) {
466 | ship.loc.x = event.clientX;
467 | ship.loc.y = event.clientY;
468 | }
469 |
470 | window.onmousedown = function(event) {
471 | mousemap[event.button] = true;
472 | }
473 |
474 | window.onmouseup = function(event) {
475 | mousemap[event.button] = false;
476 | }
477 |
478 | timeit();
479 | }
480 |
481 | window.onresize = function() {
482 | canvas.width = window.innerWidth;
483 | canvas.height = window.innerHeight;
484 | }
--------------------------------------------------------------------------------