SHX-Theme/snippets/shx-StarRatingForm.liquid

394 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

{% assign content_type = content_type | default: 'html' %}
{% assign ratingFormID = ratingFormID | default: '1' %}
{% assign _ratingFormID = "SHX_" | append: ratingFormID | append: "_" %}
{% assign ratingTexts = ratingTexts | default: "Sehr schlecht,Schlecht,Ok,Gut,Sehr gut" %}
{% assign _ratingTexts = ratingTexts | split: "," %}
{% if content_type == 'html' %}
<div class="{{ _ratingFormID }}rating SHX_rating">
<div class="SHX_rating__stars">
{% for i in (1..5) %}
<input
id="{{ _ratingFormID }}rating-{{ i }}"
class="SHX_rating__input SHX_rating__input-{{ i }}"
type="radio"
name="{{ _ratingFormID }}rating"
value="{{ i }}">
{% endfor %}
{% for i in (1..5) %}
<label class="SHX_rating__label" for="{{ _ratingFormID }}rating-{{ i }}">
<svg
class="SHX_rating__star"
width="32"
height="32"
viewBox="0 0 32 32"
aria-hidden="true">
<g transform="translate(16,16)">
<circle
class="SHX_rating__star-ring"
fill="none"
stroke="#000"
stroke-width="16"
r="8"
transform="scale(0)" />
</g>
<g
stroke="#000"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round">
<g transform="translate(16,16) rotate(180)">
<polygon
class="SHX_rating__star-stroke"
points="0,15 4.41,6.07 14.27,4.64 7.13,-2.32 8.82,-12.14 0,-7.5 -8.82,-12.14 -7.13,-2.32 -14.27,4.64 -4.41,6.07"
fill="none" />
<polygon
class="SHX_rating__star-fill"
points="0,15 4.41,6.07 14.27,4.64 7.13,-2.32 8.82,-12.14 0,-7.5 -8.82,-12.14 -7.13,-2.32 -14.27,4.64 -4.41,6.07"
fill="#000" />
</g>
<g
transform="translate(16,16)"
stroke-dasharray="12 12"
stroke-dashoffset="12">
<polyline
class="SHX_rating__star-line"
transform="rotate(0)"
points="0 4,0 16" />
<polyline
class="SHX_rating__star-line"
transform="rotate(72)"
points="0 4,0 16" />
<polyline
class="SHX_rating__star-line"
transform="rotate(144)"
points="0 4,0 16" />
<polyline
class="SHX_rating__star-line"
transform="rotate(216)"
points="0 4,0 16" />
<polyline
class="SHX_rating__star-line"
transform="rotate(288)"
points="0 4,0 16" />
</g>
</g>
</svg>
{% assign index = i | minus: 1 %}
{% assign ratingText = _ratingTexts[index] %}
<span class="SHX_rating__sr">{{ i }} stars—{{ ratingText }}</span>
</label>
{% endfor %}
{% for i in (1..5) %}
{% assign index = i | minus: 1 %}
{% assign ratingText = _ratingTexts[index] %}
<p
class="SHX_rating__display"
SHX_data-rating="{{ i }}"
hidden>{{ ratingText }}</p>
{% endfor %}
</div>
</div>
<script type="text/javascript">
let {{ _ratingFormID }}global_starRating = null;
window.addEventListener("DOMContentLoaded",() => {
const starRating = new StarRating(".{{ _ratingFormID }}rating", "{{ _ratingFormID }}");
{{ _ratingFormID }}global_starRating = starRating;
});
</script>{% elsif content_type == 'init' %}
<script type="text/javascript">
class StarRating {
constructor(qs, ratingID_Prefix) {
this.ratings = [
{id: 1, name: "{{ ratingText1 }}"},
{id: 2, name: "{{ ratingText2 }}"},
{id: 3, name: "{{ ratingText3 }}"},
{id: 4, name: "{{ ratingText4 }}"},
{id: 5, name: "{{ ratingText5 }}"}
];
this.rating = null;
this.el = document.querySelector(qs);
this.ratingID_Prefix = ratingID_Prefix;
this.init();
}
init() {
this.el?.addEventListener("change",this.updateRating.bind(this));
// stop Firefox from preserving form data between refreshes
try {
this.el?.reset();
} catch (err) {
//console.error("Element isnt a form.");
}
}
updateRating(e) {
// clear animation delays
Array.from(this.el.querySelectorAll(`[for*="SHX_rating"]`)).forEach(el => {
el.className = "SHX_rating__label";
});
const ratingObject = this.ratings.find(r => r.id === +e.target.value);
const prevRatingID = this.rating?.id || 0;
let delay = 0;
this.rating = ratingObject;
this.ratings.forEach(rating => {
const { id } = rating;
// add the delays
const ratingLabel = this.el.querySelector(`[for="${this.ratingID_Prefix}rating-${id}"]`);
if (id > prevRatingID + 1 && id <= this.rating.id) {
++delay;
ratingLabel.classList.add(`SHX_rating__label--delay${delay}`);
}
// hide ratings to not read, show the one to read
const ratingTextEl = this.el.querySelector(`[SHX_data-rating="${id}"]`);
if (this.rating.id !== id)
ratingTextEl.setAttribute("hidden",true);
else
ratingTextEl.removeAttribute("hidden");
});
}
}
</script>
<style > :root
{
--shx_rating_bg: #e3e4e8;
--shx_rating_fg: #17181c;
--shx_rating_primary: #255ff4;
--shx_rating_yellow: #f4a825;
--shx_rating_yellow-t: rgba(244, 168, 37, 0);
--shx_rating_bezier: cubic-bezier(0.42,0,0.58,1);
--shx_rating_trans-dur: 0.3s;
font-size: calc(24px +(30 - 24) *(100vw - 320px) /(1280 - 320));
}
.SHX_rating {
margin: auto auto 50px;
display: flex;
position: relative;
}
.SHX_rating__display {
font-size: 1.5em;
position: absolute;
top: 100%;
width: 100%;
text-align: center;
opacity: 0.5;
font-weight: 800;
margin: 0;
}
.SHX_rating__stars {
display: flex;
padding-bottom: 0.375em;
position: relative;
}
.SHX_rating__star {
display: block;
overflow: visible;
pointer-events: none;
width: 3em;
height: 3em;
}
.SHX_rating__star-ring,
.SHX_rating__star-fill,
.SHX_rating__star-line,
.SHX_rating__star-stroke {
animation-duration: 1s;
animation-timing-function: ease-in-out;
animation-fill-mode: forwards;
}
.SHX_rating__star-ring,
.SHX_rating__star-fill,
.SHX_rating__star-line {
stroke: var(--shx_rating_yellow);
}
.SHX_rating__star-fill {
fill: var(--shx_rating_yellow);
transform: scale(0);
transition: fill var(--shx_rating_trans-dur) var(--shx_rating_bezier)
, transform var(--shx_rating_trans-dur) var(--shx_rating_bezier);
}
.SHX_rating__star-line {
stroke-dasharray: 12 13;
stroke-dashoffset: -13;
}
.SHX_rating__star-stroke {
stroke: #c7cad1;
transition: stroke var(--shx_rating_trans-dur);
}
.SHX_rating__label {
cursor: pointer;
padding: 0.125em;
}
.SHX_rating__label--delay1 .SHX_rating__star-ring,
.SHX_rating__label--delay1 .SHX_rating__star-fill,
.SHX_rating__label--delay1 .SHX_rating__star-line,
.SHX_rating__label--delay1 .SHX_rating__star-stroke {
animation-delay: 0.05s;
}
.SHX_rating__label--delay2 .SHX_rating__star-ring,
.SHX_rating__label--delay2 .SHX_rating__star-fill,
.SHX_rating__label--delay2 .SHX_rating__star-line,
.SHX_rating__label--delay2 .SHX_rating__star-stroke {
animation-delay: 0.1s;
}
.SHX_rating__label--delay3 .SHX_rating__star-ring,
.SHX_rating__label--delay3 .SHX_rating__star-fill,
.SHX_rating__label--delay3 .SHX_rating__star-line,
.SHX_rating__label--delay3 .SHX_rating__star-stroke {
animation-delay: 0.15s;
}
.SHX_rating__label--delay4 .SHX_rating__star-ring,
.SHX_rating__label--delay4 .SHX_rating__star-fill,
.SHX_rating__label--delay4 .SHX_rating__star-line,
.SHX_rating__label--delay4 .SHX_rating__star-stroke {
animation-delay: 0.2s;
}
.SHX_rating__input {
position: absolute;
-webkit-appearance: none;
appearance: none;
}
.SHX_rating__input:hover ~ [SHX_data-rating]:not([hidden]) {
display: none;
}
.SHX_rating__input-1:hover ~ [SHX_data-rating="1"][hidden],
.SHX_rating__input-2:hover ~ [SHX_data-rating="2"][hidden],
.SHX_rating__input-3:hover ~ [SHX_data-rating="3"][hidden],
.SHX_rating__input-4:hover ~ [SHX_data-rating="4"][hidden],
.SHX_rating__input-5:hover ~ [SHX_data-rating="5"][hidden],
.SHX_rating__input:checked:hover ~ [SHX_data-rating]:not([hidden]) {
display: block;
}
.SHX_rating__input-1:hover ~ .SHX_rating__label:first-of-type .SHX_rating__star-stroke,
.SHX_rating__input-2:hover ~ .SHX_rating__label:nth-of-type(-n + 2) .SHX_rating__star-stroke,
.SHX_rating__input-3:hover ~ .SHX_rating__label:nth-of-type(-n + 3) .SHX_rating__star-stroke,
.SHX_rating__input-4:hover ~ .SHX_rating__label:nth-of-type(-n + 4) .SHX_rating__star-stroke,
.SHX_rating__input-5:hover ~ .SHX_rating__label:nth-of-type(-n + 5) .SHX_rating__star-stroke {
stroke: var(--shx_rating_yellow);
transform: scale(1);
}
.SHX_rating__input-1:checked ~ .SHX_rating__label:first-of-type .SHX_rating__star-ring,
.SHX_rating__input-2:checked ~ .SHX_rating__label:nth-of-type(-n + 2) .SHX_rating__star-ring,
.SHX_rating__input-3:checked ~ .SHX_rating__label:nth-of-type(-n + 3) .SHX_rating__star-ring,
.SHX_rating__input-4:checked ~ .SHX_rating__label:nth-of-type(-n + 4) .SHX_rating__star-ring,
.SHX_rating__input-5:checked ~ .SHX_rating__label:nth-of-type(-n + 5) .SHX_rating__star-ring {
animation-name: starRing;
}
.SHX_rating__input-1:checked ~ .SHX_rating__label:first-of-type .SHX_rating__star-stroke,
.SHX_rating__input-2:checked ~ .SHX_rating__label:nth-of-type(-n + 2) .SHX_rating__star-stroke,
.SHX_rating__input-3:checked ~ .SHX_rating__label:nth-of-type(-n + 3) .SHX_rating__star-stroke,
.SHX_rating__input-4:checked ~ .SHX_rating__label:nth-of-type(-n + 4) .SHX_rating__star-stroke,
.SHX_rating__input-5:checked ~ .SHX_rating__label:nth-of-type(-n + 5) .SHX_rating__star-stroke {
animation-name: starStroke;
}
.SHX_rating__input-1:checked ~ .SHX_rating__label:first-of-type .SHX_rating__star-line,
.SHX_rating__input-2:checked ~ .SHX_rating__label:nth-of-type(-n + 2) .SHX_rating__star-line,
.SHX_rating__input-3:checked ~ .SHX_rating__label:nth-of-type(-n + 3) .SHX_rating__star-line,
.SHX_rating__input-4:checked ~ .SHX_rating__label:nth-of-type(-n + 4) .SHX_rating__star-line,
.SHX_rating__input-5:checked ~ .SHX_rating__label:nth-of-type(-n + 5) .SHX_rating__star-line {
animation-name: starLine;
}
.SHX_rating__input-1:checked ~ .SHX_rating__label:first-of-type .SHX_rating__star-fill,
.SHX_rating__input-2:checked ~ .SHX_rating__label:nth-of-type(-n + 2) .SHX_rating__star-fill,
.SHX_rating__input-3:checked ~ .SHX_rating__label:nth-of-type(-n + 3) .SHX_rating__star-fill,
.SHX_rating__input-4:checked ~ .SHX_rating__label:nth-of-type(-n + 4) .SHX_rating__star-fill,
.SHX_rating__input-5:checked ~ .SHX_rating__label:nth-of-type(-n + 5) .SHX_rating__star-fill {
animation-name: starFill;
}
.SHX_rating__input-1:not(:checked):hover ~ .SHX_rating__label:first-of-type .SHX_rating__star-fill,
.SHX_rating__input-2:not(:checked):hover ~ .SHX_rating__label:nth-of-type(2) .SHX_rating__star-fill,
.SHX_rating__input-3:not(:checked):hover ~ .SHX_rating__label:nth-of-type(3) .SHX_rating__star-fill,
.SHX_rating__input-4:not(:checked):hover ~ .SHX_rating__label:nth-of-type(4) .SHX_rating__star-fill,
.SHX_rating__input-5:not(:checked):hover ~ .SHX_rating__label:nth-of-type(5) .SHX_rating__star-fill {
fill: var(--shx_rating_yellow-t);
}
.SHX_rating__sr {
clip: rect(1px, 1px, 1px, 1px);
overflow: hidden;
position: absolute;
width: 1px;
height: 1px;
}
@keyframes starRing {
from,
20% {
animation-timing-function: ease-in;
opacity: 1;
r: 8px;
stroke-width: 16px;
transform: scale(0);
}
35% {
animation-timing-function: ease-out;
opacity: 0.5;
r: 8px;
stroke-width: 16px;
transform: scale(1);
}
50%,
to {
opacity: 0;
r: 16px;
stroke-width: 0;
transform: scale(1);
}
}
@keyframes starFill {
from,
40% {
animation-timing-function: ease-out;
transform: scale(0);
}
60% {
animation-timing-function: ease-in-out;
transform: scale(1.2);
}
80% {
transform: scale(0.9);
}
to {
transform: scale(1);
}
}
@keyframes starStroke {
from {
transform: scale(1);
}
20%,
to {
transform: scale(0);
}
}
@keyframes starLine {
from,
40% {
animation-timing-function: ease-out;
stroke-dasharray: 1 23;
stroke-dashoffset: 1;
}
60%,
to {
stroke-dasharray: 12 13;
stroke-dashoffset: -13;
}
}</style>{% endif %}