├── 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 | ![alt tag](https://github.com/gamikun/cosas-raras/blob/master/circulos-de-colores/sample.png) 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 | ![alt tag](https://github.com/gamikun/cosas-raras/blob/master/circunferencia/arco-sample.png) 3 | 4 | ## poly.html 5 | ![alt tag](https://github.com/gamikun/cosas-raras/blob/master/circunferencia/poly-sample.png) 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 | 12 | 13 | 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 | 12 | 13 | 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 | 26 | 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 |
103 |
Radius
104 | 106 |
107 | 108 |
109 |
Puntos
110 | 112 |
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 |
112 |
Radius
113 | 115 |
116 | 117 |
118 |
Puntos
119 | 121 |
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 | } --------------------------------------------------------------------------------