scratch animation ok
This commit is contained in:
parent
3fabe83923
commit
3a7d35f701
8 changed files with 183 additions and 69 deletions
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
|
@ -6,15 +6,16 @@
|
|||
font-family: 'Montauk Pro', serif;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
|
||||
@include font-size(3rem);
|
||||
}
|
||||
|
||||
h2,h3,h4,h5,h6 {
|
||||
display: block;
|
||||
color: $color-primary;
|
||||
text-transform: uppercase;
|
||||
text-decoration: #{$color-tertiary} solid underline;
|
||||
text-decoration-thickness: 0.2rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
hr {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
@import "./../partials/spin_wheel";
|
||||
|
||||
.won-page {
|
||||
#scratch-wrapper canvas {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#wheel-wrapper {
|
||||
position: relative;
|
||||
width: 16rem;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,14 @@ return [
|
|||
'inCanvas' => true,
|
||||
'fit' => true,
|
||||
'format' => 'webp'
|
||||
],
|
||||
'scratch_prize' => [
|
||||
'height' => 300,
|
||||
'width' => 450,
|
||||
'resize' => true,
|
||||
'inCanvas' => true,
|
||||
'keepRatio' => true,
|
||||
'format' => 'webp'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { SCRATCH_TYPE, ScratchCard } from "scratchcard-js";
|
||||
import grattageUrl from "./../../assets/images/animations/grattage.png";
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
if (!document.querySelector("main.won-page")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const wheelWrapper = document.getElementById("wheel-wrapper"),
|
||||
spinWheelInner = wheelWrapper?.querySelector(".wheel-inner") as HTMLElement | null | undefined,
|
||||
spinWheelBtnList = wheelWrapper?.querySelectorAll(".wheel-spin") as NodeListOf<HTMLElement> | undefined,
|
||||
animationSection = document.getElementById("spin-animation"),
|
||||
const scratchWrapper = document.getElementById("scratch-wrapper"),
|
||||
scratchPicture = document.getElementById("scratch-picture") as HTMLPictureElement|null,
|
||||
animationSection = document.getElementById("scratch-animation"),
|
||||
prizeSection = document.getElementById("prize-section"),
|
||||
discountSection = document.getElementById("discount-section"),
|
||||
winningProofSection = document.getElementById("winning-proof-section");
|
||||
|
|
@ -29,73 +31,34 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||
};
|
||||
|
||||
if (!animationSection) {
|
||||
throw Error("section#spin-animation missing");
|
||||
throw Error("section#scratch-animation missing");
|
||||
}
|
||||
|
||||
if (wheelWrapper && spinWheelInner && spinWheelBtnList && spinWheelBtnList.length) {
|
||||
let clicks: number = 0;
|
||||
// * Set default degree (360*5) soit 5 tours
|
||||
const degree: number = (360 * 5),
|
||||
wheelPartsDeg: number = 360 / spinWheelInner.children.length,
|
||||
thisWinAngle: number = (Number.parseInt(
|
||||
String(wheelWrapper.dataset["winChild"])
|
||||
// On s'aligne sur la tranche on on ajoute entre 10% et 90% d'une part
|
||||
)) * wheelPartsDeg - 45 + (wheelPartsDeg * (Math.random() * (0.9 - 0.1) + 0.1));
|
||||
let timeout: NodeJS.Timeout | null = null;
|
||||
|
||||
const spinTheWheel = () => {
|
||||
// * Add 1 every click
|
||||
|
||||
/**
|
||||
* Multiply the degree by number of clicks
|
||||
* generate random number between 1 - 85,
|
||||
* then add to the new degree
|
||||
*/
|
||||
const newDegree = degree * ++clicks;
|
||||
const totalDegree = newDegree + thisWinAngle;
|
||||
|
||||
/**
|
||||
* Let's make the spin btn to tilt every
|
||||
* time the edge of the section hits
|
||||
* the indicator
|
||||
*/
|
||||
spinWheelInner.style["transform"] = `rotate(${totalDegree}deg)`;
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
timeout = setTimeout(toggleAnimationPhase, 7000);
|
||||
};
|
||||
/** ! Même Algo que sur GGW legacy */
|
||||
spinWheelBtnList.forEach((spinBtn) => {
|
||||
spinBtn.addEventListener("click", spinTheWheel);
|
||||
spinBtn.addEventListener("keydown", (kbdEvt: KeyboardEvent) => {
|
||||
if (
|
||||
kbdEvt.key == " " ||
|
||||
kbdEvt.code == "Space" ||
|
||||
kbdEvt.keyCode == 32 ||
|
||||
kbdEvt.key == "Enter" ||
|
||||
kbdEvt.code == "Enter" ||
|
||||
kbdEvt.keyCode == 13
|
||||
) {
|
||||
spinBtn.classList.add("active");
|
||||
spinTheWheel();
|
||||
kbdEvt.preventDefault();
|
||||
}
|
||||
if (scratchWrapper && scratchPicture) {
|
||||
scratchPicture.addEventListener("load", () => {
|
||||
const sc = new ScratchCard(scratchWrapper, {
|
||||
scratchType: SCRATCH_TYPE.LINE,
|
||||
containerWidth: scratchWrapper.offsetWidth,
|
||||
containerHeight: scratchWrapper.offsetHeight,
|
||||
imageForwardSrc: grattageUrl,
|
||||
imageBackgroundSrc: "",
|
||||
htmlBackground: "",
|
||||
clearZoneRadius: 50,
|
||||
nPoints: 30,
|
||||
pointSize: 8,
|
||||
percentToFinish: 65,
|
||||
callback: function () {
|
||||
toggleAnimationPhase();
|
||||
},
|
||||
brushSrc: "",
|
||||
enabledPercentUpdate: true
|
||||
});
|
||||
spinBtn.addEventListener("keyup", (kbdEvt: KeyboardEvent) => {
|
||||
if (
|
||||
kbdEvt.key == " " ||
|
||||
kbdEvt.code == "Space" ||
|
||||
kbdEvt.keyCode == 32 ||
|
||||
kbdEvt.key == "Enter" ||
|
||||
kbdEvt.code == "Enter" ||
|
||||
kbdEvt.keyCode == 13
|
||||
) {
|
||||
spinBtn.classList.remove("active");
|
||||
kbdEvt.preventDefault();
|
||||
}
|
||||
sc.init().catch((e) => {
|
||||
console.error(e);
|
||||
toggleAnimationPhase();
|
||||
});
|
||||
});
|
||||
scratchPicture.setAttribute("src", String(scratchPicture.dataset["src"]));
|
||||
} else {
|
||||
toggleAnimationPhase();
|
||||
}
|
||||
|
|
|
|||
103
ts/pages/won.ts.wheel.disabled
Normal file
103
ts/pages/won.ts.wheel.disabled
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
document.addEventListener("DOMContentLoaded", function () {
|
||||
if (!document.querySelector("main.won-page")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const wheelWrapper = document.getElementById("wheel-wrapper"),
|
||||
spinWheelInner = wheelWrapper?.querySelector(".wheel-inner") as HTMLElement | null | undefined,
|
||||
spinWheelBtnList = wheelWrapper?.querySelectorAll(".wheel-spin") as NodeListOf<HTMLElement> | undefined,
|
||||
animationSection = document.getElementById("spin-animation"),
|
||||
prizeSection = document.getElementById("prize-section"),
|
||||
discountSection = document.getElementById("discount-section"),
|
||||
winningProofSection = document.getElementById("winning-proof-section");
|
||||
|
||||
/** Hide animation and show win sections */
|
||||
const toggleAnimationPhase = () => {
|
||||
if (animationSection) {
|
||||
animationSection.classList.add("d-none");
|
||||
}
|
||||
if (prizeSection) {
|
||||
prizeSection.classList.remove("d-none");
|
||||
}else if (discountSection) {
|
||||
discountSection.classList.remove("d-none");
|
||||
} else {
|
||||
throw new Error("No section to toggle");
|
||||
}
|
||||
if (winningProofSection) {
|
||||
winningProofSection.classList.remove("d-none");
|
||||
}
|
||||
};
|
||||
|
||||
if (!animationSection) {
|
||||
throw Error("section#spin-animation missing");
|
||||
}
|
||||
|
||||
if (wheelWrapper && spinWheelInner && spinWheelBtnList && spinWheelBtnList.length) {
|
||||
let clicks: number = 0;
|
||||
// * Set default degree (360*5) soit 5 tours
|
||||
const degree: number = (360 * 5),
|
||||
wheelPartsDeg: number = 360 / spinWheelInner.children.length,
|
||||
thisWinAngle: number = (Number.parseInt(
|
||||
String(wheelWrapper.dataset["winChild"])
|
||||
// On s'aligne sur la tranche on on ajoute entre 10% et 90% d'une part
|
||||
)) * wheelPartsDeg - 45 + (wheelPartsDeg * (Math.random() * (0.9 - 0.1) + 0.1));
|
||||
let timeout: NodeJS.Timeout | null = null;
|
||||
|
||||
const spinTheWheel = () => {
|
||||
// * Add 1 every click
|
||||
|
||||
/**
|
||||
* Multiply the degree by number of clicks
|
||||
* generate random number between 1 - 85,
|
||||
* then add to the new degree
|
||||
*/
|
||||
const newDegree = degree * ++clicks;
|
||||
const totalDegree = newDegree + thisWinAngle;
|
||||
|
||||
/**
|
||||
* Let's make the spin btn to tilt every
|
||||
* time the edge of the section hits
|
||||
* the indicator
|
||||
*/
|
||||
spinWheelInner.style["transform"] = `rotate(${totalDegree}deg)`;
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
timeout = setTimeout(toggleAnimationPhase, 7000);
|
||||
};
|
||||
/** ! Même Algo que sur GGW legacy */
|
||||
spinWheelBtnList.forEach((spinBtn) => {
|
||||
spinBtn.addEventListener("click", spinTheWheel);
|
||||
spinBtn.addEventListener("keydown", (kbdEvt: KeyboardEvent) => {
|
||||
if (
|
||||
kbdEvt.key == " " ||
|
||||
kbdEvt.code == "Space" ||
|
||||
kbdEvt.keyCode == 32 ||
|
||||
kbdEvt.key == "Enter" ||
|
||||
kbdEvt.code == "Enter" ||
|
||||
kbdEvt.keyCode == 13
|
||||
) {
|
||||
spinBtn.classList.add("active");
|
||||
spinTheWheel();
|
||||
kbdEvt.preventDefault();
|
||||
}
|
||||
});
|
||||
spinBtn.addEventListener("keyup", (kbdEvt: KeyboardEvent) => {
|
||||
if (
|
||||
kbdEvt.key == " " ||
|
||||
kbdEvt.code == "Space" ||
|
||||
kbdEvt.keyCode == 32 ||
|
||||
kbdEvt.key == "Enter" ||
|
||||
kbdEvt.code == "Enter" ||
|
||||
kbdEvt.keyCode == 13
|
||||
) {
|
||||
spinBtn.classList.remove("active");
|
||||
kbdEvt.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
toggleAnimationPhase();
|
||||
}
|
||||
});
|
||||
|
||||
26
views/pages/participation/parts/animation-scratch.blade.php
Normal file
26
views/pages/participation/parts/animation-scratch.blade.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<section class="container pb-5 pt-5 text-center" id="{{ $sectionId }}">
|
||||
<div class="row mb-3 mt-5">
|
||||
<div class="col">
|
||||
<h1 class="text-primary text-uppercase fw-bold">{{ __('Lancez la roue et découvrez votre gain') }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-5">
|
||||
<div class="col">
|
||||
{{-- blade-formatter-enable --}}
|
||||
<div class="d-inline-block position-relative" id="scratch-wrapper" aria-describedby="scratch-helper">
|
||||
@if ($winDiscount)
|
||||
<img class="img-fluid" id="scratch-picture" data-src="{{ asset(resize($objectWon->picture, 'scratch_prize')) }}"
|
||||
src="#"
|
||||
title="{{ __('Votre bon de réduction de :value', ['value' => number_format($objectWon->face_value / 100, 2, ',')]) }}"
|
||||
alt="{{ __('Votre bon de réduction de :value', ['value' => number_format($objectWon->face_value / 100, 2, ',')]) }}">
|
||||
@else
|
||||
<img class="img-fluid" id="scratch-picture" data-src="{{ asset(resize($objectWon->picture, 'scratch_prize')) }}"
|
||||
src="#" title="{{ $objectWon->picture_title }}" alt="{{ $objectWon->picture_alt }}">
|
||||
@endif
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<span class="fs-2" id="scratch-helper">{{ __('Grattez la carte pour connaitre votre gain.') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -6,12 +6,19 @@
|
|||
@section('main-class', 'won-page g-0')
|
||||
@section('content')
|
||||
|
||||
{{-- SCRATCH CARD --}}
|
||||
@include('theme::pages.participation.parts.animation-scratch', [
|
||||
'sectionId' => 'scratch-animation',
|
||||
'winDiscount' => !empty($prizeModel) ? false : true,
|
||||
'objectWon' => $prizeModel ?? ($discount ?? null),
|
||||
])
|
||||
|
||||
{{-- SPIN WHEEL --}}
|
||||
@include('theme::pages.participation.parts.animation', [
|
||||
{{-- @include('theme::pages.participation.parts.animation', [
|
||||
'sectionId' => 'spin-animation',
|
||||
'winDiscount' => !empty($prizeModel) ? false : true,
|
||||
'prizeModel' => $prizeModel ?? null,
|
||||
])
|
||||
]) --}}
|
||||
|
||||
@if (!empty($prizeModel))
|
||||
{{-- LOT --}}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue