0 }, get firstVideoIndex() { return this.hasVideos ? this.images.length : -1 }, get total() { return this.images.length + this.productVideos.length }, modalOpen: false, modalActive: 0, // Drag/swipe state isDragging: false, wasDragging: false, startX: 0, currentX: 0, dragOffset: 0, containerWidth: 0, startY: 0, directionLocked: null, isRtl: false, imageLoading: false, // Zoom state zoomScale: 1, zoomPanX: 0, zoomPanY: 0, zoomPinching: false, zoomPanning: false, zoomInitialDistance: 0, zoomInitialScale: 1, zoomPanStartX: 0, zoomPanStartY: 0, zoomPanOffsetX: 0, zoomPanOffsetY: 0, zoomLastTap: 0, zoomLastTouchX: 0, zoomLastTouchY: 0, zoomAnimating: false, lastInputWasTouch: false, init() { this.isRtl = document.documentElement.dir === 'rtl'; this.$nextTick(() => { this.containerWidth = this.$refs.carouselContainer?.offsetWidth || 0; // Handle already-cached images where x-on:load won't fire this.$el.querySelectorAll('img.lqip-placeholder').forEach(lqip => { const realImg = lqip.nextElementSibling; if (realImg && realImg.complete && realImg.naturalWidth > 0) { realImg.dataset.lqipDone = '1'; lqip.style.display = 'none'; } }); }); window.addEventListener('resize', () => { this.containerWidth = this.$refs.carouselContainer?.offsetWidth || 0; }); // Preload first image of each variant for instant switching Object.values(this.variationImagesMap).forEach(variant => { if (variant.images && variant.images[0]) { new Image().src = variant.images[0]; } }); // Only the active slide may play. Clearing startedVideo also // drops the bound src, so swiping away stops the download and // not just the playback. this.$watch('active', () => { this.startedVideo = null; this.$el.querySelectorAll('video[data-product-video]').forEach(v => v.pause()); }); }, handleDragStart(e) { if (this.total <= 1) return; this.isDragging = true; this.directionLocked = null; this.startX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX; this.startY = e.type.includes('mouse') ? e.clientY : e.touches[0].clientY; this.currentX = this.startX; this.containerWidth = this.$refs.carouselContainer?.offsetWidth || 0; }, handleDragMove(e) { if (!this.isDragging) return; const clientX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX; const clientY = e.type.includes('mouse') ? e.clientY : e.touches[0].clientY; if (this.directionLocked === null) { const deltaX = Math.abs(clientX - this.startX); const deltaY = Math.abs(clientY - this.startY); if (deltaX < 5 && deltaY < 5) return; if (deltaY > deltaX) { this.directionLocked = 'vertical'; this.isDragging = false; this.dragOffset = 0; return; } this.directionLocked = 'horizontal'; } if (this.directionLocked === 'vertical') return; e.preventDefault(); this.currentX = clientX; let diff = this.currentX - this.startX; // Limit drag at edges const atFirst = this.active === 0; const atLast = this.active === this.total - 1; const isAtEdge = this.isRtl ? (atFirst && diff < 0) || (atLast && diff > 0) : (atFirst && diff > 0) || (atLast && diff < 0); if (isAtEdge) { diff = diff * 0.3; // Resistance at edges } this.dragOffset = diff; }, handleDragEnd() { this.directionLocked = null; if (!this.isDragging) return; this.isDragging = false; // Mark that we just finished dragging to prevent click from opening modal if (Math.abs(this.dragOffset) > 5) { this.wasDragging = true; setTimeout(() => { this.wasDragging = false; }, 100); } const threshold = this.containerWidth * 0.2; if (Math.abs(this.dragOffset) > threshold) { if (this.isRtl) { // RTL: drag left (negative) = prev, drag right (positive) = next if (this.dragOffset < 0) { this.prev(); } else { this.next(); } } else { // LTR: drag right (positive) = prev, drag left (negative) = next if (this.dragOffset > 0) { this.prev(); } else { this.next(); } } } this.dragOffset = 0; }, getSlideTransform() { // RTL: images flow right-to-left, so we use positive offset // LTR: images flow left-to-right, so we use negative offset const baseOffset = this.isRtl ? this.active * 100 : -this.active * 100; const dragPercent = this.containerWidth > 0 ? (this.dragOffset / this.containerWidth) * 100 : 0; return `translateX(${baseOffset + dragPercent}%)`; }, next() { if (this.active < this.total - 1) { this.active = this.active + 1; } }, prev() { if (this.active > 0) { this.active = this.active - 1; } }, goTo(idx) { this.active = idx }, openModal(idx) { if (this.isDragging || this.wasDragging) return; // The lightbox is images only. Its surface is touch-action:none // with modalDragStart calling preventDefault() on every touch, // which would swallow the native video control bar - and // native fullscreen is one tap away from the inline player // anyway. Video slides simply never open it. if (this.hasVideos && idx >= this.firstVideoIndex) return; this.modalActive = idx; this.modalOpen = true; document.body.style.overflow = 'hidden'; }, closeModal() { this.resetZoom(); this.modalOpen = false; document.body.style.overflow = 'auto'; }, // Wrap on the image count, not `total`: the modal never shows a // video, so paging must not land on a video index. get modalTotal() { return Math.max(1, this.images.length) }, modalNext() { this.resetZoom(); this.modalActive = (this.modalActive + 1) % this.modalTotal }, modalPrev() { this.resetZoom(); this.modalActive = (this.modalActive - 1 + this.modalTotal) % this.modalTotal }, modalGoTo(idx) { this.resetZoom(); this.modalActive = idx }, // Modal drag/swipe modalDragging: false, modalWasDragging: false, modalStartX: 0, modalDragOffset: 0, // Zoom helpers resetZoom() { this.zoomScale = 1; this.zoomPanX = 0; this.zoomPanY = 0; this.zoomPinching = false; this.zoomPanning = false; }, getTouchDistance(touches) { return Math.hypot( touches[0].clientX - touches[1].clientX, touches[0].clientY - touches[1].clientY ); }, clampPan() { const maxPanX = Math.max(0, (this.zoomScale - 1) * window.innerWidth / 2); const maxPanY = Math.max(0, (this.zoomScale - 1) * window.innerHeight / 2); this.zoomPanX = Math.max(-maxPanX, Math.min(maxPanX, this.zoomPanX)); this.zoomPanY = Math.max(-maxPanY, Math.min(maxPanY, this.zoomPanY)); }, modalDragStart(e) { const isTouch = e.type.includes('touch'); this.lastInputWasTouch = isTouch; // Store touch position for double-tap zoom center if (isTouch && e.touches[0]) { this.zoomLastTouchX = e.touches[0].clientX; this.zoomLastTouchY = e.touches[0].clientY; } // Two fingers: start pinch-to-zoom if (isTouch && e.touches.length === 2) { this.zoomPinching = true; this.zoomInitialDistance = this.getTouchDistance(e.touches); this.zoomInitialScale = this.zoomScale; this.modalDragging = false; this.zoomPanning = false; e.preventDefault(); return; } // Single finger/mouse while zoomed: start panning if (this.zoomScale > 1) { this.zoomPanning = true; this.zoomPanStartX = isTouch ? e.touches[0].clientX : e.clientX; this.zoomPanStartY = isTouch ? e.touches[0].clientY : e.clientY; this.zoomPanOffsetX = this.zoomPanX; this.zoomPanOffsetY = this.zoomPanY; e.preventDefault(); return; } // Single finger not zoomed or mouse: existing swipe // Prevent browser double-tap-to-zoom so our custom handler works if (isTouch) { e.preventDefault(); } if (this.total <= 1) return; this.modalDragging = true; this.modalStartX = isTouch ? e.touches[0].clientX : e.clientX; this.modalDragOffset = 0; }, modalDragMove(e) { const isTouch = e.type.includes('touch'); // Pinch-to-zoom if (this.zoomPinching && isTouch && e.touches.length >= 2) { e.preventDefault(); const newDist = this.getTouchDistance(e.touches); let newScale = this.zoomInitialScale * (newDist / this.zoomInitialDistance); this.zoomScale = Math.max(1, Math.min(4, newScale)); this.clampPan(); return; } // Panning while zoomed if (this.zoomPanning) { e.preventDefault(); const px = isTouch ? e.touches[0].clientX : e.clientX; const py = isTouch ? e.touches[0].clientY : e.clientY; const dx = px - this.zoomPanStartX; const dy = py - this.zoomPanStartY; this.zoomPanX = this.zoomPanOffsetX + dx; this.zoomPanY = this.zoomPanOffsetY + dy; this.clampPan(); return; } // Existing swipe logic if (!this.modalDragging) return; e.preventDefault(); const x = isTouch ? e.touches[0].clientX : e.clientX; this.modalDragOffset = x - this.modalStartX; }, modalDragEnd(e) { const isTouch = e && e.type && e.type.includes('touch'); // End pinch if (this.zoomPinching) { this.zoomPinching = false; // Snap to 1 if nearly unzoomed if (this.zoomScale < 1.1) { this.resetZoom(); } this.modalWasDragging = true; setTimeout(() => { this.modalWasDragging = false; }, 100); // If one finger remains after pinch, start panning if (isTouch && e.touches && e.touches.length === 1 && this.zoomScale > 1) { this.zoomPanning = true; this.zoomPanStartX = e.touches[0].clientX; this.zoomPanStartY = e.touches[0].clientY; this.zoomPanOffsetX = this.zoomPanX; this.zoomPanOffsetY = this.zoomPanY; } return; } // End pan if (this.zoomPanning) { this.zoomPanning = false; this.modalWasDragging = true; setTimeout(() => { this.modalWasDragging = false; }, 100); // Double-tap to zoom out while panned if (isTouch) { const now = Date.now(); if (now - this.zoomLastTap < 300) { this.zoomAnimating = true; setTimeout(() => { this.zoomAnimating = false; }, 300); this.resetZoom(); this.zoomLastTap = 0; } else { this.zoomLastTap = now; } } return; } // Existing swipe end logic const wasDragging = this.modalDragging; if (this.modalDragging) { this.modalDragging = false; const absDrag = Math.abs(this.modalDragOffset); if (absDrag > 5) { this.modalWasDragging = true; setTimeout(() => { this.modalWasDragging = false; }, 100); } const threshold = 80; if (absDrag > threshold) { if (this.isRtl) { this.modalDragOffset < 0 ? this.modalPrev() : this.modalNext(); } else { this.modalDragOffset > 0 ? this.modalPrev() : this.modalNext(); } this.modalDragOffset = 0; this.zoomLastTap = 0; return; } this.modalDragOffset = 0; } // Double-tap detection (works for both zoomed and not zoomed) if (isTouch) { const now = Date.now(); if (now - this.zoomLastTap < 300) { this.zoomAnimating = true; setTimeout(() => { this.zoomAnimating = false; }, 300); this.modalWasDragging = true; setTimeout(() => { this.modalWasDragging = false; }, 200); if (this.zoomScale > 1) { this.resetZoom(); } else { const cx = this.zoomLastTouchX - window.innerWidth / 2; const cy = this.zoomLastTouchY - window.innerHeight / 2; this.zoomScale = 2.5; this.zoomPanX = -cx * (this.zoomScale - 1) / this.zoomScale; this.zoomPanY = -cy * (this.zoomScale - 1) / this.zoomScale; this.clampPan(); } this.zoomLastTap = 0; return; } this.zoomLastTap = now; // Single tap on backdrop: close modal (touch equivalent of @click.self) if (e.target === e.currentTarget) { this.closeModal(); } } }, switchToVariation(attrValueId) { const varImages = this.variationImagesMap[attrValueId]; let newImages, newLargeImages, newLqipImages; if (varImages && varImages.images && varImages.images.length > 0) { newImages = varImages.images; newLargeImages = varImages.largeImages || varImages.images; newLqipImages = varImages.lqipImages || []; } else { newImages = this.defaultImages; newLargeImages = this.defaultLargeImages; newLqipImages = this.defaultLqipImages; } // Show loading state while first image loads this.imageLoading = true; const firstImg = new Image(); firstImg.onload = () => { this.localImages = newImages; this.localLargeImages = newLargeImages; this.localLqipImages = newLqipImages; this.active = 0; this.modalActive = 0; this.imageLoading = false; }; firstImg.onerror = () => { this.localImages = newImages; this.localLargeImages = newLargeImages; this.localLqipImages = newLqipImages; this.active = 0; this.modalActive = 0; this.imageLoading = false; }; firstImg.src = newImages[0]; // If already cached, onload fires synchronously or near-instantly } }" x-on:keydown.escape.window="closeModal()" x-on:keydown.arrow-left.window="modalOpen && modalPrev()" x-on:keydown.arrow-right.window="modalOpen && modalNext()" x-on:switch-variation-images.window="switchToVariation($event.detail.attrValueId ?? $event.detail[0]?.attrValueId)">
/

Govee Glide Lively Wall Light

اضاءة الجدار
#H610A
Govee
نفذت الكمية
IQD 130,000
فكرته ببساطة أنه يحوّل جدار غرفتك العادي أو سيت-أب الألعاب (Setup) الخاص بك إلى لوحة فنية مضيئة ومستقبلية.🌟 باختصار، لماذا هو مميز؟إضاءة ذكية ومجنونة: ليست مثل أشرطة الـ LED التقليدية التي تعرض لوناً واحداً فقط؛ بل تعرض عدة ألوان مختلفة في نفس الوقت، وتتحرك وتتدفق الألوان داخلها بسلاسة مذهلة (تقنية RGBIC).تتراقص مع ألعابك وموسيقاك: فيها ميكروفون داخلي ذكي يلقط صوت اللعب أو الأغاني، ويجعل الإضاءة تنبض وتتحرك بدقة مع كل صوت (مثالية للجيمنج وغرف النوم و غرف الاستقبال والبث المباشر).تحكّم من مكانك: يمكنك تغيير الألوان والأشكال عن طريق تطبيق بهاتفك (بالواي فاي والبلوتوث)، أو تأمرها بصوتك عبر Alexa أو Google لتغير الجو بالكامل بلمسة واحدة.تركيب سهل جداً: تأتي كقطع بلاستيكية صلبة وأنيقة تُركب وتتشابك معاً، وتلصقها على الجدار مباشرة بلاصق قوي مرفق معها، بدون أي حاجة لثقب الجدار أو استخدام مسامير.باختصار، هي القطعة السحرية التي تنقل شكل غرفتك إلى مستوى آخر تماماً من الأناقة والحماس! 🌌🎮

