Skip to content

Commit d5b4feb

Browse files
authored
Merge pull request #36 from kc3hack/feature/33
ゲームアンサー画面作成
2 parents 88fd13e + 4c846ad commit d5b4feb

File tree

14 files changed

+464
-1
lines changed

14 files changed

+464
-1
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<script>
2+
import { onMount } from 'svelte'
3+
4+
export let width = 1000
5+
export let height = 650
6+
export let color = '#333'
7+
export let background = '#fff'
8+
9+
let canvas
10+
let context
11+
let isDrawing
12+
let start
13+
14+
let t, l
15+
let history = [] //Undo用
16+
onMount(() => {
17+
context = canvas.getContext('2d')
18+
context.lineWidth = 3
19+
20+
handleSize()
21+
saveState()
22+
})
23+
24+
$: if(context) {
25+
context.strokeStyle = color
26+
}
27+
28+
const handleStart = (({ offsetX: x, offsetY: y }) => {
29+
saveState() //これを描かなかったら機能しない
30+
if(color === background) {
31+
context.clearRect(0, 0, width, height)
32+
} else {
33+
isDrawing = true
34+
start = { x, y }
35+
}
36+
})
37+
38+
const handleEnd = () => { isDrawing = false }
39+
const handleMove = (({ offsetX: x1, offsetY: y1 }) => {
40+
if(!isDrawing) return
41+
42+
const { x, y } = start
43+
context.beginPath()
44+
context.moveTo(x, y)
45+
context.lineTo(x1, y1)
46+
context.closePath()
47+
context.stroke()
48+
49+
start = { x: x1, y: y1 }
50+
})
51+
52+
const handleSize = () => {
53+
const { top, left } = canvas.getBoundingClientRect()
54+
t = top
55+
l = left
56+
}
57+
//履歴を保存
58+
const saveState = () => {
59+
history.push(canvas.toDataURL())
60+
}
61+
62+
//Undo機能
63+
const undo = () => {
64+
if (history.length > 1) {
65+
history.pop() //最新の履歴を削除
66+
const lastState = history[history.length - 1] //一つ前の履歴を取得
67+
restoreCanvas(lastState)
68+
}
69+
}
70+
71+
// **キャンバスを復元**
72+
const restoreCanvas = (imageData) => {
73+
const img = new Image()
74+
img.src = imageData
75+
img.onload = () => {
76+
context.clearRect(0, 0, canvas.width, canvas.height)
77+
context.drawImage(img, 0, 0)
78+
}
79+
}
80+
</script>
81+
82+
<svelte:window on:resize={handleSize} />
83+
<canvas
84+
class="w-full h-full"
85+
style:background
86+
bind:this={canvas}
87+
on:mousedown={handleStart}
88+
on:touchstart={e => {
89+
const { clientX, clientY } = e.touches[0]
90+
handleStart({
91+
offsetX: clientX - l,
92+
offsetY: clientY - t
93+
})
94+
}}
95+
on:mouseup={handleEnd}
96+
on:touchend={handleEnd}
97+
on:mouseleave={handleEnd}
98+
on:mousemove={handleMove}
99+
on:touchmove={e => {
100+
const { clientX, clientY } = e.touches[0]
101+
handleMove({
102+
offsetX: clientX - l,
103+
offsetY: clientY - t
104+
})
105+
}}
106+
>
107+
</canvas>
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<script>
2+
import { createEventDispatcher } from 'svelte';
3+
const dispatch = createEventDispatcher();
4+
5+
let colors = [
6+
'#d58141',
7+
'#d7c44c',
8+
'#4fa9cc',
9+
'#3f8d27',
10+
]
11+
12+
let paletteColor = colors[0]
13+
let background = '#fff'
14+
</script>
15+
16+
<div>
17+
{#each colors as color}
18+
<button
19+
on:click="{() => {
20+
dispatch('color', { color })
21+
paletteColor = color
22+
}}"
23+
style:background={color}
24+
class="w-10 h-10"
25+
>
26+
</button>
27+
{/each}
28+
</div>
29+
30+
<button
31+
on:click={() => {
32+
dispatch('color', { color: background })
33+
paletteColor = background
34+
}}
35+
style:background
36+
class="w-10 h-10">
37+
<span class="visually-hidden">
38+
<!-- Select the background color to clear the canvas -->
39+
</span>
40+
</button>
41+
42+
<!-- Undoボタン追加 -->
43+
<div class="flex justify-center mt-2">
44+
<button class="px-5 py-1 bg-yellow-500 text-white hover:bg-yellow-700">
45+
一つ前に戻る
46+
</button>
47+
</div>
48+
49+
<style>
50+
</style>

frontend/src/routes/design/top/[lobby]/ogiri/+layout.svelte renamed to frontend/src/routes/design/top/[lobby]/game_answer/+layout.svelte

