
Müşterilerinize ürünlerinizi sunma biçiminiz, onlarla kurduğunuz bağın en önemli parçasıdır. Peki ya binlerce çeşit ürününüz varsa ve her birini müşterilerinize bire bir boyutlarda, her açıdan inceleyebilecekleri şekilde sunabilseydiniz?
Bu, fermuar tutma yerleri (elcik) üreten değerli müşterimiz Ruba Fermuar’ın KeyShot’ı tercih ederken kurduğu en büyük hayaldi. Binlerce çeşit ürünlerini, statik katalogların sınırları olmadan, dijital ortamda canlı bir şekilde sergilemek istiyorlardı. Yedikare Yazılım olarak biz de, hem KeyShot yazılımı hem de web teknolojileri tarafında onlara destek vererek bu hayali gerçeğe dönüştürdük.
Aşağıda, Ruba Fermuar’ın kendi ürünlerinden birini kullanarak hazırladığımız canlı örneği görüyorsunuz. Bu interaktif model, KeyShot’ın bir CAD dosyasını nasıl güçlü bir pazarlama ve satış aracına dönüştürdüğünün mükemmel bir kanıtıdır.

İş Akışı: CAD’den İnteraktif Deneyime
Bu etkileyici sonucu elde etmek için izlediğimiz yol oldukça basit ve hızlı.
Adım 1: CAD Verinizi KeyShot’ta Hazırlayın
Süreç, elinizdeki herhangi bir CAD programından aldığınız 3D data ile başlar. Bu datayı doğrudan KeyShot’a aktararak projenizin malzemelerini, ışıklarını ve dokularını mükemmel bir şekilde hazırlarsınız.
Adım 2: Modelin Poster Görselini Render Alın
Modeliniz web’de yüklenirken boş bir ekran yerine çekici bir kapak fotoğrafı göstermek çok önemlidir. .glb
olarak dışa aktarmadan önce, KeyShot’ta modeliniz için en beğendiğiniz açıdan yüksek çözünürlüklü bir “poster” görseli render alın. Bu görseli .png
formatında kaydedin.
Adım 3: KeyShot ile GLB Olarak Dışa Aktarın
Modeliniz ve poster görseliniz hazır olduğunda, tek yapmanız gereken “Export” menüsünden GLB (.glb) formatını seçmektir. KeyShot, tüm malzeme ve doku bilgilerini bu web dostu formata optimize ederek sizin için paketler.
Adım 4: Web Sitenize Ekleyin ve Canlandırın
Oluşturduğumuz .glb
dosyasını ve render aldığınız poster görselini, size sunduğumuz hazır kod parçası ile web sitenize kolayca ekleyebilirsiniz. Bu kod, modeli interaktif olarak göstermekle kalmaz, aynı zamanda otomatik olarak boyutlarını hesaplayarak ölçülendirir ve artırılmış gerçeklik deneyimini aktif eder.
Bu Görüntüleyiciyi Kendi Sitenize Nasıl Eklersiniz?
KeyShot ile hazırladığınız .glb
dosyalarını kendi sitenizde sergilemek için aşağıdaki basit kılavuzu takip edebilirsiniz.
1. Gerekli Dosyaları Hazırlayın
Öncelikle bilgisayarınızda bir klasör oluşturun ve aşağıdaki dosya yapısını hazırlayın:
/3d-gosterim
├── index.html (Aşağıda kodunu vereceğiz)
├── urun-modeli.glb (Kendi 3D modeliniz)
├── urun-modeli.png (Modelinizin kapak fotoğrafı)
└── /ar-assets
├── view_in_ar.png (AR ikonunuz)
└── hand.png (AR ikonunuz)
2. HTML Kodunu Ekleyin
Aşağıdaki index.html kodunu kopyalayıp oluşturduğunuz dosyaya yapıştırın. Bu kod, gerekli tüm stil ve script’leri içermektedir.
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Yedikare | 3D Model Görüntüleyici (AR Destekli)</title>
<script type="module" src="[https://ajax.googleapis.com/ajax/libs/model-viewer/3.5.0/model-viewer.min.js](https://ajax.googleapis.com/ajax/libs/model-viewer/3.5.0/model-viewer.min.js)"></script>
<style>
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; }
:not(:defined) > * { display: none; }
model-viewer {
width: 100%;
height: 100vh;
background-color: #f0f0f0;
}
.dim {
background: #fff; border-radius: 4px; border: 1px solid #ddd;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); color: #333;
display: block; font-family: inherit; font-size: 14px;
font-weight: 600; padding: 0.5em 1em; position: absolute;
transform: translate3d(-50%, -50%, 0); pointer-events: none; --min-hotspot-opacity: 0;
}
.dimensionLineContainer { pointer-events: none; display: block; position: absolute; top: 0; left: 0; }
.dimensionLine {
stroke: #16a5e6;
stroke-width: 1;
stroke-dasharray: 2;
marker-start: url(#arrow);
marker-end: url(#arrow);
}
.hide { display: none !important; }
.dot { display: none; }
#controls {
position: absolute; top: 16px; right: 16px; z-index: 100;
background: rgba(255, 255, 255, 0.9); padding: 10px; border-radius: 8px; border: 1px solid #ddd;
}
#ar-button {
background-image: url(ar-assets/view_in_ar.png);
background-repeat: no-repeat; background-size: 24px 24px; background-position: 12px 50%;
background-color: #fff; position: absolute; left: 50%; transform: translateX(-50%);
white-space: nowrap; bottom: 16px; padding: 0px 18px 0px 44px;
font-family: inherit; font-size: 14px; color: #000; height: 48px;
line-height: 48px; border-radius: 24px; border: 1px solid #DADCE0; cursor: pointer;
box-shadow: 0 2px 4px rgba(0,0,0,0.15);
}
#ar-button:active { background-color: #E8EAED; }
#ar-button:focus { outline: none; }
@keyframes circle { from { transform: translateX(-50%) rotate(0deg) translateX(50px) rotate(0deg); } to { transform: translateX(-50%) rotate(360deg) translateX(50px) rotate(-360deg); } }
@keyframes elongate { from { transform: translateX(100px); } to { transform: translateX(-100px); } }
model-viewer > #ar-prompt { position: absolute; left: 50%; bottom: 85px; animation: elongate 2s infinite ease-in-out alternate; display: none; }
model-viewer[ar-status="session-started"] > #ar-prompt { display: block; }
model-viewer > #ar-prompt > img { animation: circle 4s linear infinite; }
model-viewer > #ar-failure { position: absolute; left: 50%; transform: translateX(-50%); bottom: 85px; display: none; color: red; font-weight: bold; }
model-viewer[ar-tracking="not-tracking"] > #ar-failure { display: block; }
</style>
</head>
<body>
<model-viewer
id="dimension-demo"
src="urun-modeli.glb"
poster="urun-modeli.png"
alt="Ölçülendirilebilir 3D Model"
shadow-intensity="1"
camera-controls
touch-action="pan-y"
ar
ar-modes="webxr scene-viewer quick-look"
camera-orbit="0deg 75deg 120%"
max-camera-orbit="auto auto 150%"
>
<button slot="hotspot-dot+X+Y+Z" class="dot"></button>
<button slot="hotspot-dot+X+Y-Z" class="dot"></button>
<button slot="hotspot-dot+X-Y+Z" class="dot"></button>
<button slot="hotspot-dot+X-Y-Z" class="dot"></button>
<button slot="hotspot-dot-X+Y+Z" class="dot"></button>
<button slot="hotspot-dot-X+Y-Z" class="dot"></button>
<button slot="hotspot-dot-X-Y+Z" class="dot"></button>
<button slot="hotspot-dot-X-Y-Z" class="dot"></button>
<button slot="hotspot-dim+X-Z" class="dim"></button>
<button slot="hotspot-dim+Y-Z" class="dim"></button>
<button slot="hotspot-dim-X-Y" class="dim"></button>
<svg id="dimLines" width="100%" height="100%" xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" class="dimensionLineContainer">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="10" markerHeight="10" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#16a5e6"></path>
</marker>
</defs>
<line class="dimensionLine"></line>
<line class="dimensionLine"></line>
<line class="dimensionLine"></line>
</svg>
<div id="controls">
<label for="show-dimensions">Ölçüleri Göster:</label>
<input id="show-dimensions" type="checkbox" checked="true">
</div>
<button slot="ar-button" id="ar-button">Ortamınızda Görüntüleyin</button>
<div id="ar-prompt"><img src="ar-assets/hand.png" alt="AR için zemini tara" /></div>
<button id="ar-failure">AR başlatılamadı.</button>
</model-viewer>
<script type="module">
const modelViewer = document.querySelector('#dimension-demo');
const checkbox = modelViewer.querySelector('#show-dimensions');
const dimAndLines = [...modelViewer.querySelectorAll('button.dim'), modelViewer.querySelector('#dimLines')];
function setDimensionVisibility(visible) {
dimAndLines.forEach(element => { if (element) element.classList.toggle('hide', !visible); });
}
if (checkbox) {
checkbox.addEventListener('change', () => setDimensionVisibility(checkbox.checked));
}
const dimLines = modelViewer.querySelectorAll('line');
function drawLine(svgLine, dot1, dot2) {
const offset = 12;
if (dot1 && dot2) {
const x1 = dot1.canvasPosition.x; const y1 = dot1.canvasPosition.y;
const x2 = dot2.canvasPosition.x; const y2 = dot2.canvasPosition.y;
const dx = x2 - x1; const dy = y2 - y1;
const length = Math.sqrt(dx * dx + dy * dy);
if (length > offset * 2) {
const unitX = dx / length; const unitY = dy / length;
const newX1 = x1 + unitX * offset; const newY1 = y1 + unitY * offset;
const newX2 = x2 - unitX * offset; const newY2 = y2 - unitY * offset;
svgLine.setAttribute('x1', newX1); svgLine.setAttribute('y1', newY1);
svgLine.setAttribute('x2', newX2); svgLine.setAttribute('y2', newY2);
svgLine.classList.remove('hide');
} else {
svgLine.classList.add('hide');
}
} else {
svgLine.classList.add('hide');
}
}
const renderSVG = () => {
drawLine(dimLines[0], modelViewer.queryHotspot('hotspot-dot-X+Y+Z'), modelViewer.queryHotspot('hotspot-dot+X+Y+Z'));
drawLine(dimLines[1], modelViewer.queryHotspot('hotspot-dot+X+Y+Z'), modelViewer.queryHotspot('hotspot-dot+X-Y+Z'));
drawLine(dimLines[2], modelViewer.queryHotspot('hotspot-dot+X-Y+Z'), modelViewer.queryHotspot('hotspot-dot+X-Y-Z'));
};
modelViewer.addEventListener('load', () => {
const center = modelViewer.getBoundingBoxCenter();
const size = modelViewer.getDimensions();
const x2 = size.x / 2; const y2 = size.y / 2; const z2 = size.z / 2;
const unitConversion = 1000; const unit = 'mm';
function updateHotspot(name, position) { modelViewer.updateHotspot({ name, position }); }
updateHotspot('hotspot-dot+X+Y+Z', `${center.x+x2} ${center.y+y2} ${center.z+z2}`);
updateHotspot('hotspot-dot+X+Y-Z', `${center.x+x2} ${center.y+y2} ${center.z-z2}`);
updateHotspot('hotspot-dot+X-Y+Z', `${center.x+x2} ${center.y-y2} ${center.z+z2}`);
updateHotspot('hotspot-dot+X-Y-Z', `${center.x+x2} ${center.y-y2} ${center.z-z2}`);
updateHotspot('hotspot-dot-X+Y+Z', `${center.x-x2} ${center.y+y2} ${center.z+z2}`);
updateHotspot('hotspot-dot-X+Y-Z', `${center.x-x2} ${center.y+y2} ${center.z-z2}`);
updateHotspot('hotspot-dot-X-Y+Z', `${center.x-x2} ${center.y-y2} ${center.z+z2}`);
updateHotspot('hotspot-dot-X-Y-Z', `${center.x-x2} ${center.y-y2} ${center.z-z2}`);
function setDimensionText(slot, text, position) {
const hotspot = modelViewer.querySelector(`button[slot="${slot}"]`);
if(hotspot) {
hotspot.textContent = text;
updateHotspot(slot, position);
}
}
setDimensionText('hotspot-dim+Y-Z', `${(size.x * unitConversion).toFixed(0)} ${unit}`, `${center.x} ${center.y+y2*1.1} ${center.z}`);
setDimensionText('hotspot-dim+X-Z', `${(size.y * unitConversion).toFixed(0)} ${unit}`, `${center.x+x2*1.2} ${center.y} ${center.z}`);
setDimensionText('hotspot-dim-X-Y', `${(size.z * unitConversion).toFixed(0)} ${unit}`, `${center.x+x2*1.1} ${center.y-y2*1.1} ${center.z}`);
renderSVG();
modelViewer.addEventListener('camera-change', renderSVG);
});
modelViewer.addEventListener('ar-status', (event) => {
const isArStarted = event.detail.status === 'session-started';
let shouldShowAfterAr = checkbox ? checkbox.checked : true;
setDimensionVisibility(isArStarted ? false : shouldShowAfterAr);
});
</script>
</body>
</html>
3. Model Dosyanızı Belirtin
index.html dosyasını bir metin editöründe açın ve src="urun-modeli.glb"
ile poster="urun-modeli.png"
satırlarındaki dosya adlarını kendi dosya adlarınızla değiştirin.
4. Çalıştırın!
Bu klasörü bir yerel sunucu (local server) ile çalıştırmanız gerekmektedir. Eğer Visual Studio Code kullanıyorsanız, “Live Server” eklentisi bu iş için mükemmeldir. index.html dosyasına sağ tıklayıp “Open with Live Server” demeniz yeterli.
Artık siz de ürünlerinizi en modern ve etkileşimli şekilde sunmaya hazırsınız!
KeyShot’ın Gücünü Kendiniz Deneyimleyin
Anlattığımız bu iş akışını ve KeyShot’ın sunduğu tüm profesyonel özellikleri 15 gün boyunca hiçbir kısıtlama olmadan denemek ister misiniz? Aşağıdaki formu doldurarak tam sürüm KeyShot deneme talebinizi bize iletebilirsiniz.
Başvurunuz Alındı!
Teşekkür ederiz. Size özel KeyShot Studio deneme kuponu ve indirme talimatları e-posta adresinize gönderiliyor.
Lütfen gelen kutunuzu ve spam klasörünüzü kontrol ediniz.
KeyShot Studio Deneme Sürümü
Kupon kodunuzu ve indirme linkini almak için lütfen bilgilerinizi eksiksiz doldurun.
Formu göndererek, Yedikare Yazılım’ın deneme sürümü ve ilgili ürün bilgileri hakkında sizinle iletişime geçmesini kabul etmiş olursunuz. Kişisel verileriniz, Gizlilik Politikamız kapsamında korunmaktadır.