Skip to content

Commit

Permalink
Merge pull request #5 from szres/add-glyph-draw-guess
Browse files Browse the repository at this point in the history
add glyph draw guess
  • Loading branch information
Nigh committed Apr 22, 2024
2 parents ba65fd8 + 1ab10fd commit 6aae807
Show file tree
Hide file tree
Showing 5 changed files with 728 additions and 68 deletions.
185 changes: 131 additions & 54 deletions src/routes/Glyph.svelte
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<script>
import { onMount } from 'svelte';
import { beforeUpdate } from 'svelte';
import { GlyphEffect } from './glyphParticle.js';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
export let width = 64;
export let height = 64;
export let background = '#0000';
export let outlineColor = '#47df';
export let glyph = '';
export let drawable = false;
export let guess = { points: '', name: '-', score: 0 };
let cx = width / 2;
let cy = height / 2;
Expand All @@ -30,7 +36,54 @@
t: { dx: -Math.cos(Math.PI / 6) * R * glyphK2, dy: -Math.sin(Math.PI / 6) * R * glyphK2 },
a: { dx: 0, dy: 0 }
};
const segmentNormalize = (segment) => {
segment = segment.toLowerCase().substring(0, 2);
let c0 = segment.charAt(0);
let c1 = segment.charAt(1);
if (c1 > c0) {
return segment;
} else {
return c1 + c0;
}
};
const segmentsFromPoints = (points) => {
if (points.length > 1) {
let segments = [];
for (let index = 0; index < points.length - 1; index++) {
segments.push(segmentNormalize(points.substring(index, index + 2)));
}
return segments;
}
return [];
};
let glyphJson = {};
const glyphJsonLoad = async () => {
let response = await fetch('glyphs.json');
glyphJson = await response.json();
for (const key in glyphJson) {
glyphJson[key].segments = segmentsFromPoints(glyphJson[key].glyph);
}
};
const guessGlyphFromSegments = (segments) => {
let guessed = [];
for (const key in glyphJson) {
let score = 0;
segments.forEach((segment) => {
if (glyphJson[key].segments.includes(segment)) {
score++;
} else {
score--;
}
});
score /= glyphJson[key].segments.length;
guessed.push({ name: glyphJson[key].name, score, points: glyphJson[key].glyph });
}
guessed.sort((a, b) => b.score - a.score);
if (guessed.length > 0 && guessed[0].score > 0) {
return guessed[0];
}
return { name: '-', score: 0, points: '' };
};
let canvas;
let ctx_render;
let touchTop, touchLeft;
Expand All @@ -42,10 +95,47 @@
let effect;
let effect_update;
let glyph_render;
const drawGlyph = (points) => {
ctx_draw.reset();
ctx_draw.strokeStyle = '#eee';
ctx_draw.lineWidth = 2;
ctx_draw.beginPath();
points.split('').forEach((g) => {
if (glyphPoints[g]) {
ctx_draw.lineTo(cx + glyphPoints[g].dx, cy + glyphPoints[g].dy);
} else {
if (g === '-') {
ctx_draw.closePath();
}
}
});
ctx_draw.stroke();
ctx_render.reset();
ctx_render.drawImage(layer_bg, 0, 0, width, height);
ctx_render.drawImage(layer_draw, 0, 0, width, height);
};
let ready = false;
beforeUpdate(() => {
if (!ready || drawable) {
return;
}
drawGlyph(glyph);
});
onMount(() => {
if (width < 32 || height < 32) {
console.assert(false, 'Glyph must be at least 32x32');
}
if (drawable) {
glyphJsonLoad();
canvas.addEventListener('mousedown', drawStart);
canvas.addEventListener('touchstart', drawStartOnTouch);
canvas.addEventListener('mouseup', drawEnd);
canvas.addEventListener('touchend', drawEnd);
canvas.addEventListener('mouseleave', drawEnd);
canvas.addEventListener('mousemove', drawMove);
canvas.addEventListener('touchmove', drawMoveOnTouch);
}
ctx_render = canvas.getContext('2d');
layer_bg.width = width;
layer_bg.height = height;
Expand All @@ -55,7 +145,7 @@
layer_effect.height = height;
ctx_bg.lineWidth = 2;
ctx_bg.strokeStyle = '#47df';
ctx_bg.strokeStyle = outlineColor;
let hexagon = [
{ dx: 0, dy: -R },
{ dx: +Math.cos(Math.PI / 6) * R, dy: -Math.sin(Math.PI / 6) * R },
Expand All @@ -79,30 +169,17 @@
ctx_bg.closePath();
ctx_bg.stroke();
}
if (!drawable) {
ctx_bg.strokeStyle = '#eee';
ctx_bg.lineWidth = 2;
ctx_bg.beginPath();
glyph.split('').forEach((g) => {
if (glyphPoints[g]) {
ctx_bg.lineTo(cx + glyphPoints[g].dx, cy + glyphPoints[g].dy);
} else {
if (g === '-') {
ctx_bg.closePath();
}
}
});
ctx_bg.stroke();
} else {
ctx_bg.save();
if (drawable) {
ctx_render.drawImage(layer_bg, 0, 0, width, height);
const { top, left } = canvas.getBoundingClientRect();
touchTop = top;
touchLeft = left;
effect = new GlyphEffect(layer_effect);
effect_update = effect.updater();
glyph_render = glyphDrawRender();
}
ctx_bg.save();
ctx_render.drawImage(layer_bg, 0, 0, width, height);
ready = true;
return () => {
if (glyph_render) {
glyph_render.stop();
Expand All @@ -112,7 +189,8 @@
let isDrawing = false;
let currentPointOn = '';
let sequenceDrawed = '';
let pointDrawed = '';
let segmentsDrawed = [];
let lastCheckStep = {};
let drawHue = 0;
let drawWidth = 0;
Expand All @@ -138,14 +216,24 @@
ctx_draw.closePath();
ctx_draw.stroke();
}
if (!sequenceDrawed.includes(key)) {
if (!pointDrawed.includes(key)) {
ctx_draw.fillStyle = `hsla(` + `${drawHue}` + `,90%,72%,100%)`;
ctx_draw.arc(cx + dx, cy + dy, drawWidth * 0.6, 0, 2 * Math.PI);
ctx_draw.fill();
}
currentPointOn = key;
sequenceDrawed += key;
if (sequenceDrawed.length >= 32) drawEnd();
pointDrawed += key;
segmentsDrawed = segmentsFromPoints(pointDrawed);
if (segmentsDrawed.length >= 1) {
let guessNew = guessGlyphFromSegments(segmentsDrawed);
if (guessNew.name !== guess.name) {
guess = guessNew;
dispatch('newGuess', {
guess: guess
});
}
}
if (pointDrawed.length >= 32) drawEnd();
break;
}
}
Expand Down Expand Up @@ -190,7 +278,8 @@
isDrawing = true;
lastCheckStep = { x, y };
drawPos = { x, y };
sequenceDrawed = '';
pointDrawed = '';
segmentsDrawed = [];
currentPointOn = '';
drawHue = 0;
drawWidth = lineWidth * 2;
Expand All @@ -201,8 +290,21 @@
drawCheck({ offsetX: x, offsetY: y });
glyph_render.start();
};
const drawStartOnTouch = (e) => {
const { clientX, clientY } = e.touches[0];
drawStart({
offsetX: clientX - touchLeft,
offsetY: clientY - touchTop
});
};
const drawEnd = () => {
isDrawing = false;
if (guess.score > 0) {
dispatch('newResult', {
result: guess
});
}
guess = { points: '', name: '-', score: 0 };
};
const drawMove = ({ offsetX: x1, offsetY: y1 }) => {
if (!isDrawing) return;
Expand All @@ -216,38 +318,13 @@
}
}
};
</script>

