{"id":1196,"date":"2026-10-14T16:18:53","date_gmt":"2026-10-14T06:18:53","guid":{"rendered":"https:\/\/www.appinternational.com.au\/construction-3d-preview-8b3e18d8\/"},"modified":"2026-10-14T18:03:59","modified_gmt":"2026-10-14T08:03:59","slug":"construction-facade-3d","status":"publish","type":"page","link":"https:\/\/www.appinternational.com.au\/id\/construction-facade-3d\/","title":{"rendered":"Colour-Matched Facade Joints \u2013 3D"},"content":{"rendered":"\n<style>\n.off-canvas-wrapper{overflow:clip!important}\n\n:root{--blue:#29a8e0;--ink:#06111f}\n*{box-sizing:border-box}\nbody{margin:0;font-family:\"Inter\",\"Segoe UI\",system-ui,-apple-system,sans-serif;background:radial-gradient(120% 80% at 50% 30%,#12304f 0%,#081627 55%,#040b15 100%);color:#fff;min-height:100vh;-webkit-font-smoothing:antialiased}\nheader{padding:28px 22px 8px;max-width:1100px;margin:auto}\n.eyebrow{font-size:.7rem;letter-spacing:.28em;text-transform:uppercase;color:var(--blue);font-weight:600}\nh1{font-weight:300;font-size:clamp(1.6rem,4.6vw,2.6rem);margin:.35em 0 .25em;letter-spacing:-.01em;line-height:1.1}\nh1 b{font-weight:600}\nheader p{margin:0;font-size:.88rem;color:#9fb3c8}\n#stage{position:relative;width:100%;max-width:1280px;height:70vh;height:min(70svh,640px);min-height:300px;margin:auto;overflow:hidden;box-sizing:border-box}\n#stage .zb{right:12px;top:12px}\n.zb{position:absolute;display:flex;flex-direction:column;gap:8px;z-index:4}\n.zb button{width:40px!important;height:40px!important;min-width:0!important;border-radius:50%!important;border:1px solid rgba(255,255,255,.55)!important;background:rgba(10,30,52,.75)!important;color:#fff!important;font:500 22px\/1 system-ui,sans-serif!important;cursor:pointer;padding:0!important;margin:0!important;display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent}\n.zb button:hover{background:#29a8e0!important}\n\n#stage canvas{display:block;touch-action:pan-y;max-width:100%;opacity:0;transition:opacity .8s ease}\n#stage canvas.on{opacity:1}\n.hot{position:absolute;left:0;top:0;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;background:rgba(10,30,52,.55);border:1.5px solid rgba(255,255,255,.9);color:#fff;font:600 13px\/1 inherit;cursor:pointer;padding:0;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);transition:opacity .3s,background .2s;will-change:transform}\n.hot::after{content:\"\";position:absolute;inset:-7px;border-radius:50%;border:1.5px solid var(--blue);animation:pulse 2.4s ease-out infinite;opacity:0}\n.hot:hover,.hot.act{background:var(--blue)}\n.hot.back{opacity:.35}\n@keyframes pulse{0%{transform:scale(.7);opacity:.9}100%{transform:scale(1.5);opacity:0}}\n#card{position:fixed;left:14px;right:14px;bottom:16px;max-width:460px;margin:auto;padding:18px 20px 16px;border-radius:16px;background:rgba(12,28,48,.72);backdrop-filter:blur(18px) saturate(140%);-webkit-backdrop-filter:blur(18px) saturate(140%);border:1px solid rgba(255,255,255,.12);box-shadow:0 20px 60px rgba(0,0,0,.45);transform:translateY(140%);transition:transform .5s cubic-bezier(.2,.8,.2,1);z-index:5}\n#card.show{transform:none}\n#card .n{font-size:.68rem;letter-spacing:.24em;color:var(--blue);text-transform:uppercase;font-weight:600}\n#card h2{margin:.3em 0 .35em;font-weight:500;font-size:1.15rem}\n#card #cb{font-size:.9rem;line-height:1.5;color:#d4e0ec}\n#card small{display:block;margin-top:10px;padding-top:10px;border-top:1px solid rgba(255,255,255,.1);color:#8ea5bc;font-size:.78rem}\n#card button{position:absolute;top:10px;right:12px;border:0;background:none;color:#9fb3c8;font-size:22px;cursor:pointer}\n#hint{position:absolute;left:0;right:0;bottom:6px;text-align:center;font-size:.72rem;letter-spacing:.18em;text-transform:uppercase;color:#6f88a3;pointer-events:none}\n#fallback{display:none;width:100%}\nheader.p3d-head .eyebrow{color:#29a8e0!important}\nheader.p3d-head h1,header.p3d-head h1 b{color:#fff!important}\nheader.p3d-head p{color:#9fb3c8!important}\n#card{max-height:min(62vh,520px);max-height:min(62svh,520px);overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}\n#card .pl{margin-top:12px}#card .pl span{display:block;font-size:.68rem;letter-spacing:.24em;text-transform:uppercase;color:#29a8e0;font-weight:600;margin-bottom:6px}\n#card .pl ul{list-style:none!important;margin:0!important;padding:0!important;display:flex;flex-wrap:wrap;gap:6px}\n#card .pl li{margin:0!important;padding:0!important;color:#d4e0ec;font-size:.85rem;list-style:none!important}#card .pl li::before{display:none!important}\n#card .pl li:not(:has(a)){padding:6px 10px!important;border:1px dashed rgba(255,255,255,.25);border-radius:999px}\n#card .pl a{display:inline-block;padding:6px 10px;border-radius:999px;background:rgba(41,168,224,.16);border:1px solid rgba(41,168,224,.55);color:#fff!important;text-decoration:none!important;font-size:.85rem}\n#card .pl a:hover{background:#29a8e0}\n#card h2,#card #ct{color:#fff!important}\n#card .n,#card #cn{color:#29a8e0!important}\n#card #cb{color:#d4e0ec!important}\n#card small{color:#8ea5bc!important}\n.p3d-info{max-width:900px;margin:0 auto;padding:36px 22px 48px;color:#d4e0ec!important;font-size:.95rem;line-height:1.6}\n.p3d-info h2{color:#fff!important;font-size:1.25rem!important;font-weight:500;margin:0 0 .6em}\n.p3d-info p,.p3d-info li{color:#d4e0ec!important}.p3d-info strong{color:#fff!important}\n.p3d-info ul,.p3d-info ol{padding-left:1.2em;margin:.4em 0 1.2em}\n.p3d-info img{display:block;width:100%;max-width:640px;height:auto;margin:18px auto;border-radius:12px}\n.p3d-info a.p3d-back{display:inline-block;margin-top:8px;padding:10px 18px;border-radius:999px;border:1px solid #29a8e0;color:#fff!important;text-decoration:none!important;font-weight:600}\n.p3d-info a.p3d-back:hover{background:#29a8e0}\n#stage #card{position:absolute!important;left:10px!important;right:10px!important;bottom:10px!important;top:auto!important;z-index:20!important;max-height:62%!important;transform:translateY(130%)}\n#stage #card.show{transform:none!important}\n<\/style>\n<header class=\"p3d-head\"><div class=\"eyebrow\">App International \u00b7 Construction<\/div><h1><b>Colour-matched<\/b> facade joints<\/h1><p>Drag to rotate. Pinch or use + \/ &minus; to zoom. Tap a point to learn more.<\/p><\/header>\n<div id=\"stage\"><img decoding=\"async\" id=\"fallback\" src=\"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png\" alt=\"App International bus and coach adhesive applications\" loading=\"lazy\"><div id=\"hint\">Drag to rotate<\/div><div class=\"zb\"><button type=\"button\" id=\"zi\" aria-label=\"Zoom in\">+<\/button><button type=\"button\" id=\"zo\" aria-label=\"Zoom out\">&minus;<\/button><\/div><\/div>\n<section class=\"p3d-info\"><h2>Colour-matched facade joints with Formoa 010<\/h2>\n<p>Formoa 010 is a single-component MS Polymer sealant from our partner Forgeway that can be colour-matched to any colour required, so the joint matches the facade panel.<\/p>\n<ul><li><strong>Colour matchable:<\/strong> any RAL \/ BS \/ Pantone \/ NCS reference or your specific substrate.<\/li>\n<li><strong>Substrates listed:<\/strong> composite, GRP \/ FRP, metals, plastics, poly-coated steel, concrete, painted surfaces, flexible and rigid PVC \/ EPDM.<\/li>\n<li><strong>Prep:<\/strong> clean to remove grease and contamination, apply Formoa surface activator, allow 10 minutes to flash off.<\/li>\n<li><strong>Pack:<\/strong> 290 ml cartridge; bulk options available.<\/li><\/ul>\n<img decoding=\"async\" src=\"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png\" alt=\"Formoa 010 colour-matched facade joint\" loading=\"lazy\">\n<a class=\"p3d-back\" href=\"https:\/\/www.appinternational.com.au\/construction-building\/\">&lsaquo; Back to Construction &amp; Building<\/a><\/section>\n<div id=\"card\" role=\"dialog\" aria-live=\"polite\"><button aria-label=\"Close\" id=\"cx\">\u00d7<\/button><div class=\"n\" id=\"cn\"><\/div><h2 id=\"ct\"><\/h2><div id=\"cb\"><\/div><\/div>\n<script>\nconst SPOTS=[[\"Colour-matched facade joint\", \"Formoa 010 is a single-component MS Polymer sealant that can be colour-matched to any colour required, matched to any RAL \/ BS \/ Pantone \/ NCS reference or your specific substrate. The cured joint disappears into the panel colour.\", [-0.55, 0.2, 0.12]], [\"Bead being applied\", \"Low viscosity, very easy to tool and finish, no bubble formation within the sealant, and straightforward application even in adverse conditions. Application temperature between 1 \\u00b0C and 30 \\u00b0C (lower temperatures will increase thickness).\", [1.1, 0.2, 0.25]], [\"Surface preparation\", \"Clean the surface to remove grease and contamination. Then apply Formoa surface activator prior to bonding and allow 10 minutes to flash off.\", [-1.1, 1.0, 0.12]], [\"Weathering & UV\", \"Excellent weathering and UV resistance, high UV stability, silicone and isocyanate free, and no staining of porous materials such as natural stone, granite and marble.\", [0.55, -0.6, 0.12]]];\nconst PRODS=[[[\"Formoa 010\", \"https:\/\/www.appinternational.com.au\/products\/sealants\/formoa-010\/\"]], [[\"Formoa 010\", \"https:\/\/www.appinternational.com.au\/products\/sealants\/formoa-010\/\"]], [[\"Formoa 010\", \"https:\/\/www.appinternational.com.au\/products\/sealants\/formoa-010\/\"], [\"Formoa Surface Activator (SA)\", \"https:\/\/www.appinternational.com.au\/products\/primers-activators\/formoa-surface-activator-sa\/\"]], [[\"Formoa 010\", \"https:\/\/www.appinternational.com.au\/products\/sealants\/formoa-010\/\"]]];\nconst TILT=[0.1, 0.1, 0.1, 0.1];const note=\"Formoa 010 from our partner Forgeway. Claims taken from the Formoa 010 data sheet.\";\nconst stage=document.getElementById('stage'),card=document.getElementById('card');stage.appendChild(card);\nlet focusSpot=null;\nfunction show(i){cn.textContent='0'+(i+1)+' \/ 0'+SPOTS.length;ct.textContent=SPOTS[i][0];cb.innerHTML=SPOTS[i][1]+'<div class=\"pl\"><span>Products<\/span><ul>'+PRODS[i].map(p=>'<li>'+(p[1]?'<a href=\"https:\/\/www.appinternational.com.au'+p[1]+'\">'+p[0]+' &rsaquo;<\/a>':p[0])+'<\/li>').join('')+'<\/ul><\/div><small>'+note+'<\/small>';cb.scrollTop=0;card.scrollTop=0;card.classList.add('show');focusSpot=i;document.querySelectorAll('.hot').forEach((b,j)=>b.classList.toggle('act',j==i))}\ncx.onclick=()=>{card.classList.remove('show');focusSpot=null;document.querySelectorAll('.hot').forEach(b=>b.classList.remove('act'))};\nfunction gl(){try{const c=document.createElement('canvas');return !!(c.getContext('webgl2')||c.getContext('webgl'))}catch(e){return false}}\nif(!gl()){fallback.style.display='block'}else{\n new IntersectionObserver((e,o)=>{if(e[0].isIntersecting){o.disconnect();\n  const B='https:\/\/cdn.jsdelivr.net\/npm\/three@0.160.0\/';\n  import(B+'build\/three.module.min.js').then(init).catch(()=>{fallback.style.display='block'})}}).observe(stage)}\n\n\/\/ --- tiny env without addon import: build a studio scene ourselves for PMREM ---\nfunction studioEnv(T,r){\n const s=new T.Scene();const box=new T.Mesh(new T.BoxGeometry(1,1,1),new T.MeshBasicMaterial({color:0x0d1a2a,side:T.BackSide}));box.scale.set(30,16,30);box.position.y=6;s.add(box);\n const lm=c=>new T.MeshBasicMaterial({color:c});\n const panel=(w,h,c,x,y,z,ry,rx=0)=>{const m=new T.Mesh(new T.PlaneGeometry(w,h),lm(c));m.position.set(x,y,z);m.rotation.set(rx,ry,0);s.add(m)};\n panel(18,3,new T.Color(6,6,6.4),0,13.5,0,0,Math.PI\/2);           \/\/ overhead softbox strip\n panel(8,6,new T.Color(3.2,3.4,3.6),-14.5,6,2,Math.PI\/2);        \/\/ key left\n panel(6,5,new T.Color(1.2,2.2,3.2),14.5,5,-3,-Math.PI\/2);        \/\/ cool rim right\n panel(14,1.2,new T.Color(2.5,2.5,2.5),0,4,-14.5,0);              \/\/ back strip\n panel(14,1.2,new T.Color(1.6,1.6,1.7),0,3,14.5,Math.PI);         \/\/ front strip\n const pm=new T.PMREMGenerator(r);const t=pm.fromScene(s,.03).texture;pm.dispose();return t}\n\nfunction roundedBox(T,w,h,d,rad,seg){ \/\/ extruded rounded-rect profile along Z with bevel => smooth body\n const sh=new T.Shape(),x=-w\/2,y=-h\/2;\n sh.moveTo(x+rad,y);sh.lineTo(x+w-rad,y);sh.quadraticCurveTo(x+w,y,x+w,y+rad);sh.lineTo(x+w,y+h-rad);sh.quadraticCurveTo(x+w,y+h,x+w-rad,y+h);\n sh.lineTo(x+rad,y+h);sh.quadraticCurveTo(x,y+h,x,y+h-rad);sh.lineTo(x,y+rad);sh.quadraticCurveTo(x,y,x+rad,y);\n const bv=Math.min(.12,d*.2);const g=new T.ExtrudeGeometry(sh,{depth:d-bv*2,bevelEnabled:true,bevelThickness:bv,bevelSize:bv,bevelSegments:seg||4,curveSegments:10});\n g.translate(0,0,-(d-bv*2)\/2);g.computeVertexNormals();return g}\n\nfunction init(T){\n const mobile=innerWidth<700;\n const r=new T.WebGLRenderer({alpha:true,antialias:true,powerPreference:'high-performance'});\n r.setPixelRatio(Math.min(devicePixelRatio,2));r.toneMapping=T.ACESFilmicToneMapping;r.toneMappingExposure=1.25;r.outputColorSpace=T.SRGBColorSpace;\n r.shadowMap.enabled=true;r.shadowMap.type=T.PCFSoftShadowMap;\n stage.appendChild(r.domElement);\n const s=new T.Scene();s.environment=studioEnv(T,r);\n const cam=new T.PerspectiveCamera(32,1,.1,100);\n const sun=new T.DirectionalLight(0xffffff,1.4);sun.position.set(3,9,4);sun.castShadow=true;sun.shadow.mapSize.set(mobile?1024:2048,mobile?1024:2048);\n Object.assign(sun.shadow.camera,{left:-5,right:5,top:4,bottom:-4,near:1,far:20});sun.shadow.radius=6;sun.shadow.bias=-.0005;s.add(sun);const fill=new T.DirectionalLight(0xcfe6ff,.9);fill.position.set(6,2,-3);s.add(fill);s.add(new T.HemisphereLight(0xdfefff,0x0a1422,.6));\n const COLS=[0xb7462e,0x2f5d9c,0x3f8a4f,0xe8e6e0];\n const PM=COLS.map(c=>new T.MeshPhysicalMaterial({color:c,metalness:.45,roughness:.38,clearcoat:.6,clearcoatRoughness:.2}));\n const BM=COLS.map(c=>new T.MeshPhysicalMaterial({color:c,metalness:.05,roughness:.45,clearcoat:.3}));\n const sub=new T.MeshStandardMaterial({color:0x9aa1a8,metalness:.7,roughness:.45});\n const gap=new T.MeshStandardMaterial({color:0x07090b,roughness:1});\n const nozzle=new T.MeshPhysicalMaterial({color:0xe9eef2,roughness:.25,transmission:.4,thickness:.1});\n const gunM=new T.MeshStandardMaterial({color:0x1a5f9a,metalness:.4,roughness:.4});\n const tube=new T.MeshStandardMaterial({color:0xf2f2f2,roughness:.5});\n const g=new T.Group();s.add(g);\n const add=(geo,mat,x=0,y=0,z=0,p=g)=>{const m=new T.Mesh(geo,mat);m.position.set(x,y,z);m.castShadow=true;m.receiveShadow=true;p.add(m);return m};\n add(new T.BoxGeometry(4.36,3.2,.08),gap,0,.2,-.06);\n const pw=1.0,ph=1.55,gp=.1;\n for(let i=0;i<4;i++)for(let j=0;j<2;j++){const x=(i-1.5)*(pw+gp),y=(j-.5)*(ph+gp)+.2;add(roundedBox(T,pw,ph,.09,.02,2),PM[i],x,y,.05)}\n \/\/ sub-frame rails visible in gaps\n for(let i=-1;i<=1;i++)add(new T.BoxGeometry(.04,3.3,.04),sub,i*(pw+gp),.2,-.03);\n \/\/ finished upper horizontal joint: one flush segment per panel, each matching its panel\n const segG=new T.BoxGeometry(1,gp*.98,.07);segG.translate(.5,0,0);\n\n \/\/ the joint being filled: lower horizontal, backer rod + flush bead growing behind the nozzle\n const Y=.2,X0=-2*(pw+gp),X1=2*(pw+gp);\n const br=add(new T.CylinderGeometry(.035,.035,X1-X0,10),new T.MeshStandardMaterial({color:0x6b7a88,roughness:.9}),0,Y,0);br.rotation.z=Math.PI\/2;\n const SX=i=>X0+i*(pw+gp);const segs=[0,1,2,3].map(i=>add(segG,BM[i],SX(i),Y,.06));\n \/\/ vertical joints between panels: backer rods (unfilled)\n [-1,0,1].forEach(k=>add(new T.CylinderGeometry(.035,.035,2*ph+gp,10),new T.MeshStandardMaterial({color:0x6b7a88,roughness:.9}),k*(pw+gp),.2,0));\n \/\/ caulking gun: built with nozzle tip at local origin, axis along local +x (tip -> barrel -> handle)\n const gun=new T.Group();g.add(gun);\n const n1=add(new T.ConeGeometry(.045,.34,18),nozzle,.17,0,0,gun);n1.rotation.z=Math.PI\/2;\n const c1=add(new T.CylinderGeometry(.11,.11,.9,24),tube,.79,0,0,gun);c1.rotation.z=Math.PI\/2;\n add(new T.CylinderGeometry(.12,.12,.04,24),gunM,.34,0,0,gun).rotation.z=Math.PI\/2;\n add(new T.BoxGeometry(.98,.035,.05),gunM,.8,-.14,0,gun);\n add(new T.BoxGeometry(.06,.26,.26),gunM,1.27,0,0,gun);\n add(new T.CylinderGeometry(.015,.015,.5,8),dark2(),1.5,0,0,gun).rotation.z=Math.PI\/2;\n add(new T.BoxGeometry(.09,.42,.1),gunM,1.33,-.3,0,gun).rotation.z=-.15;\n add(new T.BoxGeometry(.06,.34,.07),gunM,1.2,-.27,0,gun).rotation.z=.35;\n function dark2(){return new T.MeshStandardMaterial({color:0xcfd5da,metalness:1,roughness:.25})}\n \/\/ 45 deg: barrel goes back along travel (+x) and away from the wall (+z)\n gun.rotation.set(0,-Math.PI\/4,0);\n \/\/ sealant ribbon from tip into the joint\n const flow=add(new T.CylinderGeometry(.03,.03,.1,10),BM[0],0,0,0);flow.rotation.x=Math.PI\/2;\n \/\/ legend\n const ui=document.createElement('div');ui.style.cssText='position:absolute;left:12px;top:12px;z-index:4;display:flex;gap:8px;align-items:center;font-size:.68rem;letter-spacing:.18em;text-transform:uppercase;color:#9fb3c8';ui.innerHTML='<span>Bead = panel<\/span>'+COLS.map(c=>'<i style=\"width:18px;height:18px;border-radius:50%;border:1px solid rgba(255,255,255,.5);background:#'+c.toString(16).padStart(6,'0')+'\"><\/i>').join('');stage.appendChild(ui);\n window.__anim=t=>{const k=(t*.12)%1;const L=Math.max(.001,(X1-X0)*k);const tx=X0+L;\n  segs.forEach((sg,i)=>{sg.scale.x=Math.max(.001,Math.min(pw+gp,tx-SX(i)));sg.visible=tx>SX(i)});\n  const ci=Math.max(0,Math.min(3,Math.floor((tx-X0)\/(pw+gp))));flow.material=BM[ci];\n  gun.position.set(tx,Y,.11);flow.position.set(tx-.01,Y,.08)};\n \/\/ ground: shadow catcher + soft reflective floor fade\n const floor=new T.Mesh(new T.CircleGeometry(9,64),new T.ShadowMaterial({opacity:.45}));floor.rotation.x=-Math.PI\/2;floor.position.y=-1.21;floor.receiveShadow=true;s.add(floor);\n const cv=document.createElement('canvas');cv.width=cv.height=256;const cx2=cv.getContext('2d');const gr=cx2.createRadialGradient(128,128,10,128,128,128);\n gr.addColorStop(0,'rgba(0,0,0,.75)');gr.addColorStop(1,'rgba(0,0,0,0)');cx2.fillStyle=gr;cx2.fillRect(0,0,256,256);\n const ao=new T.Mesh(new T.PlaneGeometry(8,3.4),new T.MeshBasicMaterial({map:new T.CanvasTexture(cv),transparent:true,depthWrite:false}));ao.rotation.x=-Math.PI\/2;ao.position.y=-1.2;s.add(ao);\n const ring=new T.Mesh(new T.RingGeometry(4.6,4.63,128),new T.MeshBasicMaterial({color:0x29a8e0,transparent:true,opacity:.35}));ring.rotation.x=-Math.PI\/2;ring.position.y=-1.19;s.add(ring);\n \/\/ hotspots\n const els=SPOTS.map((sp,i)=>{const b=document.createElement('button');b.className='hot';b.textContent=i+1;b.setAttribute('aria-label',sp[0]);b.onclick=e=>{e.stopPropagation();show(i)};stage.appendChild(b);return b});\n \/\/ interaction with inertia + easing\n let ry=-.75,rx=.18,try_=ry,trx=rx,vel=0,dr=null,idle=0,zoom=1,tz=1;\n const CV=r.domElement,ZC=()=>{idle=0};const PINCHSTART=()=>{dr=null};\n let uz=1;const UZ=v=>Math.max(.45,Math.min(1.8,v));\n zi.onclick=()=>{uz=UZ(uz\/1.25);ZC()};zo.onclick=()=>{uz=UZ(uz*1.25);ZC()};\n const pts=new Map();let pd=0;const pdist=()=>{const a=[...pts.values()];return Math.hypot(a[0][0]-a[1][0],a[0][1]-a[1][1])||1};\n CV.addEventListener('pointerdown',e=>{pts.set(e.pointerId,[e.clientX,e.clientY]);if(pts.size==2){pd=pdist();PINCHSTART()}});\n addEventListener('pointermove',e=>{if(!pts.has(e.pointerId))return;pts.set(e.pointerId,[e.clientX,e.clientY]);if(pts.size>=2){const d=pdist();uz=UZ(uz*pd\/d);pd=d;ZC()}});\n const pu=e=>{pts.delete(e.pointerId)};addEventListener('pointerup',pu);addEventListener('pointercancel',pu);\n CV.addEventListener('wheel',e=>{if(!(e.ctrlKey||e.metaKey))return;e.preventDefault();uz=UZ(uz*Math.exp(e.deltaY*.0025));ZC()},{passive:false});\n CV.addEventListener('pointerdown',e=>{if(pts.size>1)return;dr=[e.clientX,e.clientY];idle=0;hint.style.opacity=0});\n addEventListener('pointerup',()=>dr=null);addEventListener('pointercancel',()=>dr=null);\n addEventListener('pointermove',e=>{if(!dr||pts.size>1)return;const dx=(e.clientX-dr[0])*.008;try_+=dx;vel=dx;trx=Math.max(-.1,Math.min(.6,trx+(e.clientY-dr[1])*.004));dr=[e.clientX,e.clientY]});\n function size(){const w=stage.clientWidth,h=stage.clientHeight;r.setSize(w,h);cam.aspect=w\/h;cam.updateProjectionMatrix()}\n addEventListener('resize',size);size();\n const v=new T.Vector3(),n=new T.Vector3(),cp=new T.Vector3();let last=performance.now();\n window.__ready=true;r.domElement.classList.add('on');\n const fitD=()=>{const v=cam.fov*Math.PI\/360,h=Math.atan(Math.tan(v)*cam.aspect);return Math.max(1.8\/Math.tan(v),2.5\/Math.tan(h))*(cam.aspect<1?1.28:1.08)};\n const dist=()=>fitD()*zoom*uz;\n (function loop(t){const dt=Math.min(.05,(t-last)\/1000||.016);last=t;\n  if(!dr){try_+=vel;vel*=.92;idle+=dt;if(idle>3&&focusSpot===null)try_+=dt*.12}\n  if(focusSpot!==null){const p=SPOTS[focusSpot][2];const target=Math.atan2(p[0],p[2])*-1;tz=.82;\n   let d=target-try_;d=Math.atan2(Math.sin(d),Math.cos(d));try_+=d*dt*3;trx+=( (TILT[focusSpot])-trx)*dt*3}else tz=1;\n  ry+=(try_-ry)*Math.min(1,dt*8);rx+=(trx-rx)*Math.min(1,dt*8);zoom+=(tz-zoom)*dt*3;\n  const D=dist();cam.position.set(Math.sin(-ry)*0+0,Math.sin(rx)*D+.4,Math.cos(rx)*D);cam.lookAt(0,-.05,0);\n  g.rotation.y=ry;if(window.__anim)__anim(t\/1000);r.render(s,cam);g.updateMatrixWorld();\n  SPOTS.forEach((sp,i)=>{v.set(...sp[2]).applyMatrix4(g.matrixWorld);n.set(sp[2][0],0,sp[2][2]).normalize().transformDirection(g.matrixWorld);\n   const facing=n.dot(cp.copy(cam.position).sub(v).normalize())>-.15||(SPOTS[i][3]==1);v.project(cam);\n   els[i].style.transform=`translate(${(v.x+1)\/2*stage.clientWidth}px,${(1-v.y)\/2*stage.clientHeight}px)`;els[i].classList.toggle('back',!facing)});\n  requestAnimationFrame(loop)})(performance.now());\n}\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>App International \u00b7 Construction Colour-matched facade joints Drag to rotate. Pinch or use + \/ &minus; to zoom. Tap a point to learn more. Drag to rotate +&minus; Colour-matched facade joints with Formoa 010 Formoa 010 is a single-component MS Polymer sealant from our partner Forgeway that can be colour-matched to any colour required, so<a class=\"excerpt-read-more\" href=\"https:\/\/www.appinternational.com.au\/id\/construction-facade-3d\/\" title=\"ReadColour-Matched Facade Joints \u2013 3D\">&#8230; Read more &raquo;<\/a><\/p>","protected":false},"author":11,"featured_media":0,"parent":0,"menu_order":-4,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-1196","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Colour-Matched Facade Joints \u2013 3D - App International<\/title>\n<meta name=\"description\" content=\"Interactive 3D facade showing Formoa 010 colour-matched to each panel and laid into the joint.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.appinternational.com.au\/id\/construction-facade-3d\/\" \/>\n<meta property=\"og:locale\" content=\"id_ID\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Colour-Matched Facade Joints \u2013 3D - App International\" \/>\n<meta property=\"og:description\" content=\"Interactive 3D facade showing Formoa 010 colour-matched to each panel and laid into the joint.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.appinternational.com.au\/id\/construction-facade-3d\/\" \/>\n<meta property=\"og:site_name\" content=\"App International\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-14T08:03:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/\",\"url\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/\",\"name\":\"Colour-Matched Facade Joints \u2013 3D - App International\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.appinternational.com.au\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/construction-3d-still.png\",\"datePublished\":\"2026-10-14T06:18:53+00:00\",\"dateModified\":\"2026-10-14T08:03:59+00:00\",\"description\":\"Interactive 3D facade showing Formoa 010 colour-matched to each panel and laid into the joint.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/#breadcrumb\"},\"inLanguage\":\"id-ID\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"id-ID\",\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.appinternational.com.au\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/construction-3d-still.png\",\"contentUrl\":\"https:\\\/\\\/www.appinternational.com.au\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/construction-3d-still.png\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/construction-facade-3d\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.appinternational.com.au\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Colour-Matched Facade Joints \u2013 3D\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/#website\",\"url\":\"https:\\\/\\\/www.appinternational.com.au\\\/\",\"name\":\"App International\",\"description\":\"Industrial adhesives, sealants, coatings and concrete fibres\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.appinternational.com.au\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"id-ID\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/#organization\",\"name\":\"App International Pty Ltd\",\"url\":\"https:\\\/\\\/www.appinternational.com.au\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"id-ID\",\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.appinternational.com.au\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/APP_logono-background-01.png\",\"contentUrl\":\"https:\\\/\\\/www.appinternational.com.au\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/APP_logono-background-01.png\",\"width\":1920,\"height\":683,\"caption\":\"App International Pty Ltd\"},\"image\":{\"@id\":\"https:\\\/\\\/www.appinternational.com.au\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Colour-Matched Facade Joints \u2013 3D - App International","description":"Interactive 3D facade showing Formoa 010 colour-matched to each panel and laid into the joint.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.appinternational.com.au\/id\/construction-facade-3d\/","og_locale":"id_ID","og_type":"article","og_title":"Colour-Matched Facade Joints \u2013 3D - App International","og_description":"Interactive 3D facade showing Formoa 010 colour-matched to each panel and laid into the joint.","og_url":"https:\/\/www.appinternational.com.au\/id\/construction-facade-3d\/","og_site_name":"App International","article_modified_time":"2026-10-14T08:03:59+00:00","og_image":[{"url":"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/","url":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/","name":"Colour-Matched Facade Joints \u2013 3D - App International","isPartOf":{"@id":"https:\/\/www.appinternational.com.au\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/#primaryimage"},"image":{"@id":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/#primaryimage"},"thumbnailUrl":"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png","datePublished":"2026-10-14T06:18:53+00:00","dateModified":"2026-10-14T08:03:59+00:00","description":"Interactive 3D facade showing Formoa 010 colour-matched to each panel and laid into the joint.","breadcrumb":{"@id":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/#breadcrumb"},"inLanguage":"id-ID","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.appinternational.com.au\/construction-facade-3d\/"]}]},{"@type":"ImageObject","inLanguage":"id-ID","@id":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/#primaryimage","url":"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png","contentUrl":"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2026\/10\/construction-3d-still.png"},{"@type":"BreadcrumbList","@id":"https:\/\/www.appinternational.com.au\/construction-facade-3d\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.appinternational.com.au\/"},{"@type":"ListItem","position":2,"name":"Colour-Matched Facade Joints \u2013 3D"}]},{"@type":"WebSite","@id":"https:\/\/www.appinternational.com.au\/#website","url":"https:\/\/www.appinternational.com.au\/","name":"App International","description":"Industrial adhesives, sealants, coatings and concrete fibres","publisher":{"@id":"https:\/\/www.appinternational.com.au\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.appinternational.com.au\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"id-ID"},{"@type":"Organization","@id":"https:\/\/www.appinternational.com.au\/#organization","name":"App International Pty Ltd","url":"https:\/\/www.appinternational.com.au\/","logo":{"@type":"ImageObject","inLanguage":"id-ID","@id":"https:\/\/www.appinternational.com.au\/#\/schema\/logo\/image\/","url":"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2025\/07\/APP_logono-background-01.png","contentUrl":"https:\/\/www.appinternational.com.au\/wp-content\/uploads\/2025\/07\/APP_logono-background-01.png","width":1920,"height":683,"caption":"App International Pty Ltd"},"image":{"@id":"https:\/\/www.appinternational.com.au\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/pages\/1196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/comments?post=1196"}],"version-history":[{"count":5,"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/pages\/1196\/revisions"}],"predecessor-version":[{"id":1209,"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/pages\/1196\/revisions\/1209"}],"wp:attachment":[{"href":"https:\/\/www.appinternational.com.au\/id\/wp-json\/wp\/v2\/media?parent=1196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}