From 44097da7288042e988bcb89f1c6cc817a8e1eec9 Mon Sep 17 00:00:00 2001 From: zhang Date: Sat, 4 Jun 2022 08:48:54 +0800 Subject: 0604 --- att/swin_transformer_demo.py | 1 + cv/seg/img2video.py | 3 +- cv/tracker/object_tracker.py | 106 ++- cv/tracker/video.avi | Bin 0 -> 12927512 bytes learn_torch/seq/basic_rnn.py | 43 + learn_torch/seq/sentiment_analysis.py | 193 ++++ learn_torch/seq/test_rnn.py | 8 + pose/1.mp4 | Bin 0 -> 13892865 bytes pose/4.jpg | Bin 0 -> 333738 bytes pose/PoseEstimation.py | 64 ++ pretrained/swin/demo.py | 36 + pretrained/swin/house_finch.jpg | Bin 0 -> 20694 bytes pretrained/swin/imagenet_labels.json | 1000 ++++++++++++++++++++ rl/gym_demo/hello.py | 10 + ...ower of Hanoi Animation by Y. Daniel Liang.html | 762 +++++++++++++++ web/bigai/canvas_layering.html | 116 +++ web/bigai/myrender.py | 109 +++ web/bigai/test.html | 52 + web/canvas-transforms.html | 82 ++ web/canvas_animation.html | 73 ++ web/canvas_layering.html | 113 +++ web/layers/CanvasStack-2v01.js | 207 ++++ web/layers/index.html | 13 + web/layers/main.js | 15 + web/learn_canvas/bar_canvas.html | 50 + web/learn_canvas/basics/index.html | 11 + web/learn_canvas/basics/main.js | 60 ++ web/learn_canvas/canvas_btns/example.js | 121 +++ web/learn_canvas/canvas_btns/index.html | 43 + web/learn_canvas/canvas_btns/main.js | 11 + web/learn_canvas/canvas_btns/style.css | 18 + web/learn_canvas/canvas_btns/test.html | 77 ++ web/learn_canvas/canvas_btns/test2.html | 47 + web/multi_layers.html | 24 + web/multi_layers/index.html | 11 + web/multi_layers/main.js | 60 ++ 36 files changed, 3515 insertions(+), 24 deletions(-) create mode 100644 att/swin_transformer_demo.py create mode 100644 cv/tracker/video.avi create mode 100644 learn_torch/seq/basic_rnn.py create mode 100644 learn_torch/seq/sentiment_analysis.py create mode 100644 learn_torch/seq/test_rnn.py create mode 100644 pose/1.mp4 create mode 100644 pose/4.jpg create mode 100644 pose/PoseEstimation.py create mode 100644 pretrained/swin/demo.py create mode 100644 pretrained/swin/house_finch.jpg create mode 100644 pretrained/swin/imagenet_labels.json create mode 100644 rl/gym_demo/hello.py create mode 100644 web/Tower of Hanoi Animation by Y. Daniel Liang.html create mode 100644 web/bigai/canvas_layering.html create mode 100644 web/bigai/myrender.py create mode 100644 web/bigai/test.html create mode 100644 web/canvas-transforms.html create mode 100644 web/canvas_animation.html create mode 100644 web/canvas_layering.html create mode 100644 web/layers/CanvasStack-2v01.js create mode 100644 web/layers/index.html create mode 100644 web/layers/main.js create mode 100644 web/learn_canvas/bar_canvas.html create mode 100644 web/learn_canvas/basics/index.html create mode 100644 web/learn_canvas/basics/main.js create mode 100644 web/learn_canvas/canvas_btns/example.js create mode 100644 web/learn_canvas/canvas_btns/index.html create mode 100644 web/learn_canvas/canvas_btns/main.js create mode 100644 web/learn_canvas/canvas_btns/style.css create mode 100644 web/learn_canvas/canvas_btns/test.html create mode 100644 web/learn_canvas/canvas_btns/test2.html create mode 100644 web/multi_layers.html create mode 100644 web/multi_layers/index.html create mode 100644 web/multi_layers/main.js diff --git a/att/swin_transformer_demo.py b/att/swin_transformer_demo.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/att/swin_transformer_demo.py @@ -0,0 +1 @@ + diff --git a/cv/seg/img2video.py b/cv/seg/img2video.py index c824c9c..4fdc17b 100644 --- a/cv/seg/img2video.py +++ b/cv/seg/img2video.py @@ -9,7 +9,8 @@ images = [img for img in os.listdir(image_folder) if img.endswith(".jpg")] frame = cv2.imread(os.path.join(image_folder, images[0])) height, width, layers = frame.shape -video = cv2.VideoWriter(video_name, 0, 10, (width,height)) +fourcc = cv2.VideoWriter_fourcc(*'XVID') +video = cv2.VideoWriter(video_name, fourcc, 10, (width,height)) images.sort(key=lambda s: int(s.split('.')[0].split('-')[1])) for image in tqdm(images): video.write(cv2.imread(os.path.join(image_folder, image))) diff --git a/cv/tracker/object_tracker.py b/cv/tracker/object_tracker.py index 315ffa3..7c99145 100644 --- a/cv/tracker/object_tracker.py +++ b/cv/tracker/object_tracker.py @@ -1,35 +1,95 @@ import cv2 +import sys -cap = cv2.VideoCapture(0) +(major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.') -tracker = cv2.TrackerGOTURN_create() -success, img = cap.read() +if __name__ == '__main__': -# select a bounding box ( ROI ) -bbox = cv2.selectROI("Tracking", img, False) -tracker.init(img, bbox) + # Set up tracker. + # Instead of MIL, you can also use + tracker_types = ['BOOSTING', 'MIL', 'KCF', 'TLD', 'MEDIANFLOW', 'GOTURN', 'MOSSE', 'CSRT'] + tracker_type = tracker_types[2] -def drawBox(img, bbox): - x, y, w, h = int(bbox[0]), int(bbox[1]), int(bbox[2]), int(bbox[3]) - cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 255), 3, 1) - cv2.putText(img, "Tracking", (75, 75), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2) + if int(minor_ver) < 3: + tracker = cv2.Tracker_create(tracker_type) + else: + if tracker_type == 'BOOSTING': + tracker = cv2.TrackerBoosting_create() + if tracker_type == 'MIL': + tracker = cv2.TrackerMIL_create() + if tracker_type == 'KCF': + tracker = cv2.TrackerKCF_create() + if tracker_type == 'TLD': + tracker = cv2.TrackerTLD_create() + if tracker_type == 'MEDIANFLOW': + tracker = cv2.TrackerMedianFlow_create() + if tracker_type == 'GOTURN': + tracker = cv2.TrackerGOTURN_create() + if tracker_type == 'MOSSE': + tracker = cv2.TrackerMOSSE_create() + if tracker_type == "CSRT": + tracker = cv2.TrackerCSRT_create() + # Read video + video = cv2.VideoCapture("./video.avi") -while True: - timer = cv2.getTickCount() - success, img = cap.read() + # Exit if video not opened. + if not video.isOpened(): + print + "Could not open video" + sys.exit() - success, bbox = tracker.update(img) + # Read first frame. + ok, frame = video.read() + if not ok: + print + 'Cannot read video file' + sys.exit() - if success: - drawBox(img, bbox) - else: - cv2.putText(img, "Loss", (75, 75), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) + # Define an initial bounding box + bbox = (287, 23, 86, 320) + + # Uncomment the line below to select a different bounding box + bbox = cv2.selectROI(frame, False) + + # Initialize tracker with first frame and bounding box + ok = tracker.init(frame, bbox) + + while True: + # Read a new frame + ok, frame = video.read() + if not ok: + break + + # Start timer + timer = cv2.getTickCount() + + # Update tracker + ok, bbox = tracker.update(frame) + + # Calculate Frames per second (FPS) + fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer); + + # Draw bounding box + if ok: + # Tracking success + p1 = (int(bbox[0]), int(bbox[1])) + p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3])) + cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1) + else: + # Tracking failure + cv2.putText(frame, "Tracking failure detected", (100, 80), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2) + + # Display tracker type on frame + cv2.putText(frame, tracker_type + " Tracker", (100, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2); + + # Display FPS on frame + cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2); - fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer) - cv2.putText(img, str(int(fps)), (75, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) - cv2.imshow("Tracking", img) + # Display result + cv2.imshow("Tracking", frame) - if cv2.waitKey(1) & 0xff == ord('q'): - break \ No newline at end of file + # Exit if ESC pressed + k = cv2.waitKey(1) & 0xff + if k == 27: break diff --git a/cv/tracker/video.avi b/cv/tracker/video.avi new file mode 100644 index 0000000..2006145 Binary files /dev/null and b/cv/tracker/video.avi differ diff --git a/learn_torch/seq/basic_rnn.py b/learn_torch/seq/basic_rnn.py new file mode 100644 index 0000000..a2db2af --- /dev/null +++ b/learn_torch/seq/basic_rnn.py @@ -0,0 +1,43 @@ +import torch +from torch import nn + + +def t1(): + rnn = nn.RNN(10, 20, 2) + input = torch.randn(5, 3, 10) + h0 = torch.randn(2, 3, 20) + output, hn = rnn(input, h0) + print() + +def t2(): + data = torch.Tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]) + print("Data: ", data.shape, "\n\n", data) + ###################### OUTPUT ###################### + + + # Number of features used as input. (Number of columns) + INPUT_SIZE = 1 + # Number of previous time stamps taken into account. + SEQ_LENGTH = 5 + # Number of features in last hidden state ie. number of output time- + # steps to predict.See image below for more clarity. + HIDDEN_SIZE = 2 + # Number of stacked rnn layers. + NUM_LAYERS = 1 + # We have total of 20 rows in our input. + # We divide the input into 4 batches where each batch has only 1 + # row. Each row corresponds to a sequence of length 5. + BATCH_SIZE = 4 + + # Initialize the RNN. + rnn = nn.RNN(input_size=INPUT_SIZE, hidden_size=HIDDEN_SIZE, num_layers = 1, batch_first=True) + # input size : (batch, seq_len, input_size) + inputs = data.view(BATCH_SIZE, SEQ_LENGTH, INPUT_SIZE) + # out shape = (batch, seq_len, num_directions * hidden_size) + # h_n shape = (num_layers * num_directions, batch, hidden_size) + out, h_n = rnn(inputs) + + +if __name__ == '__main__': + nn.Linear + t1() diff --git a/learn_torch/seq/sentiment_analysis.py b/learn_torch/seq/sentiment_analysis.py new file mode 100644 index 0000000..8971e31 --- /dev/null +++ b/learn_torch/seq/sentiment_analysis.py @@ -0,0 +1,193 @@ +import torch +from torchtext.legacy import data +from torchtext.legacy import datasets +import random +import torch.nn as nn +import time + +SEED = 1234 + +torch.manual_seed(SEED) +torch.backends.cudnn.deterministic = True + +TEXT = data.Field(tokenize='spacy', + tokenizer_language='en_core_web_sm') +LABEL = data.LabelField(dtype=torch.float) + + +train_data, test_data = datasets.IMDB.splits(TEXT, LABEL) + +print(f'Number of training examples: {len(train_data)}') +print(f'Number of testing examples: {len(test_data)}') + +print(vars(train_data.examples[0])) + +train_data, valid_data = train_data.split(random_state = random.seed(SEED)) + +print(f'Number of training examples: {len(train_data)}') +print(f'Number of validation examples: {len(valid_data)}') +print(f'Number of testing examples: {len(test_data)}') + +MAX_VOCAB_SIZE = 25_000 + +TEXT.build_vocab(train_data, max_size = MAX_VOCAB_SIZE) +LABEL.build_vocab(train_data) + +print(f"Unique tokens in TEXT vocabulary: {len(TEXT.vocab)}") +print(f"Unique tokens in LABEL vocabulary: {len(LABEL.vocab)}") + +print(TEXT.vocab.freqs.most_common(20)) + +print(TEXT.vocab.itos[:10]) +print(LABEL.vocab.stoi) + +BATCH_SIZE = 64 + +device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') + +train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits( + (train_data, valid_data, test_data), + batch_size = BATCH_SIZE, + device = device) + + +class RNN(nn.Module): + def __init__(self, input_dim, embedding_dim, hidden_dim, output_dim): + super().__init__() + + self.embedding = nn.Embedding(input_dim, embedding_dim) + + self.rnn = nn.RNN(embedding_dim, hidden_dim) + + self.fc = nn.Linear(hidden_dim, output_dim) + + def forward(self, text): + # text = [sent len, batch size] + + embedded = self.embedding(text) + + # embedded = [sent len, batch size, emb dim] + + output, hidden = self.rnn(embedded) + + # output = [sent len, batch size, hid dim] + # hidden = [1, batch size, hid dim] + + assert torch.equal(output[-1, :, :], hidden.squeeze(0)) + + return self.fc(hidden.squeeze(0)) + +INPUT_DIM = len(TEXT.vocab) +EMBEDDING_DIM = 100 +HIDDEN_DIM = 256 +OUTPUT_DIM = 1 + +model = RNN(INPUT_DIM, EMBEDDING_DIM, HIDDEN_DIM, OUTPUT_DIM) + +def count_parameters(model): + return sum(p.numel() for p in model.parameters() if p.requires_grad) + +print(f'The model has {count_parameters(model):,} trainable parameters') + + +import torch.optim as optim + +optimizer = optim.SGD(model.parameters(), lr=1e-3) +criterion = nn.BCEWithLogitsLoss() + +model = model.to(device) +criterion = criterion.to(device) + +def binary_accuracy(preds, y): + """ + Returns accuracy per batch, i.e. if you get 8/10 right, this returns 0.8, NOT 8 + """ + + #round predictions to the closest integer + rounded_preds = torch.round(torch.sigmoid(preds)) + correct = (rounded_preds == y).float() #convert into float for division + acc = correct.sum() / len(correct) + return acc + + +def train(model, iterator, optimizer, criterion): + epoch_loss = 0 + epoch_acc = 0 + + model.train() + + for batch in iterator: + optimizer.zero_grad() + + predictions = model(batch.text).squeeze(1) + + loss = criterion(predictions, batch.label) + + acc = binary_accuracy(predictions, batch.label) + + loss.backward() + + optimizer.step() + + epoch_loss += loss.item() + epoch_acc += acc.item() + + return epoch_loss / len(iterator), epoch_acc / len(iterator) + + +def evaluate(model, iterator, criterion): + epoch_loss = 0 + epoch_acc = 0 + + model.eval() + + with torch.no_grad(): + for batch in iterator: + predictions = model(batch.text).squeeze(1) + + loss = criterion(predictions, batch.label) + + acc = binary_accuracy(predictions, batch.label) + + epoch_loss += loss.item() + epoch_acc += acc.item() + + return epoch_loss / len(iterator), epoch_acc / len(iterator) + + +def epoch_time(start_time, end_time): + elapsed_time = end_time - start_time + elapsed_mins = int(elapsed_time / 60) + elapsed_secs = int(elapsed_time - (elapsed_mins * 60)) + return elapsed_mins, elapsed_secs + + +N_EPOCHS = 5 + +best_valid_loss = float('inf') + +for epoch in range(N_EPOCHS): + + start_time = time.time() + + train_loss, train_acc = train(model, train_iterator, optimizer, criterion) + valid_loss, valid_acc = evaluate(model, valid_iterator, criterion) + + end_time = time.time() + + epoch_mins, epoch_secs = epoch_time(start_time, end_time) + + if valid_loss < best_valid_loss: + best_valid_loss = valid_loss + torch.save(model.state_dict(), 'tut1-model.pt') + + print(f'Epoch: {epoch+1:02} | Epoch Time: {epoch_mins}m {epoch_secs}s') + print(f'\tTrain Loss: {train_loss:.3f} | Train Acc: {train_acc*100:.2f}%') + print(f'\t Val. Loss: {valid_loss:.3f} | Val. Acc: {valid_acc*100:.2f}%') + + +model.load_state_dict(torch.load('tut1-model.pt')) + +test_loss, test_acc = evaluate(model, test_iterator, criterion) + +print(f'Test Loss: {test_loss:.3f} | Test Acc: {test_acc*100:.2f}%') \ No newline at end of file diff --git a/learn_torch/seq/test_rnn.py b/learn_torch/seq/test_rnn.py new file mode 100644 index 0000000..5a7baf2 --- /dev/null +++ b/learn_torch/seq/test_rnn.py @@ -0,0 +1,8 @@ +import torch +from torch import nn + +if __name__ == '__main__': + rnn = nn.RNN(10, 20, 2) + input = torch.randn(5, 3, 10) + h0 = torch.randn(2, 3, 10) + rnn(input, h0) diff --git a/pose/1.mp4 b/pose/1.mp4 new file mode 100644 index 0000000..7435e06 Binary files /dev/null and b/pose/1.mp4 differ diff --git a/pose/4.jpg b/pose/4.jpg new file mode 100644 index 0000000..04f7515 Binary files /dev/null and b/pose/4.jpg differ diff --git a/pose/PoseEstimation.py b/pose/PoseEstimation.py new file mode 100644 index 0000000..cdd594a --- /dev/null +++ b/pose/PoseEstimation.py @@ -0,0 +1,64 @@ +# Created by MediaPipe +# Modified by Augmented Startups 2021 +# Pose-Estimation in 5 Minutes +# Watch 5 Minute Tutorial at www.augmentedstartups.info/YouTube +import cv2 +import mediapipe as mp +import time +import os + +mp_drawing = mp.solutions.drawing_utils +mp_pose = mp.solutions.pose +mp_holistic = mp.solutions.holistic + +# For static images: +with mp_pose.Pose( + static_image_mode=True, + # model_complexity=2, + min_detection_confidence=0.5) as pose: + image = cv2.imread('4.jpg') # Insert your Image Here + image_height, image_width, _ = image.shape + # Convert the BGR image to RGB before processing. + results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) + # Draw pose landmarks on the image. + annotated_image = image.copy() + mp_drawing.draw_landmarks(annotated_image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) + cv2.imwrite(r'4.png', annotated_image) + +# For webcam input: +# cap = cv2.VideoCapture(0) +cap = cv2.VideoCapture("1.mp4") +# For Video input: +prevTime = 0 +with mp_pose.Pose( + min_detection_confidence=0.5, + min_tracking_confidence=0.5) as pose: + while cap.isOpened(): + success, image = cap.read() + if not success: + print("Ignoring empty camera frame.") + # If loading a video, use 'break' instead of 'continue'. + continue + + # Convert the BGR image to RGB. + image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) + # To improve performance, optionally mark the image as not writeable to + # pass by reference. + image.flags.writeable = False + results = pose.process(image) + + # Draw the pose annotation on the image. + image.flags.writeable = True + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + mp_drawing.draw_landmarks( + image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS) + currTime = time.time() + fps = 1 / (currTime - prevTime) + prevTime = currTime + cv2.putText(image, f'FPS: {int(fps)}', (20, 70), cv2.FONT_HERSHEY_PLAIN, 3, (0, 196, 255), 2) + cv2.imshow('BlazePose', image) + if cv2.waitKey(5) & 0xFF == 27: + break +cap.release() +# Learn more AI in Computer Vision by Enrolling in our AI_CV Nano Degree: +# https://bit.ly/AugmentedAICVPRO diff --git a/pretrained/swin/demo.py b/pretrained/swin/demo.py new file mode 100644 index 0000000..6f8d87b --- /dev/null +++ b/pretrained/swin/demo.py @@ -0,0 +1,36 @@ +import timm +import torch +import torchvision +from PIL import Image +from torchvision import transforms as T +import json + +if __name__ == '__main__': + trans_ = T.Compose( + [ + T.Resize(256), + T.CenterCrop(224), + T.ToTensor(), + T.Normalize(timm.data.IMAGENET_DEFAULT_MEAN, timm.data.IMAGENET_DEFAULT_STD)] + ) + + image = Image.open('./house_finch.jpg') + transformed = trans_(image) + print(transformed.shape) + batch_input = transformed.unsqueeze(0) + print(batch_input.shape) + + model = timm.create_model('swin_base_patch4_window7_224', pretrained=True) + + with torch.no_grad(): + output = model(batch_input) + + print(output) + print(output.shape) + labels = json.load(open('./imagenet_labels.json')) + class_ = output.argmax(dim=1) + print(class_) + print(class_.data) + print(output.sum(dim=1)) + print(labels[class_]) + diff --git a/pretrained/swin/house_finch.jpg b/pretrained/swin/house_finch.jpg new file mode 100644 index 0000000..b3b92df Binary files /dev/null and b/pretrained/swin/house_finch.jpg differ diff --git a/pretrained/swin/imagenet_labels.json b/pretrained/swin/imagenet_labels.json new file mode 100644 index 0000000..28fce58 --- /dev/null +++ b/pretrained/swin/imagenet_labels.json @@ -0,0 +1,1000 @@ +["tench", +"goldfish", +"great white shark", +"tiger shark", +"hammerhead shark", +"electric ray", +"stingray", +"cock", +"hen", +"ostrich", +"brambling", +"goldfinch", +"house finch", +"junco", +"indigo bunting", +"American robin", +"bulbul", +"jay", +"magpie", +"chickadee", +"American dipper", +"kite", +"bald eagle", +"vulture", +"great grey owl", +"fire salamander", +"smooth newt", +"newt", +"spotted salamander", +"axolotl", +"American bullfrog", +"tree frog", +"tailed frog", +"loggerhead sea turtle", +"leatherback sea turtle", +"mud turtle", +"terrapin", +"box turtle", +"banded gecko", +"green iguana", +"Carolina anole", +"desert grassland whiptail lizard", +"agama", +"frilled-necked lizard", +"alligator lizard", +"Gila monster", +"European green lizard", +"chameleon", +"Komodo dragon", +"Nile crocodile", +"American alligator", +"triceratops", +"worm snake", +"ring-necked snake", +"eastern hog-nosed snake", +"smooth green snake", +"kingsnake", +"garter snake", +"water snake", +"vine snake", +"night snake", +"boa constrictor", +"African rock python", +"Indian cobra", +"green mamba", +"sea snake", +"Saharan horned viper", +"eastern diamondback rattlesnake", +"sidewinder", +"trilobite", +"harvestman", +"scorpion", +"yellow garden spider", +"barn spider", +"European garden spider", +"southern black widow", +"tarantula", +"wolf spider", +"tick", +"centipede", +"black grouse", +"ptarmigan", +"ruffed grouse", +"prairie grouse", +"peacock", +"quail", +"partridge", +"grey parrot", +"macaw", +"sulphur-crested cockatoo", +"lorikeet", +"coucal", +"bee eater", +"hornbill", +"hummingbird", +"jacamar", +"toucan", +"duck", +"red-breasted merganser", +"goose", +"black swan", +"tusker", +"echidna", +"platypus", +"wallaby", +"koala", +"wombat", +"jellyfish", +"sea anemone", +"brain coral", +"flatworm", +"nematode", +"conch", +"snail", +"slug", +"sea slug", +"chiton", +"chambered nautilus", +"Dungeness crab", +"rock crab", +"fiddler crab", +"red king crab", +"American lobster", +"spiny lobster", +"crayfish", +"hermit crab", +"isopod", +"white stork", +"black stork", +"spoonbill", +"flamingo", +"little blue heron", +"great egret", +"bittern", +"crane (bird)", +"limpkin", +"common gallinule", +"American coot", +"bustard", +"ruddy turnstone", +"dunlin", +"common redshank", +"dowitcher", +"oystercatcher", +"pelican", +"king penguin", +"albatross", +"grey whale", +"killer whale", +"dugong", +"sea lion", +"Chihuahua", +"Japanese Chin", +"Maltese", +"Pekingese", +"Shih Tzu", +"King Charles Spaniel", +"Papillon", +"toy terrier", +"Rhodesian Ridgeback", +"Afghan Hound", +"Basset Hound", +"Beagle", +"Bloodhound", +"Bluetick Coonhound", +"Black and Tan Coonhound", +"Treeing Walker Coonhound", +"English foxhound", +"Redbone Coonhound", +"borzoi", +"Irish Wolfhound", +"Italian Greyhound", +"Whippet", +"Ibizan Hound", +"Norwegian Elkhound", +"Otterhound", +"Saluki", +"Scottish Deerhound", +"Weimaraner", +"Staffordshire Bull Terrier", +"American Staffordshire Terrier", +"Bedlington Terrier", +"Border Terrier", +"Kerry Blue Terrier", +"Irish Terrier", +"Norfolk Terrier", +"Norwich Terrier", +"Yorkshire Terrier", +"Wire Fox Terrier", +"Lakeland Terrier", +"Sealyham Terrier", +"Airedale Terrier", +"Cairn Terrier", +"Australian Terrier", +"Dandie Dinmont Terrier", +"Boston Terrier", +"Miniature Schnauzer", +"Giant Schnauzer", +"Standard Schnauzer", +"Scottish Terrier", +"Tibetan Terrier", +"Australian Silky Terrier", +"Soft-coated Wheaten Terrier", +"West Highland White Terrier", +"Lhasa Apso", +"Flat-Coated Retriever", +"Curly-coated Retriever", +"Golden Retriever", +"Labrador Retriever", +"Chesapeake Bay Retriever", +"German Shorthaired Pointer", +"Vizsla", +"English Setter", +"Irish Setter", +"Gordon Setter", +"Brittany", +"Clumber Spaniel", +"English Springer Spaniel", +"Welsh Springer Spaniel", +"Cocker Spaniels", +"Sussex Spaniel", +"Irish Water Spaniel", +"Kuvasz", +"Schipperke", +"Groenendael", +"Malinois", +"Briard", +"Australian Kelpie", +"Komondor", +"Old English Sheepdog", +"Shetland Sheepdog", +"collie", +"Border Collie", +"Bouvier des Flandres", +"Rottweiler", +"German Shepherd Dog", +"Dobermann", +"Miniature Pinscher", +"Greater Swiss Mountain Dog", +"Bernese Mountain Dog", +"Appenzeller Sennenhund", +"Entlebucher Sennenhund", +"Boxer", +"Bullmastiff", +"Tibetan Mastiff", +"French Bulldog", +"Great Dane", +"St. Bernard", +"husky", +"Alaskan Malamute", +"Siberian Husky", +"Dalmatian", +"Affenpinscher", +"Basenji", +"pug", +"Leonberger", +"Newfoundland", +"Pyrenean Mountain Dog", +"Samoyed", +"Pomeranian", +"Chow Chow", +"Keeshond", +"Griffon Bruxellois", +"Pembroke Welsh Corgi", +"Cardigan Welsh Corgi", +"Toy Poodle", +"Miniature Poodle", +"Standard Poodle", +"Mexican hairless dog", +"grey wolf", +"Alaskan tundra wolf", +"red wolf", +"coyote", +"dingo", +"dhole", +"African wild dog", +"hyena", +"red fox", +"kit fox", +"Arctic fox", +"grey fox", +"tabby cat", +"tiger cat", +"Persian cat", +"Siamese cat", +"Egyptian Mau", +"cougar", +"lynx", +"leopard", +"snow leopard", +"jaguar", +"lion", +"tiger", +"cheetah", +"brown bear", +"American black bear", +"polar bear", +"sloth bear", +"mongoose", +"meerkat", +"tiger beetle", +"ladybug", +"ground beetle", +"longhorn beetle", +"leaf beetle", +"dung beetle", +"rhinoceros beetle", +"weevil", +"fly", +"bee", +"ant", +"grasshopper", +"cricket", +"stick insect", +"cockroach", +"mantis", +"cicada", +"leafhopper", +"lacewing", +"dragonfly", +"damselfly", +"red admiral", +"ringlet", +"monarch butterfly", +"small white", +"sulphur butterfly", +"gossamer-winged butterfly", +"starfish", +"sea urchin", +"sea cucumber", +"cottontail rabbit", +"hare", +"Angora rabbit", +"hamster", +"porcupine", +"fox squirrel", +"marmot", +"beaver", +"guinea pig", +"common sorrel", +"zebra", +"pig", +"wild boar", +"warthog", +"hippopotamus", +"ox", +"water buffalo", +"bison", +"ram", +"bighorn sheep", +"Alpine ibex", +"hartebeest", +"impala", +"gazelle", +"dromedary", +"llama", +"weasel", +"mink", +"European polecat", +"black-footed ferret", +"otter", +"skunk", +"badger", +"armadillo", +"three-toed sloth", +"orangutan", +"gorilla", +"chimpanzee", +"gibbon", +"siamang", +"guenon", +"patas monkey", +"baboon", +"macaque", +"langur", +"black-and-white colobus", +"proboscis monkey", +"marmoset", +"white-headed capuchin", +"howler monkey", +"titi", +"Geoffroy's spider monkey", +"common squirrel monkey", +"ring-tailed lemur", +"indri", +"Asian elephant", +"African bush elephant", +"red panda", +"giant panda", +"snoek", +"eel", +"coho salmon", +"rock beauty", +"clownfish", +"sturgeon", +"garfish", +"lionfish", +"pufferfish", +"abacus", +"abaya", +"academic gown", +"accordion", +"acoustic guitar", +"aircraft carrier", +"airliner", +"airship", +"altar", +"ambulance", +"amphibious vehicle", +"analog clock", +"apiary", +"apron", +"waste container", +"assault rifle", +"backpack", +"bakery", +"balance beam", +"balloon", +"ballpoint pen", +"Band-Aid", +"banjo", +"baluster", +"barbell", +"barber chair", +"barbershop", +"barn", +"barometer", +"barrel", +"wheelbarrow", +"baseball", +"basketball", +"bassinet", +"bassoon", +"swimming cap", +"bath towel", +"bathtub", +"station wagon", +"lighthouse", +"beaker", +"military cap", +"beer bottle", +"beer glass", +"bell-cot", +"bib", +"tandem bicycle", +"bikini", +"ring binder", +"binoculars", +"birdhouse", +"boathouse", +"bobsleigh", +"bolo tie", +"poke bonnet", +"bookcase", +"bookstore", +"bottle cap", +"bow", +"bow tie", +"brass", +"bra", +"breakwater", +"breastplate", +"broom", +"bucket", +"buckle", +"bulletproof vest", +"high-speed train", +"butcher shop", +"taxicab", +"cauldron", +"candle", +"cannon", +"canoe", +"can opener", +"cardigan", +"car mirror", +"carousel", +"tool kit", +"carton", +"car wheel", +"automated teller machine", +"cassette", +"cassette player", +"castle", +"catamaran", +"CD player", +"cello", +"mobile phone", +"chain", +"chain-link fence", +"chain mail", +"chainsaw", +"chest", +"chiffonier", +"chime", +"china cabinet", +"Christmas stocking", +"church", +"movie theater", +"cleaver", +"cliff dwelling", +"cloak", +"clogs", +"cocktail shaker", +"coffee mug", +"coffeemaker", +"coil", +"combination lock", +"computer keyboard", +"confectionery store", +"container ship", +"convertible", +"corkscrew", +"cornet", +"cowboy boot", +"cowboy hat", +"cradle", +"crane (machine)", +"crash helmet", +"crate", +"infant bed", +"Crock Pot", +"croquet ball", +"crutch", +"cuirass", +"dam", +"desk", +"desktop computer", +"rotary dial telephone", +"diaper", +"digital clock", +"digital watch", +"dining table", +"dishcloth", +"dishwasher", +"disc brake", +"dock", +"dog sled", +"dome", +"doormat", +"drilling rig", +"drum", +"drumstick", +"dumbbell", +"Dutch oven", +"electric fan", +"electric guitar", +"electric locomotive", +"entertainment center", +"envelope", +"espresso machine", +"face powder", +"feather boa", +"filing cabinet", +"fireboat", +"fire engine", +"fire screen sheet", +"flagpole", +"flute", +"folding chair", +"football helmet", +"forklift", +"fountain", +"fountain pen", +"four-poster bed", +"freight car", +"French horn", +"frying pan", +"fur coat", +"garbage truck", +"gas mask", +"gas pump", +"goblet", +"go-kart", +"golf ball", +"golf cart", +"gondola", +"gong", +"gown", +"grand piano", +"greenhouse", +"grille", +"grocery store", +"guillotine", +"barrette", +"hair spray", +"half-track", +"hammer", +"hamper", +"hair dryer", +"hand-held computer", +"handkerchief", +"hard disk drive", +"harmonica", +"harp", +"harvester", +"hatchet", +"holster", +"home theater", +"honeycomb", +"hook", +"hoop skirt", +"horizontal bar", +"horse-drawn vehicle", +"hourglass", +"iPod", +"clothes iron", +"jack-o'-lantern", +"jeans", +"jeep", +"T-shirt", +"jigsaw puzzle", +"pulled rickshaw", +"joystick", +"kimono", +"knee pad", +"knot", +"lab coat", +"ladle", +"lampshade", +"laptop computer", +"lawn mower", +"lens cap", +"paper knife", +"library", +"lifeboat", +"lighter", +"limousine", +"ocean liner", +"lipstick", +"slip-on shoe", +"lotion", +"speaker", +"loupe", +"sawmill", +"magnetic compass", +"mail bag", +"mailbox", +"tights", +"tank suit", +"manhole cover", +"maraca", +"marimba", +"mask", +"match", +"maypole", +"maze", +"measuring cup", +"medicine chest", +"megalith", +"microphone", +"microwave oven", +"military uniform", +"milk can", +"minibus", +"miniskirt", +"minivan", +"missile", +"mitten", +"mixing bowl", +"mobile home", +"Model T", +"modem", +"monastery", +"monitor", +"moped", +"mortar", +"square academic cap", +"mosque", +"mosquito net", +"scooter", +"mountain bike", +"tent", +"computer mouse", +"mousetrap", +"moving van", +"muzzle", +"nail", +"neck brace", +"necklace", +"nipple", +"notebook computer", +"obelisk", +"oboe", +"ocarina", +"odometer", +"oil filter", +"organ", +"oscilloscope", +"overskirt", +"bullock cart", +"oxygen mask", +"packet", +"paddle", +"paddle wheel", +"padlock", +"paintbrush", +"pajamas", +"palace", +"pan flute", +"paper towel", +"parachute", +"parallel bars", +"park bench", +"parking meter", +"passenger car", +"patio", +"payphone", +"pedestal", +"pencil case", +"pencil sharpener", +"perfume", +"Petri dish", +"photocopier", +"plectrum", +"Pickelhaube", +"picket fence", +"pickup truck", +"pier", +"piggy bank", +"pill bottle", +"pillow", +"ping-pong ball", +"pinwheel", +"pirate ship", +"pitcher", +"hand plane", +"planetarium", +"plastic bag", +"plate rack", +"plow", +"plunger", +"Polaroid camera", +"pole", +"police van", +"poncho", +"billiard table", +"soda bottle", +"pot", +"potter's wheel", +"power drill", +"prayer rug", +"printer", +"prison", +"projectile", +"projector", +"hockey puck", +"punching bag", +"purse", +"quill", +"quilt", +"race car", +"racket", +"radiator", +"radio", +"radio telescope", +"rain barrel", +"recreational vehicle", +"reel", +"reflex camera", +"refrigerator", +"remote control", +"restaurant", +"revolver", +"rifle", +"rocking chair", +"rotisserie", +"eraser", +"rugby ball", +"ruler", +"running shoe", +"safe", +"safety pin", +"salt shaker", +"sandal", +"sarong", +"saxophone", +"scabbard", +"weighing scale", +"school bus", +"schooner", +"scoreboard", +"CRT screen", +"screw", +"screwdriver", +"seat belt", +"sewing machine", +"shield", +"shoe store", +"shoji", +"shopping basket", +"shopping cart", +"shovel", +"shower cap", +"shower curtain", +"ski", +"ski mask", +"sleeping bag", +"slide rule", +"sliding door", +"slot machine", +"snorkel", +"snowmobile", +"snowplow", +"soap dispenser", +"soccer ball", +"sock", +"solar thermal collector", +"sombrero", +"soup bowl", +"space bar", +"space heater", +"space shuttle", +"spatula", +"motorboat", +"spider web", +"spindle", +"sports car", +"spotlight", +"stage", +"steam locomotive", +"through arch bridge", +"steel drum", +"stethoscope", +"scarf", +"stone wall", +"stopwatch", +"stove", +"strainer", +"tram", +"stretcher", +"couch", +"stupa", +"submarine", +"suit", +"sundial", +"sunglass", +"sunglasses", +"sunscreen", +"suspension bridge", +"mop", +"sweatshirt", +"swimsuit", +"swing", +"switch", +"syringe", +"table lamp", +"tank", +"tape player", +"teapot", +"teddy bear", +"television", +"tennis ball", +"thatched roof", +"front curtain", +"thimble", +"threshing machine", +"throne", +"tile roof", +"toaster", +"tobacco shop", +"toilet seat", +"torch", +"totem pole", +"tow truck", +"toy store", +"tractor", +"semi-trailer truck", +"tray", +"trench coat", +"tricycle", +"trimaran", +"tripod", +"triumphal arch", +"trolleybus", +"trombone", +"tub", +"turnstile", +"typewriter keyboard", +"umbrella", +"unicycle", +"upright piano", +"vacuum cleaner", +"vase", +"vault", +"velvet", +"vending machine", +"vestment", +"viaduct", +"violin", +"volleyball", +"waffle iron", +"wall clock", +"wallet", +"wardrobe", +"military aircraft", +"sink", +"washing machine", +"water bottle", +"water jug", +"water tower", +"whiskey jug", +"whistle", +"wig", +"window screen", +"window shade", +"Windsor tie", +"wine bottle", +"wing", +"wok", +"wooden spoon", +"wool", +"split-rail fence", +"shipwreck", +"yawl", +"yurt", +"website", +"comic book", +"crossword", +"traffic sign", +"traffic light", +"dust jacket", +"menu", +"plate", +"guacamole", +"consomme", +"hot pot", +"trifle", +"ice cream", +"ice pop", +"baguette", +"bagel", +"pretzel", +"cheeseburger", +"hot dog", +"mashed potato", +"cabbage", +"broccoli", +"cauliflower", +"zucchini", +"spaghetti squash", +"acorn squash", +"butternut squash", +"cucumber", +"artichoke", +"bell pepper", +"cardoon", +"mushroom", +"Granny Smith", +"strawberry", +"orange", +"lemon", +"fig", +"pineapple", +"banana", +"jackfruit", +"custard apple", +"pomegranate", +"hay", +"carbonara", +"chocolate syrup", +"dough", +"meatloaf", +"pizza", +"pot pie", +"burrito", +"red wine", +"espresso", +"cup", +"eggnog", +"alp", +"bubble", +"cliff", +"coral reef", +"geyser", +"lakeshore", +"promontory", +"shoal", +"seashore", +"valley", +"volcano", +"baseball player", +"bridegroom", +"scuba diver", +"rapeseed", +"daisy", +"yellow lady's slipper", +"corn", +"acorn", +"rose hip", +"horse chestnut seed", +"coral fungus", +"agaric", +"gyromitra", +"stinkhorn mushroom", +"earth star", +"hen-of-the-woods", +"bolete", +"ear", +"toilet paper"] \ No newline at end of file diff --git a/rl/gym_demo/hello.py b/rl/gym_demo/hello.py new file mode 100644 index 0000000..766d2b3 --- /dev/null +++ b/rl/gym_demo/hello.py @@ -0,0 +1,10 @@ + +import gym +# 创建一个小车倒立摆模型 +env = gym.make('CartPole-v0') +# 初始化环境 +env.reset() +# 刷新当前环境,并显示 +for _ in range(1000): + env.render() + env.step(env.action_space.sample()) # take a random action \ No newline at end of file diff --git a/web/Tower of Hanoi Animation by Y. Daniel Liang.html b/web/Tower of Hanoi Animation by Y. Daniel Liang.html new file mode 100644 index 0000000..3014467 --- /dev/null +++ b/web/Tower of Hanoi Animation by Y. Daniel Liang.html @@ -0,0 +1,762 @@ + + + + Tower of Hanoi Animation by Y. Daniel Liang + + + + + + + + + + + + + + + + + + + + + + + + + + +

