Skip to content

Instantly share code, notes, and snippets.

@motsu0
Last active Jun 26, 2022
Embed
What would you like to do?
#card{
display: grid;
grid-template-columns: repeat(3,1fr);
row-gap: 5%;
column-gap: 5%;
width: 90%;
margin: 0 auto;
padding: 5%;
position: relative;
background-color: #FFF59D;
user-select: none;
}
.card__section{
position: relative;
}
.card__section::before{
display: block;
content: "";
padding-top: 100%;
}
.card__cover{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 1;
border-radius: 50%;
cursor: url('pathto/cursor-scratch.svg') 24 24, pointer;
-webkit-tap-highlight-color: transparent;
}
.card__cont{
width: 90%;
height: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: 0;
pointer-events: none;
}
#card__prepare{
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 10;
border: 1px solid #333;
background-color: #fff;
}
#card__prepare.hide{
display: none;
}
#bt-reset{
display: block;
padding: 4px 12px;
margin: 12px auto;
border: 1px solid #555;
background-color: #fff;
cursor: pointer;
}
<div id="card">
<div class="card__section">
<canvas class="card__cover"></canvas>
<img src="" alt="" class="card__cont">
</div>
<div class="card__section">
<canvas class="card__cover"></canvas>
<img src="" alt="" class="card__cont">
</div>
<div class="card__section">
<canvas class="card__cover"></canvas>
<img src="" alt="" class="card__cont">
</div>
<div class="card__section">
<canvas class="card__cover"></canvas>
<img src="" alt="" class="card__cont">
</div>
<div class="card__section">
<canvas class="card__cover"></canvas>
<img src="" alt="" class="card__cont">
</div>
<div class="card__section">
<canvas class="card__cover"></canvas>
<img src="" alt="" class="card__cont">
</div>
<div id="card__prepare">準備中</div>
</div>
<button id="bt-reset">新しいカードにする</button>
scratchCard();
function scratchCard(){
//カード取得
const el_card = document.getElementById('card');
el_card.addEventListener('pointerdown', scratchStart);
el_card.addEventListener('pointerup',scratchEnd);
el_card.addEventListener('pointerleave',scratchEnd);
el_card.addEventListener('touchleave',scratchEnd);
el_card.addEventListener('touchmove',e=>{
e.preventDefault();
});
//目隠し取得
const el_card__prepare = document.getElementById('card__prepare');
//canvas取得 サイズ設定
const els_card__cover = document.getElementsByClassName('card__cover');
let scratching = false;
let num_scratch = undefined;
[...els_card__cover].forEach((canvas,i)=>{
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const r_scratch = canvas.width/10;
//削り機能
canvas.addEventListener('pointerdown',e=>{
e.stopPropagation();
scratchStart();
scratch(e,i,r_scratch);
});
canvas.addEventListener('mousemove',e=>{
if(scratching) scratch(e,i,r_scratch);
});
canvas.addEventListener('touchmove',e=>{
scratch(e,i,r_scratch);
});
});
//カバー作成
const els_ctx = [...els_card__cover].map(canvas=>canvas.getContext('2d'));
makeCover();
//内容作成
const els_card__cont = document.getElementsByClassName('card__cont');
const src_atari = 'pathto/atari.svg';
const src_hazure = 'pathto/hazure.svg';
makeCont();
//
const bt_reset = document.getElementById('bt-reset');
bt_reset.addEventListener('click',reset);
function makeCover(){
els_ctx.forEach((ctx,i)=>{
const x = els_card__cover[i].width/2;
const y = els_card__cover[i].height/2;
ctx.globalCompositeOperation = 'source-over';
ctx.beginPath();
ctx.arc(x,y,x,0,2*Math.PI);
ctx.fillStyle = '#9E9E9E';
ctx.fill();
});
}
function makeCont(){
const arr_cont = [1,1,0,0,0,0];
shuffle(arr_cont);
const promise_set = [];
arr_cont.forEach((n,i)=>{
const promise = new Promise(resolve=>{
els_card__cont[i].onload = ()=>{
resolve();
}
});
promise_set.push(promise);
if(n==1){
els_card__cont[i].src = src_atari;
}else{
els_card__cont[i].src = src_hazure;
}
});
Promise.all(promise_set).then(()=>{
el_card__prepare.classList.add('hide');
});
}
function scratch(e,i,r){
//判定
if(num_scratch===undefined){
num_scratch = i;
}else{
if(num_scratch!=i) return;
}
//描画
const ctx = els_ctx[i];
const rect = e.target.getBoundingClientRect();
const x = e.offsetX || e.touches[0].clientX - rect.left; //右はスマホタップ
const y = e.offsetY || e.touches[0].clientY - rect.top;
ctx.globalCompositeOperation = 'destination-out';
ctx.beginPath();
ctx.arc(x,y,r,0,2*Math.PI);
ctx.fill();
}
function scratchStart(){
scratching = true;
}
function scratchEnd(){
scratching = false;
}
function reset(){
el_card__prepare.classList.add('hide');
num_scratch = undefined;
makeCover();
makeCont();
}
function randomMN(m,n){
const d = Math.max(m,n)-Math.min(m,n);
return Math.floor(Math.random()*(d+1)+Math.min(m,n));
}
function shuffle(array){
for(let i=array.length-1;i>=1;i--){
const j = randomMN(0,i);
[array[j],array[i]] = [array[i],array[j]];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment