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 RGBIC Car LED Strip Light

اضاءة السيارة
#H7090
Govee Vendor: Govee_iraq
Out of Stock
IQD 55,000 IQD 60,000
إضاءة Govee H7090 هي عبارة عن أشرطة إضاءة LED ذكية مخصصة لداخلية السيارة، تعتمد على تقنية RGBIC المتطورة التي تسمح بعرض عدة ألوان في آنٍ واحد على الشريط نفسه، مما يخلق تأثيرات تشبه قوس قزح. يتم التحكم بها بشكل كامل عبر تطبيق Govee Home للهواتف الذكية من خلال اتصال البلوتوث.
  • تأثيرات RGBIC: على عكس RGB التقليدية، يمكن أن يظهر ضوء السيارة LED أكثر من لون واحد في كل مرة. يسمح التحكم في الألوان المجزأة RGBIC بشاشات إضاءة متعددة الألوان، مما يجلب مستوى جديدا تماما من ديكور الإضاءة الشخصي لسيارتك.
  • التحكم الذكي في التطبيقات: مع تطبيق Govee Home الخاص بنا، قم بتخصيص الألوان الزاهية، وتعيين تأثيرات مختلفة، وضبط السطوع، وتشغيل / إيقاف التشغيل، واستكشاف ميزات المجتمع المذهلة بما في ذلك تطبيق التأثيرات المخصصة الأخرى على ضوء سيارتك الداخلي بنقرة واحدة.
  • 4 أوضاع موسيقية: ابدأ الحفلة بأوضاع الموسيقى الديناميكية التي تستخدم الميكروفون المدمج لمزامنة تأثيرات الإضاءة مع الإيقاع والأصوات. قم بتنشيط رحلاتك على الطريق أو التنقل المسائي بألوان ترقص بنشاط على أغانيك المفضلة.
  • 30 وضعا للمشهد: مع مجموعة من أوضاع المشهد المحددة مسبقا، قم دائما بالقيادة في الإضاءة التي تناسب أسلوبك أو مزاجك. اكتشف مشاهد تعتمد على الطبيعة والعطلات والعواطف للحفاظ على التصميم الداخلي لسيارتك طازجا وممتعا.
  • وضع DIY: اصنع تأثيرات الإضاءة الداخلية الديناميكية الخاصة بك في تطبيق Govee Home وحتى شاركها مع المجتمع الذي يضم 8 ملايين مستخدم مسجل. قم بالتخصيص باستخدام 16 مليون لون وسرعات وسطوع قابل للتعديل. غير مخصص للإضاءة. يستخدم فقط لخلق أجواء.
  • طول كل شريط: 30 سم.
  • عدد الأشرطة: تحتوي المجموعة على 4 أشرطة منفصلة، صُممت لتوضع تحت لوحة القيادة وتحت المقاعد الأمامية لتغطية منطقة الأقدام بالكامل.
  • عرض الشريط وسماكته: يبلغ عرض الشريط حوالي 12 ملموسماكته 3 ملم.
  • توزيع الإضاءة: يحتوي كل شريط بطول 30 سم على 18 وحدة LED (بإجمالي 72 وحدة للمجموعة كاملة) لضمان توزيع متساوي وقوي للإضاءة.
  •  
Category اضاءة السيارة
Brand Govee
SKU H7090
Weight 0.3 kg
Estimated Delivery 1-2 days
Edition 2021
0 (0 reviews)

No reviews yet. Be the first to review this product!

Login to write a review

Related Products

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

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

footer_branding

Govee Iraq

Add our store to your home screen

  1. 1 Tap the Share button in the browser bar
  2. 2 Choose Add to Home Screen