Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
06676ec
added notes file
Jameson789 Sep 25, 2025
489532b
added notes
oakes777 Sep 25, 2025
9a4667b
added boilerplate express server
Jameson789 Sep 25, 2025
344f865
Server running
Jameson789 Sep 25, 2025
bcf02ab
updated Node version and added mysql2
Jameson789 Sep 25, 2025
9f360b8
Cleaning app.js
Jameson789 Oct 2, 2025
4213dee
changes to package.json
oakes777 Oct 2, 2025
f83dfd2
Changed h1 on home.ejs
Jameson789 Oct 2, 2025
c629a54
Added .env to gitignore and added more notes
Jameson789 Oct 2, 2025
e17a3af
added db.js
Jameson789 Oct 2, 2025
122ec28
Reconfig app.js to support mysql connection
Jameson789 Oct 2, 2025
11d7c61
added test route to read from database
Jameson789 Oct 2, 2025
f3e32ac
removed mariadb
Jameson789 Oct 7, 2025
83da097
changing gitignore to hide .env
Jameson789 Oct 7, 2025
fa62842
Merge branch 'test'
Jameson789 Oct 7, 2025
24993d2
new package-lock
Jameson789 Oct 7, 2025
cfc1669
wtf
oakes777 Oct 7, 2025
c5392e9
Added basic frontend functionality
Jameson789 Oct 7, 2025
07d0f0f
removed trailing comma from grid array
oakes777 Oct 9, 2025
136ea18
cleaned up "scripts"
oakes777 Oct 9, 2025
42e8707
adding drag and color fxn to grid.js
oakes777 Oct 9, 2025
2efca46
Fixed local dev issue with nodemon exiting
Jameson789 Oct 9, 2025
4512dd4
Merge branch 'test' of https://github.com/Jameson789/Pixel-to-Pattern…
Jameson789 Oct 9, 2025
e377203
Added grid resizeablility to grid.js
Jameson789 Oct 9, 2025
534129a
added grid resize controls to home.ejs
Jameson789 Oct 9, 2025
d98c892
added grid resizing funcition
Jameson789 Oct 9, 2025
e5f9f9f
added drag.color to grid.js. this is on branch test. main content now…
oakes777 Oct 9, 2025
9120468
added test.sql db file
oakes777 Oct 14, 2025
caa2b84
added instructions.js for pattern gen and transmit to db
oakes777 Oct 14, 2025
f32e92f
added pattern.js to calcuate basic crochet pattern
Jameson789 Oct 14, 2025
897b0e6
Merge branch 'test' of https://github.com/Jameson789/Pixel-to-Pattern…
Jameson789 Oct 14, 2025
d99598a
added 1mb clause in app.js
oakes777 Oct 14, 2025
f9b7fc3
added POST function to app.js
oakes777 Oct 14, 2025
1e5342a
updated pattern.js to show pattern under generate pattern button.
Jameson789 Oct 14, 2025
62f3b7f
Merge branch 'test' of https://github.com/Jameson789/Pixel-to-Pattern…
Jameson789 Oct 14, 2025
c33a7c6
created sprint2notes.md file
oakes777 Oct 14, 2025
c9c22eb
added save button and label input box
Jameson789 Oct 14, 2025
f6c4e56
Merge branch 'test' into dbtest
oakes777 Oct 14, 2025
2904ce8
fixed pattern.js
oakes777 Oct 14, 2025
84c8862
added naming fxn to home.ejs and pattern.js
oakes777 Oct 14, 2025
0521b3f
merged sprint1notes and sprint2notes into README and edited for easy …
oakes777 Oct 14, 2025
3338c33
Added patterns.ejs and links between pages
Jameson789 Oct 15, 2025
15d69fc
Merge branch 'test' of https://github.com/Jameson789/Pixel-to-Pattern…
Jameson789 Oct 15, 2025
5537899
finished merge conflicts
Jameson789 Oct 15, 2025
d14961a
updates patterns route to select from db
Jameson789 Oct 15, 2025
76e6887
added rendering for completed patterns on pattern.js
Jameson789 Oct 16, 2025
a47aa9c
added patterns.css to style db results
Jameson789 Oct 16, 2025
b9a4e0f
styling changes
Jameson789 Oct 16, 2025
f670854
cleaned app.js
Jameson789 Oct 16, 2025
06cf25e
fixed app.js
Jameson789 Oct 16, 2025
bb8407b
Merge branch 'test'
Jameson789 Oct 16, 2025
10b003b
app.js rework
Jameson789 Oct 16, 2025
2b3db4a
reworked post route for better understanding
Jameson789 Oct 16, 2025
a983d9b
pattern.js simplified
Jameson789 Oct 16, 2025
55f972c
edited grid.js and home to work better with pattern.js
Jameson789 Oct 16, 2025
236cc4f
changed addEventListeners
Jameson789 Oct 16, 2025
e3e79ab
Merge branch 'test'
Jameson789 Oct 16, 2025
73baf7c
removed instrustions.js
Jameson789 Oct 20, 2025
90025cc
Merge branch 'test'
Jameson789 Oct 20, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
.env
211 changes: 133 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,135 @@
Project Name: Pixel to Pattern