<canvas
class="self-center"
{width}
{height}
style:background
bind:this={canvas}
on:mousedown={drawStart}
on:touchstart={(e) => {
const { clientX, clientY } = e.touches[0];
drawStart({
offsetX: clientX - touchLeft,
offsetY: clientY - touchTop
});
}}
on:mouseup={drawEnd}
on:touchend={drawEnd}
on:mouseleave={drawEnd}
on:mousemove={drawMove}
on:touchmove={(e) => {
const drawMoveOnTouch = (e) => {
const { clientX, clientY } = e.touches[0];
drawMove({
offsetX: clientX - touchLeft,
offsetY: clientY - touchTop
});
}}
/>
{#if drawable}
<div>
<span>
{sequenceDrawed}
</span>
</div>
{/if}
};
</script>

<canvas class="self-center" {width} {height} style:background bind:this={canvas} />
20 changes: 20 additions & 0 deletions src/routes/GlyphDraw.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<script>
import Glyph from './Glyph.svelte';
let guess = { points: '', name: '-', score: 0 };
</script>

<div class="flex justify-center pb-2">
<div class="flex flex-col">
<Glyph glyph={guess.points} />
<span class="text-center">{guess.name}</span>
</div>
</div>
<div class="flex justify-center">
<Glyph
width="500"
height="500"
drawable="true"
on:newGuess={(e) => (guess = e.detail.guess)}
on:newResult
/>
</div>
7 changes: 3 additions & 4 deletions src/routes/glyphParticle.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ export class GlyphEffect {
x: -9999,
y: -9999
};
console.log('this.context', this.context);
}