المعلومات الإضافية

تسجيل الدخول مطلوب

يرجى تسجيل الدخول أو إنشاء حساب لملء المعلومات الإضافية.
  • التطبيق الذكي والتحكم الصوتي: تقوم زخارف حائط Govee بضبط Light Bar أضواء الألعاب RGBIC بدون استخدام اليدين عبر Alexa وGoogle Assistant. يتحكم البلوتوث والواي فاي في الألوان والسطوع وتأثيرات المشهد على تطبيق Govee Home. ملاحظة*: يرجى توصيل جميع الأشرطة قبل توصيل الطاقة.
  • الإنارات متعددة الألوان القابلة للتعديل: مع تقنية RGBIC الحاصلة على براءة اختراع، يجعل Govee Glide lively Light شاشة الانزلاق 24 لونا في وقت واحد مع وضع DIY، و16 مليون لون لخيارات التخصيص التي لا نهاية لها، وتأثيرات متعددة الألوان المتدفقة، تناسب زخارف الألعاب. ملاحظة: تحتوي الصورة على أكثر من مجموعة واحدة من المنتجات.
  • 11 وضعا موسيقيا مطورا: دع موسيقى LED Wall Sconces تتزامن مع الصوت المفضل لديك وخلق تجربة استماع غامرة. اختر من بين 11 وضعا موسيقيا متعدد الاستخدامات على تطبيق Govee Home للحفاظ على استمرار الحفلة.
  • 64+ أوضاع المشهد: ابحث عن الإضاءة المناسبة لأي جو وقم بتزيين غرفتك بسهولة، بما في ذلك أمسية هادئة في المنزل. مع أكثر من 64 وضع مشهد ديناميكي، صمم زخارفك الخاصة بنقرة واحدة على تطبيق Govee Home لأضواء ديكور الحائط Glide LED.
  • سهل التركيب: استخدم الفيلكرو والمواد اللاصقة المضمنة لإعداد قضبان إضاءة RGBIC بسهولة على أي سطح أملس داخل منزلك، واضغط على الفيلكرو لمدة 10 ثوان، واترك الفيلكرو يقف لمدة ساعة تقريبا، وسوف يلتصق بشكل أفضل. تحتوي مجموعة واحدة على شرائح 6 * 14.8 بوصة والتي يمكن أن تخلق خطين.
  • ملاحظة: شريط الضوء H610A هذا عبارة عن مجموعة من لوحتين. تحتوي كل لوحة على 3 أقسام ضوئية. شريط إضاءة LED صلب وصلب، وليس مرنا. أبعاد شريط إضاءة واحد: طوله 37.6 سم وعرضه 3.2 سم وارتفاعه 2.6 سم.