File renamed without changes.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<script>
2+
import Canvas from './Canvas.svelte'
3+
import Palette from './Palette.svelte'
4+
5+
const colors = [
6+
'#d58141',
7+
'#d7c44c',
8+
'#4fa9cc',
9+
'#3f8d27',
10+
]
11+
const background = '#fff'
12+
13+
let color = colors[0]
14+
const paletteColor = color
15+
</script>
16+
<main class="content h-250 container mx-auto flex flex-col bg-amber-300">
17+
<!-- お題表示の部分 -->
18+
<section class= "w-full bg-yellow-500 p-15 text-5xl rounded-md text-center text-black">
19+
お題:ボウリングで全ての投球がガターだった時、起こることは?
20+
</section>
21+
22+
23+
<!-- お絵描き部分 -->
24+
<div class="Drawing section w-1/2 bg-amber-600">
25+
<Canvas {color} {background} />
26+
<div class="palette w-1/2 bg-amber-500">
27+
<Palette
28+
{paletteColor}
29+
{colors}
30+
{background}
31+
on:color="{({ detail }) => {
32+
color = detail.color;
33+
}}"
34+
/>
35+
</div>
36+
</div>
37+
38+
<!-- 発表部分 -->
39+
<div class= "bg-amber-200 p-5 flex justify-end fixed bottom-20 right-1">
40+
<button class="px-10 py-3 bg-yellow-600 text-white rounded-md text-4xl hover:bg-orange-200">
41+
発表する!
42+
</button>
43+
</div>
44+
45+
46+
</main>
47+
48+
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<script>
2+
import { onMount } from 'svelte'
3+
4+
export let width = 1000
5+
export let height = 650
6+
export let color = '#333'
7+
export let background = '#fff'
8+
9+
let canvas
10+
let context
11+
let isDrawing
12+
let start
13+
14+
let t, l
15+
let history = [] //Undo用
16+
onMount(() => {
17+
context = canvas.getContext('2d')
18+
context.lineWidth = 3
19+
20+
handleSize()
21+
saveState()
22+
})
23+
24+
$: if(context) {
25+
context.strokeStyle = color
26+
}
27+
28+
const handleStart = (({ offsetX: x, offsetY: y }) => {
29+
saveState() //これを描かなかったら機能しない
30+
if(color === background) {
31+
context.clearRect(0, 0, width, height)
32+
} else {
33+
isDrawing = true
34+
start = { x, y }
35+
}
36+
})
37+
38+
const handleEnd = () => { isDrawing = false }
39+
const handleMove = (({ offsetX: x1, offsetY: y1 }) => {
40+
if(!isDrawing) return
41+
42+
const { x, y } = start
43+
context.beginPath()
44+
context.moveTo(x, y)
45+
context.lineTo(x1, y1)
46+
context.closePath()
47+
context.stroke()
48+
49+
start = { x: x1, y: y1 }
50+
})
51+
52+
const handleSize = () => {
53+
const { top, left } = canvas.getBoundingClientRect()
54+
t = top
55+
l = left
56+
}
57+
//履歴を保存
58+
const saveState = () => {
59+
history.push(canvas.toDataURL())
60+
}
61+
62+
//Undo機能
63+
const undo = () => {
64+
if (history.length > 1) {
65+
history.pop() //最新の履歴を削除
66+
const lastState = history[history.length - 1] //一つ前の履歴を取得
67+
restoreCanvas(lastState)
68+
}
69+
}
70+
71+
// **キャンバスを復元**
72+
const restoreCanvas = (imageData) => {
73+
const img = new Image()
74+
img.src = imageData
75+
img.onload = () => {
76+
context.clearRect(0, 0, canvas.width, canvas.height)
77+
context.drawImage(img, 0, 0)
78+
}
79+
}
80+
</script>
81+
82+
<svelte:window on:resize={handleSize} />
83+
<div>
84+
<canvas
85+
{width}
86+
{height}
87+
style:background
88+
bind:this={canvas}
89+
on:mousedown={handleStart}
90+
on:touchstart={e => {
91+
const { clientX, clientY } = e.touches[0]
92+
handleStart({
93+
offsetX: clientX - l,
94+
offsetY: clientY - t
95+
})
96+
}}
97+
on:mouseup={handleEnd}
98+
on:touchend={handleEnd}
99+
on:mouseleave={handleEnd}
100+
on:mousemove={handleMove}
101+
on:touchmove={e => {
102+
const { clientX, clientY } = e.touches[0]
103+
handleMove({
104+
offsetX: clientX - l,
105+
offsetY: clientY - t
106+
})
107+
}}
108+
>
109+
</canvas>
110+
111+
<!-- Undoボタン追加 -->
112+
<div class="flex justify-center mt-2">
113+
<button on:click={undo} class="px-5 py-1 bg-yellow-500 text-white rounded-md hover:bg-yellow-700">
114+
一つ前に戻る
115+
</button>
116+
</div>
117+
</div>

0 commit comments

Comments
 (0)