spawn(x, y, type = 'fast') {
Expand Down Expand Up @@ -136,11 +135,11 @@ export class GlyphEffect {
particle.draw(bufferContext);
}

context.filter = `none`;
context.filter = `blur(1px) opacity(75%)`;
context.drawImage(buffer, 0, 0);
context.filter = `blur(11px)`;
context.drawImage(buffer, 0, 0);
context.filter = `blur(10px)`;
context.drawImage(buffer, 0, 0);
context.filter = 'none';
return particles.length;
};
return update;
Expand Down
46 changes: 36 additions & 10 deletions src/routes/overclock.svelte
Original file line number Diff line number Diff line change
@@ -1,16 +1,42 @@
<script>
import Glyph from './Glyph.svelte';
import GlyphDraw from './GlyphDraw.svelte';
let predictionDepth = 5;
let predictions = [
{ name: '', points: '' },
{ name: '', points: '' },
{ name: '', points: '' },
{ name: '', points: '' },
{ name: '', points: '' }
];
const newPrediction = () => {
predictions = [];
for (let index = 0; index < predictionDepth; index++) {
predictions = [...predictions, { name: '', points: '' }];
}
};
const writePrediction = (c) => {
for (let index = 0; index < predictionDepth; index++) {
if (predictions[index].name === '') {
predictions[index] = c;
predictions = predictions;
return;
}
}
newPrediction();
writePrediction(c);
};
const onNewResult = (e) => {
let result = e.detail.result;
writePrediction(result);
};
</script>

<div class="grid grid-flow-row gap-4 h-max m-4 justify-center content-center">
<ul class="steps">
<li data-content="?" class="step step-neutral"><Glyph glyph="bhcjd" />DEFEND</li>
<li data-content="?" class="step step-neutral"><Glyph glyph="trjch-" />HUMAN</li>
<li data-content="?" class="step step-neutral"><Glyph glyph="bthjrd" />CIVILIZATION</li>
<li data-content="?" class="step step-neutral"><Glyph glyph="lhtmrjk" />SHAPERS</li>
<li data-content="?" class="step step-neutral"><Glyph glyph="htajra" />LIE</li>
</ul>
<div>
<Glyph width="500" height="500" drawable="true" />
<div class="flex flex-col h-max m-4">
<div class="flex justify-center mb-4">
{#each predictions as prediction}
<Glyph glyph={prediction.points} />
{/each}
</div>
<GlyphDraw on:newResult={onNewResult} />
</div>
Loading

0 comments on commit 6aae807

Please sign in to comment.