التصنيف اضاءة الجدار
العلامة التجارية Govee
رمز المنتج H610A
الوزن 1200 kg
التوصيل المتوقع ١-٢ يوم
0 (0 تقييمات)

لا توجد تقييمات بعد. كن أول من يقيم هذا المنتج!

تسجيل الدخول لكتابة تقييم

منتجات مرتبطة

مميزات تجعل Govee الخيار الأفضل

  • تكنولوجيا RGBIC الثورية: على عكس الإضاءة التقليدية، تتيح تقنية RGBIC من Govee عرض ألوان متعددة متحركة في وقت واحد على نفس الشريط أو اللوح، مما يخلق تأثيرات "قوس قزح" انسيابية.
  • نظام الترفيه الغامر (DreamView): تتيح منتجاتها مزامنة الإضاءة مع ما يعرض على شاشة التلفزيون أو مع إيقاع الموسيقى، مما يحول غرفتك إلى سينما منزلية أو بيئة ألعاب احترافية.
  • ذكاء اصطناعي متقدم (CogniGlow): تستخدم Govee خوارزميات الذكاء الاصطناعي لتحليل المحتوى وتقديم تأثيرات إضاءة دقيقة وذكية تتفاعل مع البيئة المحيطة.
  • تحكم شامل ومرن: توفر الشركة تطبيق Govee Home الذي يضم ملايين المستخدمين، مع دعم كامل للأوامر الصوتية (Alexa & Google Assistant) ومعيار Matter لضمان التوافق مع كافة أنظمة المنزل الذكي.

تم إنشاء وتصميم المتجر الإلكتروني بواسطة ترينافو

Govee Iraq

أضف متجرنا إلى شاشتك الرئيسية

  1. 1 اضغط على زر المشاركة في شريط المتصفح
  2. 2 اختر "إضافة إلى الشاشة الرئيسية"