Skip to content

Commit

Permalink
working webworker version
Browse files Browse the repository at this point in the history
  • Loading branch information
bakedPotatoLord committed Sep 16, 2024
1 parent 30147bb commit 4aa4d7c
Show file tree
Hide file tree
Showing 6 changed files with 271 additions and 188 deletions.
6 changes: 3 additions & 3 deletions src/HexNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class HexNode extends Node{
super(x,y,parent)
}

draw(ctx:CanvasRenderingContext2D,blockSize:number){
draw(ctx:OffscreenCanvasRenderingContext2D,blockSize:number){

//this.y is a lie

Expand Down Expand Up @@ -39,7 +39,7 @@ export default class HexNode extends Node{

}

drawWallBetween(el:Node,ctx:CanvasRenderingContext2D,blockSize:number){
drawWallBetween(el:Node,ctx:OffscreenCanvasRenderingContext2D,blockSize:number){
let wallLength = (blockSize/2)* (1 / Math.cos(Math.PI/6))
ctx.save()
ctx.translate(this.x,this.y)
Expand Down Expand Up @@ -78,7 +78,7 @@ export default class HexNode extends Node{
)
}

drawLineTo(node:Node,ctx:CanvasRenderingContext2D){
drawLineTo(node:Node,ctx:OffscreenCanvasRenderingContext2D){
ctx.beginPath()
ctx.moveTo(this.x,this.y*(Math.sqrt(3) / 2 ))
ctx.lineTo(node.x,node.y*(Math.sqrt(3) / 2 ))
Expand Down
6 changes: 3 additions & 3 deletions src/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default class Node{
this.parent = parent
}

topLine(ctx:CanvasRenderingContext2D,blockSize:number){
topLine(ctx:OffscreenCanvasRenderingContext2D,blockSize:number){
console.log('topline called')
ctx.strokeStyle = 'black'

Expand All @@ -34,7 +34,7 @@ export default class Node{
ctx.stroke()
}

draw(ctx:CanvasRenderingContext2D,blockSize:number){
draw(ctx:OffscreenCanvasRenderingContext2D,blockSize:number){
if(this.isStartingNode){
ctx.fillStyle = "green"
}else if(this.isEndingNode){
Expand Down Expand Up @@ -84,7 +84,7 @@ export default class Node{
)
}

drawLineTo(node:Node,ctx:CanvasRenderingContext2D){
drawLineTo(node:Node,ctx:OffscreenCanvasRenderingContext2D){
ctx.beginPath()
ctx.moveTo(this.x,this.y)
ctx.lineTo(node.x,node.y)
Expand Down
6 changes: 3 additions & 3 deletions src/TriNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default class TriNode extends Node{
super(x,y,parent)
}

draw(ctx:CanvasRenderingContext2D,blockSize:number){
draw(ctx:OffscreenCanvasRenderingContext2D,blockSize:number){

//this.y is a lie

Expand Down Expand Up @@ -45,7 +45,7 @@ export default class TriNode extends Node{
}


drawWallBetween(el:Node,ctx:CanvasRenderingContext2D,blockSize:number){
drawWallBetween(el:Node,ctx:OffscreenCanvasRenderingContext2D,blockSize:number){
let wallLength = (blockSize/2)* (1 / Math.cos(Math.PI/6))
ctx.save()
ctx.translate(this.x,this.y)
Expand Down Expand Up @@ -81,7 +81,7 @@ export default class TriNode extends Node{
)
}

drawLineTo(node:Node,ctx:CanvasRenderingContext2D){
drawLineTo(node:Node,ctx:OffscreenCanvasRenderingContext2D){
ctx.beginPath()
ctx.moveTo(this.x,this.y*(Math.sqrt(3) / 2 ))
ctx.lineTo(node.x,node.y*(Math.sqrt(3) / 2 ))
Expand Down
260 changes: 82 additions & 178 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import Node from "./Node"
import rdfs from "./rdfs"
import { getEndingNode, getStartingNode, makeHexNodeMap, makeSquareNodeMap, makeTriNodeMap} from "./helpers"
import bfs from "./bfs"

import { startData, workerResponse } from "./workerGenerate"
import Worker from "./workerGenerate?worker"

let c = document.querySelector("canvas")
let ctx = c.getContext("2d")
Expand All @@ -11,208 +8,115 @@ let mazeOptions = <HTMLDivElement>document.querySelector('.mazeOptions')

ctx.fillStyle = "black"

// declare canvas vars
let cw:number
let ch:number
let blockSize:number
let numW:number
let numH :number

// declare graph algorithm vars
let nodes:Map<string,Node>
let startingNode:Node
let endingNode:Node

//extra vars
let mazeExists = false

function setup(width:number,heigth:number,blockSizeP:number,shape:number){
//set up
numH = heigth
numW = width
blockSize = blockSizeP
ch = c.height = heigth *blockSize
cw = c.width = width * blockSize
if(shape== 4){
nodes = makeSquareNodeMap(cw,ch,blockSize)
}else if(shape == 6){
nodes = makeHexNodeMap(cw,ch,blockSize)
ch = c.height = (heigth) * blockSize * (Math.sqrt(3)/2)
}else if(shape == 3){
nodes = makeTriNodeMap(cw,blockSize)
ch = c.height = (heigth) * blockSize * (Math.sqrt(3)/2)
}
//create start and end nodes
startingNode = getStartingNode(nodes)
startingNode.isStartingNode = true
endingNode = getEndingNode(nodes)
endingNode.isEndingNode = true
//do the grunt work
rdfs(nodes,startingNode,blockSize)
//draw it
requestAnimationFrame( draw )
}
async function doRealtimeGenerate(width: number, heigth: number, blockSize: number, shape: number){

function draw(){
ctx.fillStyle = 'white'
ctx.clearRect(0,0,cw,ch)
ctx.strokeStyle = 'black'
ctx.lineWidth = 2
ctx.fillRect(0,0,cw,ch)
ctx.beginPath
ctx.rect(1,1,cw-1,ch-1)
ctx.stroke()
//draw all node
nodes.forEach(el=>el.draw(ctx,blockSize))
//use breadth-first search because depth first will find "a" solutoion, but not "the" solutoin
bfs(startingNode,endingNode,nodes,blockSize,false)
const work = new Worker();


if(startingNode.type ==6){
ctx.save()
drawHexBorder('x')
if(numH%2 == 0){
ctx.translate(0,(ch)- blockSize - 1)
}else{
ctx.translate(-blockSize/2,(ch)- blockSize -1)
}
drawHexBorder('x',true)
ctx.restore()

ctx.save()
drawHexBorder('y')
ctx.translate(cw-blockSize,0)
drawHexBorder('y',true)
ctx.restore()
}
mazeExists = true
state.innerHTML = ''
mazeOptions.hidden = false
}
work.postMessage(<startData>{width, heigth, blockSize, shape})

function drawHexBorder(axis:'x'|'y', flip?:boolean){
work.onmessage = (e) => {
const {completion, state:workerState, done, imageData} = <workerResponse>e.data

let wallLength = (blockSize/2)* (1 / Math.cos(Math.PI/6))
let xDist = blockSize / 2
let yDist = blockSize/(2 * Math.sqrt(3))

let x= blockSize/2
let y = blockSize/4
ctx.beginPath()
ctx.moveTo(x,y)
if(axis == 'x'){
x=0
y= blockSize/2
ctx.moveTo(x,y)
let i = flip?1:0
while(x < cw+blockSize){
ctx.lineTo(x,y)
x+=xDist
y+= (i%2==0)?-yDist:yDist
i++
}
}else{
let i =flip?2:0
while(y < ch-yDist*4){
if(i%4 == 0){
x+= -xDist
y+= yDist
}else if(i%4 == 1){
x+= 0
y+= wallLength
}else if(i%4 == 2){
x+= xDist
y+= yDist
}else if(i%4 == 3){
x+= 0
y+= wallLength
}
ctx.lineTo(x,y)
i++
const formattedPercent = (completion*100).toFixed(2)+'%';
state.innerHTML = (workerState==='RDFS')?('RDFSing: '+formattedPercent):('drawing: '+formattedPercent)
if(done){
console.log("done",e.data);
work.terminate()
mazeExists = true
state.innerHTML = 'done'
c.width = width*blockSize
c.height = heigth*blockSize
console.log(c,width,blockSize)
ctx.putImageData(imageData, 0, 0)
}

}
ctx.stroke()

}


//form submission button
document.forms[0]
onsubmit= (e)=>{
onsubmit = (e) => {
e.preventDefault()
showSolution.checked = false
let data = (new FormData(<HTMLFormElement>e.target))
state.innerHTML = 'generating ...'
requestAnimationFrame(()=>{
try{
setup(
requestAnimationFrame(() => {
try {
doRealtimeGenerate(
parseFloat(data.get('width').toString()),
parseFloat(data.get('heigth').toString()),
parseFloat(data.get('cellSize').toString()),
parseFloat(data.get('shape').toString()),
)
}catch(err){
if(err[0]) alert(err[1])
} catch (err) {
if (err[0]) alert(err[1])
console.log(err)
return
}
})
}
//download button
(<HTMLButtonElement>document.querySelector('#d'))
.onclick = (e)=>{
e.preventDefault()
if(mazeExists){
let a = document.createElement('a')
document.body.appendChild(a)
a.href = c.toDataURL()
a.download = 'maze.png'
a.click()
}else{
alert('you need to generate your maze first bozo')
}
}
//show solution button
let showSolution = (<HTMLInputElement>document.querySelector('#showSolution'))
showSolution
.onclick = (e)=>{
//data validation
if(!mazeExists){
.onclick = (e) => {
e.preventDefault()
alert('you need to generate your maze first bozo')
return
}
//set line style based on
if((<HTMLInputElement>e.target).checked){
ctx.strokeStyle = 'blue'
}else{
ctx.strokeStyle = 'white'
}

//trace the parent path
let n = endingNode
if(n.type==6 || n.type == 3){
nodes.forEach(n=>n.y *= (Math.sqrt(3) / 2 ))
if (mazeExists) {
let a = document.createElement('a')
document.body.appendChild(a)
a.href = c.toDataURL()
a.download = 'maze.png'
a.click()
} else {
alert('you need to generate your maze first bozo')
}
}
//show solution button
// let showSolution = (<HTMLInputElement>document.querySelector('#showSolution'))
// showSolution
// .onclick = (e) => {
// //data validation
// if (!mazeExists) {
// e.preventDefault()
// alert('you need to generate your maze first bozo')
// return
// }
// //set line style based on
// if ((<HTMLInputElement>e.target).checked) {
// ctx.strokeStyle = 'blue'
// } else {
// ctx.strokeStyle = 'white'
// }

if((<HTMLInputElement>e.target).checked){
ctx.lineWidth = 2
}else{
ctx.lineWidth = 3.5
}

ctx.beginPath()
ctx.moveTo(n.x,n.y)
while(n.parent != undefined){

ctx.lineTo(n.parent.x,n.parent.y)
ctx.lineTo(n.x,n.y)
ctx.lineTo(n.parent.x,n.parent.y)
n = n.parent
}
ctx.stroke()
if(n.type==6 || n.type == 3){
nodes.forEach(n=>n.y /= (Math.sqrt(3) / 2 ))
}
//re-draw start and end nodes
startingNode.draw(ctx,blockSize)
endingNode.draw(ctx,blockSize)
}
// //trace the parent path
// let n = endingNode
// if (n.type == 6 || n.type == 3) {
// nodes.forEach(n => n.y *= (Math.sqrt(3) / 2))
// }

// if ((<HTMLInputElement>e.target).checked) {
// ctx.lineWidth = 2
// } else {
// ctx.lineWidth = 3.5
// }

// ctx.beginPath()
// ctx.moveTo(n.x, n.y)
// while (n.parent != undefined) {

// ctx.lineTo(n.parent.x, n.parent.y)
// ctx.lineTo(n.x, n.y)
// ctx.lineTo(n.parent.x, n.parent.y)
// n = n.parent
// }
// ctx.stroke()
// if (n.type == 6 || n.type == 3) {
// nodes.forEach(n => n.y /= (Math.sqrt(3) / 2))
// }
// //re-draw start and end nodes
// startingNode.draw(ctx, blockSize)
// endingNode.draw(ctx, blockSize)
// }
Loading

0 comments on commit 4aa4d7c

Please sign in to comment.