UNPKG

@react-three/drei

Version:

useful add-ons for react-three-fiber

2 lines (1 loc) 3 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),e=require("@react-three/fiber"),i=require("three");function s(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach((function(i){if("default"!==i){var s=Object.getOwnPropertyDescriptor(t,i);Object.defineProperty(e,i,s.get?s:{enumerable:!0,get:function(){return t[i]}})}})),e.default=t,Object.freeze(e)}var a=s(t);const h=t=>Math.sqrt(1-Math.pow(t-1,2));class r{constructor({size:t=256,maxAge:e=750,radius:i=.3,intensity:s=.2,interpolate:a=0,smoothing:r=0,minForce:n=.3,blend:c="screen",ease:o=h}={}){this.size=t,this.maxAge=e,this.radius=i,this.intensity=s,this.ease=o,this.interpolate=a,this.smoothing=r,this.minForce=n,this.blend=c,this.trail=[],this.force=0,this.initTexture()}initTexture(){this.canvas=document.createElement("canvas"),this.canvas.width=this.canvas.height=this.size;const t=this.canvas.getContext("2d");if(null===t)throw new Error("2D not available");this.ctx=t,this.ctx.fillStyle="black",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height),this.texture=new i.Texture(this.canvas),this.canvas.id="touchTexture",this.canvas.style.width=this.canvas.style.height=`${this.canvas.width}px`}update(t){this.clear(),this.trail.forEach(((e,i)=>{e.age+=1e3*t,e.age>this.maxAge&&this.trail.splice(i,1)})),this.trail.length||(this.force=0),this.trail.forEach((t=>{this.drawTouch(t)})),this.texture.needsUpdate=!0}clear(){this.ctx.globalCompositeOperation="source-over",this.ctx.fillStyle="black",this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)}addTouch(t){const e=this.trail[this.trail.length-1];if(e){const i=e.x-t.x,s=e.y-t.y,a=i*i+s*s,h=Math.max(this.minForce,Math.min(1e4*a,1));if(this.force=function(t,e,i=.9){return e*i+t*(1-i)}(h,this.force,this.smoothing),this.interpolate){const t=Math.ceil(a/Math.pow(.5*this.radius/this.interpolate,2));if(t>1)for(let a=1;a<t;a++)this.trail.push({x:e.x-i/t*a,y:e.y-s/t*a,age:0,force:h})}}this.trail.push({x:t.x,y:t.y,age:0,force:this.force})}drawTouch(t){const e={x:t.x*this.size,y:(1-t.y)*this.size};let i=1;i=t.age<.3*this.maxAge?this.ease(t.age/(.3*this.maxAge)):this.ease(1-(t.age-.3*this.maxAge)/(.7*this.maxAge)),i*=t.force,this.ctx.globalCompositeOperation=this.blend;const s=this.size*this.radius*i,a=this.ctx.createRadialGradient(e.x,e.y,Math.max(0,.25*s),e.x,e.y,Math.max(0,s));a.addColorStop(0,`rgba(255, 255, 255, ${this.intensity})`),a.addColorStop(1,"rgba(0, 0, 0, 0.0)"),this.ctx.beginPath(),this.ctx.fillStyle=a,this.ctx.arc(e.x,e.y,Math.max(0,s),0,2*Math.PI),this.ctx.fill()}}function n(i={}){const{size:s,maxAge:a,radius:h,intensity:n,interpolate:c,smoothing:o,minForce:l,blend:u,ease:x}=i,d=t.useMemo((()=>new r(i)),[s,a,h,n,c,o,l,u,x]);e.useFrame(((t,e)=>{d.update(e)}));const f=t.useCallback((t=>d.addTouch(t.uv)),[d]);return[d.texture,f]}exports.TrailTexture=({children:t,...e})=>{const i=n(e);return a.createElement(a.Fragment,null,null==t?void 0:t(i))},exports.useTrailTexture=n;