Tower of Hanoi Animation by + Y. Daniel Liang

+

+ Usage: Click the Start button to move all the discs from Tower A to Tower B. Click the Reset button to reset to the initial state. +

+ +
+ +
+
+
+
+
+
+
Tower A
+
Tower B
+
Tower C
+
+
+
+ + + + + + +
+
+ + + + + + + +
+
+ +
+ + + + +
\ No newline at end of file diff --git a/web/bigai/canvas_layering.html b/web/bigai/canvas_layering.html new file mode 100644 index 0000000..669fdf9 --- /dev/null +++ b/web/bigai/canvas_layering.html @@ -0,0 +1,116 @@ + + + + + Canvas Layers Test + + +
+ + + This text is displayed if your browser does not support HTML5 Canvas. + + + + This text is displayed if your browser does not support HTML5 Canvas. + + + + This text is displayed if your browser does not support HTML5 Canvas. + + + + +
+ + \ No newline at end of file diff --git a/web/bigai/myrender.py b/web/bigai/myrender.py new file mode 100644 index 0000000..d49e69b --- /dev/null +++ b/web/bigai/myrender.py @@ -0,0 +1,109 @@ +import gym +from gym.envs.classic_control import rendering +import math +from pyglet.gl import * +import pyglet + +class Attr(object): + def enable(self): + raise NotImplementedError + def disable(self): + pass + + +class Color(Attr): + def __init__(self, vec4): + self.vec4 = vec4 + def enable(self): + glColor4f(*self.vec4) +p +class Geom(object): + def __init__(self): + self._color=Color((0, 0, 0, 1.0)) + self.attrs = [self._color] + def render(self): + for attr in reversed(self.attrs): + attr.enable() + self.render1() + for attr in self.attrs: + attr.disable() + def render1(self): + raise NotImplementedError + def add_attr(self, attr): + self.attrs.append(attr) + def set_color(self, r, g, b, alpha=1): + self._color.vec4 = (r, g, b, alpha) + + +class FilledPolygon(Geom): + def __init__(self, v): + Geom.__init__(self) + self.v = v + def render1(self): + if len(self.v) == 4 : glBegin(GL_QUADS) + elif len(self.v) > 4 : glBegin(GL_POLYGON) + else: glBegin(GL_TRIANGLES) + for p in self.v: + glVertex3f(p[0], p[1],0) # draw each vertex + glEnd() + + color = (self._color.vec4[0] * 0.5, self._color.vec4[1] * 0.5, self._color.vec4[2] * 0.5, self._color.vec4[3] * 0.5) + glColor4f(*color) + glBegin(GL_LINE_LOOP) + for p in self.v: + glVertex3f(p[0], p[1],0) # draw each vertex + glEnd() + + +class MyEnv(gym.Env): + metadata = { + 'render.modes': ['human', 'rgb_array'], + 'videos.frames_per_second': 2 + } + + def __init__(self): + self.viewer = rendering.Viewer(800, 600) + + # def render(self, mode='human', close=False): + # line1 = rendering.Line((100, 300), (500, 300)) + # line2 = rendering.Line((100, 200), (500, 200)) + # line1.set_color(0, 0, 0) + # line2.set_color(0, 0, 0) + # self.viewer.add_geom(line1) + # self.viewer.add_geom(line2) + # return self.viewer.render(return_rgb_array=mode == 'rgb_array') + + def make_agent(self): + radius = 10 + res = 30 + WORLD_WIDTH = 10 + visual_distance = 100 + points = [] + for i in range(res): + ang = 2*math.pi*i/res + points.append([math.cos(ang)*radius, math.sin(ang)*radius]) + for i in range(9): + ang = 2 * math.pi * (i - 4) / res + points.append((math.cos(ang) * visual_distance + radius, math.sin(ang) * visual_distance)) + return points + + + # def render(self, mode='human', close=False): + # circle = rendering.make_circle(30) + # circle_transform = rendering.Transform(translation=(100, 100)) + # circle.add_attr(circle_transform) + # self.viewer.add_geom(circle) + # return self.viewer.render(return_rgb_array=mode == 'rgb_array') + + def render(self, mode='human'): + agent_points = self.make_agent() + agent = FilledPolygon(agent_points) + trans = rendering.Transform(translation=(200, 200)) + agent.add_attr(trans) + self.viewer.add_geom(agent) + return self.viewer.render(return_rgb_array=mode == 'rgb_array') + +if __name__ == '__main__': + env = MyEnv() + while True: + env.render() diff --git a/web/bigai/test.html b/web/bigai/test.html new file mode 100644 index 0000000..abc1d15 --- /dev/null +++ b/web/bigai/test.html @@ -0,0 +1,52 @@ + + + + + + + + + + \ No newline at end of file diff --git a/web/canvas-transforms.html b/web/canvas-transforms.html new file mode 100644 index 0000000..bfdbe80 --- /dev/null +++ b/web/canvas-transforms.html @@ -0,0 +1,82 @@ + + + + + + + Canvas Rotation + + + + + + + \ No newline at end of file diff --git a/web/canvas_animation.html b/web/canvas_animation.html new file mode 100644 index 0000000..205f8fe --- /dev/null +++ b/web/canvas_animation.html @@ -0,0 +1,73 @@ + + + + + Canvas Test + + +
+
+ + This text is displayed if your browser + does not support HTML5 Canvas. + +
+ + + +
+ + \ No newline at end of file diff --git a/web/canvas_layering.html b/web/canvas_layering.html new file mode 100644 index 0000000..6214009 --- /dev/null +++ b/web/canvas_layering.html @@ -0,0 +1,113 @@ + + + + + Canvas Layers Test + + +
+
+ + This text is displayed if your browser does not support HTML5 Canvas. + + + + This text is displayed if your browser does not support HTML5 Canvas. + + + + This text is displayed if your browser does not support HTML5 Canvas. + +
+ + +
+ + \ No newline at end of file diff --git a/web/layers/CanvasStack-2v01.js b/web/layers/CanvasStack-2v01.js new file mode 100644 index 0000000..1d8b328 --- /dev/null +++ b/web/layers/CanvasStack-2v01.js @@ -0,0 +1,207 @@ +/*============================================================= + Filename: CanvasStack-2v01.js + Rev: 2 + By: A.R.Collins + Description: Utilities to create multiple transparent + canvas layers suitable for animation. + License: Released into the public domain + latest version at + + + Date |Description |By + ------------------------------------------------------------- + 30Oct09 Rev 1.00 First release ARC + 08Sep12 bugfix: test for emulator failed in IE9 ARC + 02Mar13 Re-write to use screen canvas as background ARC + 28Jul13 remove getOverlayCanvas (use getElementById) + Tidy for JSLint ARC + 20Jul14 Setup a resize handler for layers, required when + canvas size changes on window resize (width in %). + Dropped excanvas support ARC + 18Sep19 Re-factor to simplify ARC + 21Sep19 Convert to Classes etc ARC + 30Sep19 Added addResizeCallback method + Released as Rev 2v00 ARC + 01Jan20 Add Layer.dragObjects to match Cango Layer ARC + =============================================================*/ + +var CanvasStack; + +(function() +{ + "use strict"; + + class Layer + { + constructor(canvasID, canvasElement) + { + this.id = canvasID; + this.cElem = canvasElement; + this.dragObjects = []; + } + } + + CanvasStack = class{ + constructor(cvsID, stackLimit){ + const savThis = this; + + function setResizeHandler(resizeLayers, timeout){ + let timer_id = undefined; + window.addEventListener("resize", ()=>{ + if(timer_id != undefined) + { + clearTimeout(timer_id); + timer_id = undefined; + } + timer_id = setTimeout(()=>{ + timer_id = undefined; + resizeLayers(); + savThis.bkgCanvas.resizeFns.forEach((currFn)=>currFn()); + }, timeout); + }); + } + + function resizeLayers(){ + const t = savThis.bkgCanvas.offsetTop + savThis.bkgCanvas.clientTop, + l = savThis.bkgCanvas.offsetLeft + savThis.bkgCanvas.clientLeft, + w = savThis.bkgCanvas.offsetWidth, + h = savThis.bkgCanvas.offsetHeight; + + // check if canvas size changed when window resized, allow some rounding error in layout calcs + if ((Math.abs(w - savThis.rawWidth)/w < 0.01) && (Math.abs(h - savThis.rawHeight)/h < 0.01)) + { + // canvas size didn't change so return + return; + } + // canvas has been resized so resize all the overlay canvases + for (let j=1; j= this.stackLimit) + { + console.error("CanvasStack: too many layers"); + return; + } + this.bkgCanvas.unique += 1; // a private static variable + const uniqueTag = this.bkgCanvas.unique.toString(); + const ovlId = this.cId+"_ovl_"+uniqueTag; + const ovlHTML = ""; + const topCvs = this.bkgCanvas.layers[nLyrs-1].cElem; + topCvs.insertAdjacentHTML('afterend', ovlHTML); + const newCvs = document.getElementById(ovlId); + newCvs.style.backgroundColor = "transparent"; + newCvs.style.left = (this.bkgCanvas.offsetLeft+this.bkgCanvas.clientLeft)+'px'; + newCvs.style.top = (this.bkgCanvas.offsetTop+this.bkgCanvas.clientTop)+'px'; + // make it the same size as the background canvas + newCvs.style.width = this.bkgCanvas.offsetWidth+'px'; + newCvs.style.height = this.bkgCanvas.offsetHeight+'px'; + let newL = new Layer(ovlId, newCvs); + // save the ID in an array to facilitate removal + this.bkgCanvas.layers.push(newL); + + return ovlId; // return the new canvas id + } + + deleteLayer(ovlyId){ + // check background canvas is still there + if (!(this.bkgCanvas && this.bkgCanvas.layers)) + { + console.log("CanvasStack: missing background canvas"); + return; + } + for (let i=1; i0; i--) // don't delete layers[0] its the bakg canavs + { + let ovlNode = this.bkgCanvas.layers[i].cElem; + if (ovlNode) + { + let orphan = ovlNode.parentNode.removeChild(ovlNode); + orphan = null; + } + // now delete layers array element + this.bkgCanvas.layers.splice(i,1); + } + // clear any resize callbacks, the layers are gone + this.bkgCanvas.resizeFns.length = 0; // remove any added handlers, leave the basic + } + + addResizeCallback(callbackFn){ + this.bkgCanvas.resizeFns.push(callbackFn); + } + }; + +}()); diff --git a/web/layers/index.html b/web/layers/index.html new file mode 100644 index 0000000..e30c96a --- /dev/null +++ b/web/layers/index.html @@ -0,0 +1,13 @@ + + + + + Document + + + + + + + + \ No newline at end of file diff --git a/web/layers/main.js b/web/layers/main.js new file mode 100644 index 0000000..6bab236 --- /dev/null +++ b/web/layers/main.js @@ -0,0 +1,15 @@ + +var canvas = document.getElementById("canvas"); +var ctx = canvas.getContext("2d"); + +canvas.width = window.innerWidth; +canvas.height = window.innerHeight; + +var stack = new CanvasStack(); +var layer1 = stack.createLayer(); +var ctx1 = document.getElementById(layer1).getContext("2d"); + +ctx1.fillRect(0, 0, 100, 100); + + + diff --git a/web/learn_canvas/bar_canvas.html b/web/learn_canvas/bar_canvas.html new file mode 100644 index 0000000..c2d7518 --- /dev/null +++ b/web/learn_canvas/bar_canvas.html @@ -0,0 +1,50 @@ + + + + + + + + + Enter the values seperated by a comma
+
+ +

+ + + + + diff --git a/web/learn_canvas/basics/index.html b/web/learn_canvas/basics/index.html new file mode 100644 index 0000000..3c0cfb8 --- /dev/null +++ b/web/learn_canvas/basics/index.html @@ -0,0 +1,11 @@ + + + + + Title + + + + + + \ No newline at end of file diff --git a/web/learn_canvas/basics/main.js b/web/learn_canvas/basics/main.js new file mode 100644 index 0000000..5aa6458 --- /dev/null +++ b/web/learn_canvas/basics/main.js @@ -0,0 +1,60 @@ +let canvas = document.getElementById("canvas"); +let ctx = canvas.getContext("2d"); + +var win_height = window.innerHeight; +var win_width = window.innerWidth; + +canvas.height = win_height; +canvas.width = win_width; +console.log(canvas.width, canvas.height); + +canvas.style.background = "#bbf"; + + +class Circle { + constructor(context, xpos, ypos, radius, color) { + this.context = context; + this.xpos = xpos; + this.ypos = ypos; + this.radius = radius; + this.color = color; + } + draw() { + this.context.beginPath(); + this.context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI*2, this.color); + this.context.strokeStyle = "grey"; + this.context.lineWidth = 15; + this.context.fillStyle = this.color; + this.context.fill(); + this.context.stroke(); + this.context.closePath(); + } + clickCircle(xmouse, ymouse) { + const distance = Math.sqrt((xmouse - this.xpos) * (xmouse - this.xpos) + (ymouse - this.ypos) * (ymouse - this.ypos)); + if (distance <= this.radius) { + return true; + } + return false; + } + changeColor (newColor) { + this.color = newColor; + this.draw(); + } +} + + +let circle = new Circle(ctx, 200, 200, 100, "blue"); +circle.draw(ctx); +canvas.addEventListener("click", (event) => { +// console.log(event); +// console.log("clicked canvas"); + const rect = canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + if (circle.clickCircle(x, y)) { + circle.changeColor("red"); + } else { + circle.changeColor("blue"); + } +// console.log(rect); +}); diff --git a/web/learn_canvas/canvas_btns/example.js b/web/learn_canvas/canvas_btns/example.js new file mode 100644 index 0000000..0722613 --- /dev/null +++ b/web/learn_canvas/canvas_btns/example.js @@ -0,0 +1,121 @@ +var canvas = document.getElementById('canvas'), + context = canvas.getContext('2d'), + rubberbandDiv = document.getElementById('rubberbandDiv'), + resetButton = document.getElementById('resetButton'), + image = new Image(), + mousedown = {}, + rubberbandRectangle = {}, + dragging = false; + +// Functions.......................................................... + +function rubberbandStart(x, y) { + mousedown.x = x; + mousedown.y = y; + + rubberbandRectangle.left = mousedown.x; + rubberbandRectangle.top = mousedown.y; + + moveRubberbandDiv(); + showRubberbandDiv(); + + dragging = true; +} + +function rubberbandStretch(x, y) { + rubberbandRectangle.left = x < mousedown.x ? x : mousedown.x; + rubberbandRectangle.top = y < mousedown.y ? y : mousedown.y; + + rubberbandRectangle.width = Math.abs(x - mousedown.x), + rubberbandRectangle.height = Math.abs(y - mousedown.y); + + moveRubberbandDiv(); + resizeRubberbandDiv(); +} + +function rubberbandEnd() { + var bbox = canvas.getBoundingClientRect(); + + try { + context.drawImage(canvas, + rubberbandRectangle.left - bbox.left, + rubberbandRectangle.top - bbox.top, + rubberbandRectangle.width, + rubberbandRectangle.height, + 0, 0, canvas.width, canvas.height); + } + catch (e) { + // Suppress error message when mouse is released + // outside the canvas + } + + resetRubberbandRectangle(); + + rubberbandDiv.style.width = 0; + rubberbandDiv.style.height = 0; + + hideRubberbandDiv(); + + dragging = false; +} + +function moveRubberbandDiv() { + rubberbandDiv.style.top = rubberbandRectangle.top + 'px'; + rubberbandDiv.style.left = rubberbandRectangle.left + 'px'; +} + +function resizeRubberbandDiv() { + rubberbandDiv.style.width = rubberbandRectangle.width + 'px'; + rubberbandDiv.style.height = rubberbandRectangle.height + 'px'; +} + +function showRubberbandDiv() { + rubberbandDiv.style.display = 'inline'; +} + +function hideRubberbandDiv() { + rubberbandDiv.style.display = 'none'; +} + +function resetRubberbandRectangle() { + rubberbandRectangle = { top: 0, left: 0, width: 0, height: 0 }; +} + +// Event handlers..................................................... + +canvas.onmousedown = function (e) { + var x = e.clientX, + y = e.clientY; + + e.preventDefault(); + rubberbandStart(x, y); +}; + +window.onmousemove = function (e) { + var x = e.clientX, + y = e.clientY; + + e.preventDefault(); + if (dragging) { + rubberbandStretch(x, y); + } +}; + +window.onmouseup = function (e) { + e.preventDefault(); + rubberbandEnd(); +}; + +image.onload = function () { + context.drawImage(image, 0, 0, canvas.width, canvas.height); +}; + +resetButton.onclick = function(e) { + context.clearRect(0, 0, context.canvas.width, + context.canvas.height); + context.drawImage(image, 0, 0, canvas.width, canvas.height); +}; + +// Initialization..................................................... + +image.src = 'curved-road.png'; \ No newline at end of file diff --git a/web/learn_canvas/canvas_btns/index.html b/web/learn_canvas/canvas_btns/index.html new file mode 100644 index 0000000..9509727 --- /dev/null +++ b/web/learn_canvas/canvas_btns/index.html @@ -0,0 +1,43 @@ + + + + + Title + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/learn_canvas/canvas_btns/main.js b/web/learn_canvas/canvas_btns/main.js new file mode 100644 index 0000000..be07ddb --- /dev/null +++ b/web/learn_canvas/canvas_btns/main.js @@ -0,0 +1,11 @@ +let canvas = document.getElementById("viewport"); +let ctx = canvas.getContext("2d"); + +//var win_height = 600; +//var win_width = 800; + +canvas.height = 600; +canvas.width = 800; +console.log(canvas.width, canvas.height); + +canvas.style.background = "#bbf"; \ No newline at end of file diff --git a/web/learn_canvas/canvas_btns/style.css b/web/learn_canvas/canvas_btns/style.css new file mode 100644 index 0000000..c9b2bbf --- /dev/null +++ b/web/learn_canvas/canvas_btns/style.css @@ -0,0 +1,18 @@ +#container +{ + height: 400px; + position: relative; + width: 400px; +} +#viewport +{ + height: 100%; + width: 100%; +} +#controls +{ + bottom: 0; + left: 0; + position: absolute; + width: 100%; +} \ No newline at end of file diff --git a/web/learn_canvas/canvas_btns/test.html b/web/learn_canvas/canvas_btns/test.html new file mode 100644 index 0000000..9de2318 --- /dev/null +++ b/web/learn_canvas/canvas_btns/test.html @@ -0,0 +1,77 @@ + + + + Bouncing Balls + + + + + +
+

Bouncing Balls

+ +

One hundred balls bouncing

+ + Start +
+ + + Canvas not supported + + + + + diff --git a/web/learn_canvas/canvas_btns/test2.html b/web/learn_canvas/canvas_btns/test2.html new file mode 100644 index 0000000..b456738 --- /dev/null +++ b/web/learn_canvas/canvas_btns/test2.html @@ -0,0 +1,47 @@ + + + + Rubber bands with layered elements + + + + + +
+ +
+ +
+ + + Canvas not supported + + + + + \ No newline at end of file diff --git a/web/multi_layers.html b/web/multi_layers.html new file mode 100644 index 0000000..1311a77 --- /dev/null +++ b/web/multi_layers.html @@ -0,0 +1,24 @@ + + + + + Title + + + + + +
+ + +
+ + + \ No newline at end of file diff --git a/web/multi_layers/index.html b/web/multi_layers/index.html new file mode 100644 index 0000000..3c0cfb8 --- /dev/null +++ b/web/multi_layers/index.html @@ -0,0 +1,11 @@ + + + + + Title + + + + + + \ No newline at end of file diff --git a/web/multi_layers/main.js b/web/multi_layers/main.js new file mode 100644 index 0000000..5aa6458 --- /dev/null +++ b/web/multi_layers/main.js @@ -0,0 +1,60 @@ +let canvas = document.getElementById("canvas"); +let ctx = canvas.getContext("2d"); + +var win_height = window.innerHeight; +var win_width = window.innerWidth; + +canvas.height = win_height; +canvas.width = win_width; +console.log(canvas.width, canvas.height); + +canvas.style.background = "#bbf"; + + +class Circle { + constructor(context, xpos, ypos, radius, color) { + this.context = context; + this.xpos = xpos; + this.ypos = ypos; + this.radius = radius; + this.color = color; + } + draw() { + this.context.beginPath(); + this.context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI*2, this.color); + this.context.strokeStyle = "grey"; + this.context.lineWidth = 15; + this.context.fillStyle = this.color; + this.context.fill(); + this.context.stroke(); + this.context.closePath(); + } + clickCircle(xmouse, ymouse) { + const distance = Math.sqrt((xmouse - this.xpos) * (xmouse - this.xpos) + (ymouse - this.ypos) * (ymouse - this.ypos)); + if (distance <= this.radius) { + return true; + } + return false; + } + changeColor (newColor) { + this.color = newColor; + this.draw(); + } +} + + +let circle = new Circle(ctx, 200, 200, 100, "blue"); +circle.draw(ctx); +canvas.addEventListener("click", (event) => { +// console.log(event); +// console.log("clicked canvas"); + const rect = canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + if (circle.clickCircle(x, y)) { + circle.changeColor("red"); + } else { + circle.changeColor("blue"); + } +// console.log(rect); +}); -- cgit v1.2.3