Tagline: Create your perfect tapestry

Target Users: Beginner- Advanced crocheters



Feature Breakdown

MVP Features:

Create: Pixel drawing to be converted
Pixel drawing is converted to pattern row by row:
Basically counting how many pixels in a row are a certain color.
EX: ( sc = single crochet)
Row 1: 28 sc (white)
Row 2: 9 sc (white), 10 sc (yellow), 9 sc (white)
Row 3: 8 sc (white), 10 sc (yellow), 9 sc (white)
Read: All the submitted patterns
Update: TBD
Delete: Delete pattern user has posted



Extended:

Comments under posts
Sidebar with links to crochet tutorials or pixel art tutorials



Data Model

Core Entities: Users, Posts, Comments

Key Relationships: Each post/comment has one User, can be viewed by all Users

CRUD Operations:

Create: Pixel drawings, comments

Read: All submitted drawings and comments

Update: TBD

Delete: Delete Patterns and comments



User Experience

User Flows:

Land on Home Page that includes:
posts from other users
sidebar with resources/ links
Floating plus button to post
Add Post Page:
Generic canvas generated with responsive input at top of page to change canvas size
Drawing tools to left of canvas:
Pencil (fills one pixel)
Color
Eraser
Fill Canvas
Clear Canvas
View Post Page
After User posts their canvas or clicks on post
Display image of pixel drawing
Underneath drawing, generated crochet pattern is written out





Madeleine Chance



Software Development and Data Analytics Student, Green River College
Target Users: Beginner – Advanced crocheters

ORIGINAL PLAN

* Feature Breakdown (MVP)

* Create: user paints a pixel drawing that is converted to a crochet pattern row-by-row (count stitches per color).
Example (sc = single crochet):
Row 1: 28 sc (white)
Row 2: 9 sc (white), 10 sc (yellow), 9 sc (white)
Row 3: 8 sc (white), 10 sc (yellow), 9 sc (white)
* Read: view all submitted patterns
* Update: TBD
* Delete: remove a pattern the user posted
* Extended Ideas

* Comments under posts
* Sidebar with links to crochet or pixel-art tutorials
* Data Model (initial concept)

* Core Entities: Users, Posts, Comments
* Relationships: each post/comment belongs to one user; everyone can view
* CRUD: create pixel drawings and comments; read all; update TBD; delete patterns and comments
* User Experience (planned)

* Home Page: feed of posts, sidebar resources, floating + to post
* Add Post: responsive canvas size (width/height independent), tools (pencil, color, eraser, fill, clear)
* View Post: show pixel image; underneath, generated crochet pattern text
* Credits

* Madeleine Chance, Software Development and Data Analytics Student, Green River College

SPRINT1 WORK

* Direction

* Build a grid where users choose size (1–50 by 1–50), select basic colors, and paint pixel-by-pixel.
* Backend will convert the pixel grid into a crochet pattern.
* Milestones

1. Hello World in Node
2. Deploy the app
3. Set up MySQL
4. Connect using a pool from code
5. Build the frontend
* Front End

* Variable grid (1–50 x 1–50)
* Sprint goal: save a generated pattern to the database with a label
* Extras considered: DB view page, sticky header with grid-size inputs and logo/index title
* Back End

* Frontend connects to DB (Workbench used during setup)
* Data fields for initial persistence: ID, Label, pattern saved as an array (early concept before final Sprint 2 schema)

SPRINT2 WORK

* What we shipped

* Grid UX: resizable grid; palette; click + drag paints straight rows or columns (axis locks on first move)
* Pattern generation (client): reads DOM cells and produces row-by-row RLE text (example: Row 1: 9W 10Y 9W)
* Persistence (server): POST /api/patterns stores { id, name, instructions }; GET /api/patterns/:id fetches a saved pattern
* Branches

* test: grid drag-to-paint feature
* dbtest: POST instructions route wired to DB in app.js
* main: unchanged during this sprint
* Database and environment (current)

