/** * Circular Process Slider v2 — cps-script.js * Arrow slides smoothly ALONG the ring path (continuous motion). */ (function () { 'use strict'; var SVG_CX = 250, SVG_CY = 250, SVG_R = 210; function deg2rad(d) { return d * Math.PI / 180; } function ringPoint(angleDeg) { var rad = deg2rad(angleDeg - 90); return { x: SVG_CX + SVG_R * Math.cos(rad), y: SVG_CY + SVG_R * Math.sin(rad) }; } document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('.cps-section').forEach(initInstance); }); function initInstance(section) { var total = parseInt(section.dataset.total, 10) || 6; var speed = parseInt(section.dataset.speed, 10) || 3000; var START = 60; var GAP = 360 / total; var angles = []; for (var i = 0; i < total; i++) angles.push(START + i * GAP); var current = 0; var arrowDeg = angles[0]; var targetDeg = angles[0]; var animId = null; var autoTimer = null; var paused = false; var lastTs = null; var ROT_SPEED = 180; var svg = section.querySelector('.cps-ring-svg'); var arrowG = section.querySelector('.cps-arrow-group'); var dotsGroup = section.querySelector('.cps-dots-group'); angles.forEach(function (deg, i) { var p = ringPoint(deg); var dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); dot.setAttribute('cx', p.x); dot.setAttribute('cy', p.y); dot.setAttribute('r', 5.5); dot.setAttribute('class', 'cps-dot-marker' + (i === 0 ? ' active' : '')); dot.dataset.step = i; dotsGroup.appendChild(dot); }); var arena = section.querySelector('.cps-arena'); var labels = section.querySelectorAll('.cps-label'); function positionLabels() { var W = arena.offsetWidth; var H = arena.offsetHeight; var lR = W * 0.63; labels.forEach(function (lbl, i) { var rad = deg2rad(angles[i] - 90); lbl.style.left = (W / 2 + lR * Math.cos(rad)) + 'px'; lbl.style.top = (H / 2 + lR * Math.sin(rad)) + 'px'; }); } positionLabels(); window.addEventListener('resize', positionLabels); function drawArrow(deg) { var p = ringPoint(deg); var rot = deg; arrowG.setAttribute('transform', 'translate(' + p.x + ',' + p.y + ') rotate(' + rot + ')'); } drawArrow(arrowDeg); function animArrow(ts) { if (!lastTs) lastTs = ts; var dt = ts - lastTs; lastTs = ts; var diff = targetDeg - arrowDeg; while (diff > 180) diff -= 360; while (diff < -180) diff += 360; if (Math.abs(diff) < 0.25) { arrowDeg = targetDeg; drawArrow(arrowDeg); animId = null; lastTs = null; return; } var step = ROT_SPEED * (dt / 1000); arrowDeg += (diff > 0 ? 1 : -1) * Math.min(step, Math.abs(diff)); drawArrow(arrowDeg); animId = requestAnimationFrame(animArrow); } function rotateTo(deg) { var cur = ((arrowDeg % 360) + 360) % 360; var tgt = ((deg % 360) + 360) % 360; if (tgt <= cur) tgt += 360; targetDeg = arrowDeg + (tgt - cur); if (animId) { cancelAnimationFrame(animId); animId = null; } lastTs = null; animId = requestAnimationFrame(animArrow); } function activateStep(idx) { current = ((idx % total) + total) % total; section.querySelectorAll('.cps-step-img').forEach(function (img) { img.classList.toggle('cps-img-active', +img.dataset.step === current); }); labels.forEach(function (lbl) { lbl.classList.toggle('cps-label-active', +lbl.dataset.step === current); }); dotsGroup.querySelectorAll('.cps-dot-marker').forEach(function (d) { d.classList.toggle('active', +d.dataset.step === current); }); section.querySelectorAll('.cps-minfo-item').forEach(function (item) { item.classList.toggle('cps-minfo-active', +item.dataset.step === current); }); rotateTo(angles[current]); } function startAuto() { if (autoTimer) return; autoTimer = setInterval(function () { if (!paused) activateStep(current + 1); }, speed); } function stopAuto() { if (autoTimer) { clearInterval(autoTimer); autoTimer = null; } } section.addEventListener('mouseenter', function () { paused = true; }); section.addEventListener('mouseleave', function () { paused = false; }); section.addEventListener('focusin', function () { paused = true; }); section.addEventListener('focusout', function () { paused = false; }); labels.forEach(function (lbl) { lbl.addEventListener('click', function () { stopAuto(); activateStep(+lbl.dataset.step); startAuto(); }); lbl.addEventListener('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); lbl.click(); } }); }); var btnPrev = section.querySelector('.cps-btn-prev'); var btnNext = section.querySelector('.cps-btn-next'); if (btnPrev) btnPrev.addEventListener('click', function () { stopAuto(); activateStep(current - 1); startAuto(); }); if (btnNext) btnNext.addEventListener('click', function () { stopAuto(); activateStep(current + 1); startAuto(); }); if ('IntersectionObserver' in window) { new IntersectionObserver(function (entries) { entries.forEach(function (e) { e.isIntersecting ? startAuto() : stopAuto(); }); }, { threshold: 0.2 }).observe(section); } else { startAuto(); } } })(); Organic – ibic
  • Home 3
  • Product categories
  • Organic

Fresh New Potato

Great things are on the horizon

Something big is brewing! Our store is in the works and will be launching soon!

Cart (0 items)

Lorem ipsum dolor sit amet, porro quisquam est, qui dolorem ipsum quia dolor sit amet.

Socials:
Select the fields to be shown. Others will be hidden. Drag and drop to rearrange the order.
  • Image
  • SKU
  • Rating
  • Price
  • Stock
  • Availability
  • Add to cart
  • Description
  • Content
  • Weight
  • Dimensions
  • Additional information
Click outside to hide the comparison bar
Compare