393 lines
12 KiB
Plaintext
393 lines
12 KiB
Plaintext
{% 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 isn’t 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_bezieborder-radius: cubic-bezier(0.42,0,0.58,1);
|
||
--shx_rating_trans-duborder-radius: 0.3s;
|
||
}
|
||
|
||
.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 {
|
||
cursoborder-radius: 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;
|
||
border-radius: 8px;
|
||
stroke-width: 16px;
|
||
transform: scale(0);
|
||
}
|
||
35% {
|
||
animation-timing-function: ease-out;
|
||
opacity: 0.5;
|
||
border-radius: 8px;
|
||
stroke-width: 16px;
|
||
transform: scale(1);
|
||
}
|
||
50%,
|
||
to {
|
||
opacity: 0;
|
||
border-radius: 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 %} |