* test.sql
CREATE TABLE IF NOT EXISTS patterns (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
instructions MEDIUMTEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
* .env
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=p2p_user
DB_PASS=sulesule
DB_NAME=p2p_db
HOST=0.0.0.0
PORT=3000
* Note: DB_HOST=127.0.0.1 assumes app and DB run on the same machine (works on each MacBook and on the VM when both app and DB run there)
* App routes (in dbtest)

* POST /api/patterns → insert { name, instructions }
* GET /api/patterns/:id → return { id, name, instructions, created_at }
* GET /api/patterns → list recent (dev helper)
* GET /health/db → simple MySQL connectivity check
* Frontend wiring

* views/home.ejs includes grid controls, palette, grid, a Generate Pattern button
* Scripts load in order: grid.js then pattern.js
* pattern.js reads .cell colors → builds RLE rows for on-page preview → requires a name → POSTs { name, instructions } to /api/patterns
* How to run (local or VM)

* Switch to branch with POST route:
git checkout dbtest
git pull --rebase
* Install dependencies:
npm install
* Ensure DB table exists on each machine:
mysql -u p2p_user -p p2p_db < test.sql
* Start the server:
npm run dev
or
npm start
* Open the app:
[http://localhost:3000](http://localhost:3000) (or VM_IP:3000 if accessing remotely)
* Smoke tests

1. Open /health/db → expect {"db":"ok","result":1}
2. Generate grid; paint with click-drag rows/columns; white erases
3. Click Generate Pattern to see preview, enter a name, click Save Pattern → alert shows saved ID
4. Visit /api/patterns/ID → expect JSON { id, name, instructions, created_at }
5. Optional cURL insert:
curl -s -X POST [http://localhost:3000/api/patterns](http://localhost:3000/api/patterns)
-H 'Content-Type: application/json'
-d '{"name":"Smoke Test","instructions":"Row 1: 10W"}'
* Known limits at end of Sprint 2

* Instructions are top-to-bottom RLE (no RS/WS alternating yet)
* No authentication; patterns are readable by ID
* Only { id, name, instructions } are stored (grid and palette not persisted yet)
* Next sprint candidates

* RS/WS alternating, bottom-up reading; left-handed mode option
* Save/load full charts (persist grid + palette)
* TXT/PDF export and shareable read-only view
* Auth and “My Patterns”; edit/delete
* Clear, Undo/Redo, freehand mode, Shift for straight lines
71 changes: 71 additions & 0 deletions app.js
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This server entry point file is done very well. Organized well and is very easy to read. good job!

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import express from 'express';
import pool from './db.js';

const PORT = process.env.PORT || 3000;
const HOST = process.env.HOST || 'localhost';

const app = express();

app.use(express.json({ limit: '1mb'}));
app.use(express.urlencoded({ extended: false }));
app.use(express.static("public"));
app.set('view engine', 'ejs');

app.get('/', (req, res) => res.render('home'));

app.get("/patterns", async (req, res) => {
let rows = [];
let error = null;

try {
const [result] = await pool.query(
"SELECT id, name, instructions, created_at FROM patterns ORDER BY id DESC"
);
rows = result;
} catch (err) {
console.error(err);
}

res.render("patterns", { patterns: rows, error });
});

app.get('/health/db', async (_req, res) => {
try {
const [rows] = await pool.query('SELECT 1 AS ok');
res.json({ db: 'ok', result: rows[0].ok });
} catch (err) {
console.error(err);
res.status(500).json({ db: 'error', message: err.message });
}
});

app.get('/ping', async (_req, res) => {
const [rows] = await pool.query('SELECT * FROM ping ORDER BY id DESC LIMIT 5');
res.json(rows);
});

app.post('/api/patterns', async (req, res) => {
const name = req.body.name ? req.body.name.trim() : '';
const instructions = req.body.instructions || '';

if (!name) {
return res.status(400).json({ error: 'name is required' });
}

try {
const [result] = await pool.query(
'INSERT INTO patterns (name, instructions) VALUES (?, ?)',
[name, instructions]
);

res.status(201).json({ id: result.insertId, name });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'insert failed' });
}
});


app.listen(PORT, HOST, () => {
console.log(`Running on http://${HOST}:${PORT}`);
});
15 changes: 15 additions & 0 deletions db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'dotenv/config';
import mysql from 'mysql2/promise';

const pool = mysql.createPool({
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT || 3306),
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
});

export default pool;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the simplicity of the db

Loading