UNPKG

shader-doodle

Version:

A friendly web-component for writing and rendering shaders.

18 lines (17 loc) 8.35 kB
'use strict';function _classCallCheck(d,b){if(!(d instanceof b))throw new TypeError("Cannot call a class as a function");}function _defineProperties(d,b){for(var a=0;a<b.length;a++){var c=b[a];c.enumerable=c.enumerable||!1;c.configurable=!0;"value"in c&&(c.writable=!0);Object.defineProperty(d,c.key,c)}}function _createClass(d,b,a){b&&_defineProperties(d.prototype,b);a&&_defineProperties(d,a);return d} function _inherits(d,b){if("function"!==typeof b&&null!==b)throw new TypeError("Super expression must either be null or a function");d.prototype=Object.create(b&&b.prototype,{constructor:{value:d,writable:!0,configurable:!0}});b&&_setPrototypeOf(d,b)}function _getPrototypeOf(d){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function(b){return b.__proto__||Object.getPrototypeOf(b)};return _getPrototypeOf(d)} function _setPrototypeOf(d,b){_setPrototypeOf=Object.setPrototypeOf||function(a,c){a.__proto__=c;return a};return _setPrototypeOf(d,b)}function isNativeReflectConstruct(){if("undefined"===typeof Reflect||!Reflect.construct||Reflect.construct.sham)return!1;if("function"===typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(d){return!1}} function _construct(d,b,a){_construct=isNativeReflectConstruct()?Reflect.construct:function(a,e,b){var c=[null];c.push.apply(c,e);a=new (Function.bind.apply(a,c));b&&_setPrototypeOf(a,b.prototype);return a};return _construct.apply(null,arguments)}function _isNativeFunction(d){return-1!==Function.toString.call(d).indexOf("[native code]")} function _wrapNativeSuper(d){var b="function"===typeof Map?new Map:void 0;_wrapNativeSuper=function(a){function c(){return _construct(a,arguments,_getPrototypeOf(this).constructor)}if(null===a||!_isNativeFunction(a))return a;if("function"!==typeof a)throw new TypeError("Super expression must either be null or a function");if("undefined"!==typeof b){if(b.has(a))return b.get(a);b.set(a,c)}c.prototype=Object.create(a.prototype,{constructor:{value:c,enumerable:!1,writable:!0,configurable:!0}});return _setPrototypeOf(c, a)};return _wrapNativeSuper(d)}function _assertThisInitialized(d){if(void 0===d)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return d}function _possibleConstructorReturn(d,b){return!b||"object"!==typeof b&&"function"!==typeof b?_assertThisInitialized(d):b}var DEFAULT_VS="\nattribute vec2 position;\n\nvoid main() {\n gl_Position = vec4(position, 0.0, 1.0);\n}",TEMPLATE=document.createElement("template");TEMPLATE.innerHTML="\n<style>\n :host {\n position: relative;\n display: inline-block;\n width: 250px;\n height: 250px;\n }\n :host > canvas {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n border-radius: inherit;\n }\n</style>\n"; var SHADERTOY_IO=/\(\s*out\s+vec4\s+(\S+)\s*,\s*in\s+vec2\s+(\S+)\s*\)/,ShaderDoodle=function(d){function b(){_classCallCheck(this,b);var a=_possibleConstructorReturn(this,_getPrototypeOf(b).call(this));a.shadow=a.attachShadow({mode:"open"});a.shadow.appendChild(TEMPLATE.content.cloneNode(!0));return a}_inherits(b,d);_createClass(b,[{key:"connectedCallback",value:function(){var a=this;this.mounted=!0;setTimeout(function(){if(!a.textContent.trim())return!1;try{a.init()}catch(c){a.textContent="",console.error(c&& c.message||"Error in shader-doodle.")}})}},{key:"disconnectedCallback",value:function(){this.mounted=!1;this.canvas.removeEventListener("mousedown",this.mouseDown);this.canvas.removeEventListener("mousemove",this.mouseMove);this.canvas.removeEventListener("mouseup",this.mouseUp);clearAnimationFrame(this.animationFrame)}},{key:"init",value:function(){var a=this;this.useST=this.hasAttribute("shadertoy");var c=this.textContent;this.uniforms={resolution:{name:this.useST?"iResolution":"u_resolution",type:"vec2", value:[0,0]},time:{name:this.useST?"iTime":"u_time",type:"float",value:0},delta:{name:this.useST?"iTimeDelta":"u_delta",type:"float",value:0},date:{name:this.useST?"iDate":"u_date",type:"vec4",value:[0,0,0,0]},frame:{name:this.useST?"iFrame":"u_frame",type:"int",value:0},mouse:{name:this.useST?"iMouse":"u_mouse",type:this.useST?"vec4":"vec2",value:this.useST?[0,0,0,0]:[0,0]}};this.canvas=document.createElement("canvas");this.shadow.appendChild(this.canvas);var e=this.gl=this.canvas.getContext("webgl"); this.updateRect();if(this.useST){var b=c.match(SHADERTOY_IO);c=c.replace("mainImage","main");c=c.replace(SHADERTOY_IO,"()");c=(b?"#define ".concat(b[1]," gl_FragColor\n#define ").concat(b[2]," gl_FragCoord.xy\n"):"")+c}c="precision highp float;\n"+(Object.values(this.uniforms).reduce(function(a,c){return a+"uniform ".concat(c.type," ").concat(c.name,";\n")},"")+c);e.clearColor(0,0,0,0);this.vertexShader=this.makeShader(e.VERTEX_SHADER,DEFAULT_VS);this.fragmentShader=this.makeShader(e.FRAGMENT_SHADER, c);this.program=this.makeProgram(this.vertexShader,this.fragmentShader);this.vertices=new Float32Array([-1,1,1,1,1,-1,-1,1,1,-1,-1,-1]);this.buffer=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,this.buffer);e.bufferData(e.ARRAY_BUFFER,this.vertices,e.STATIC_DRAW);e.useProgram(this.program);this.program.position=e.getAttribLocation(this.program,"position");e.enableVertexAttribArray(this.program.position);e.vertexAttribPointer(this.program.position,2,e.FLOAT,!1,0,0);Object.values(this.uniforms).forEach(function(c){c.location= e.getUniformLocation(a.program,c.name)});this._bind("mouseDown","mouseMove","mouseUp","render");this.canvas.addEventListener("mousedown",this.mouseDown);this.canvas.addEventListener("mousemove",this.mouseMove);this.canvas.addEventListener("mouseup",this.mouseUp);this.render()}},{key:"render",value:function(a){if(this&&this.mounted&&this.gl){var c=this.gl;this.updateTimeUniforms(a);this.updateRect();c.clear(c.COLOR_BUFFER_BIT);Object.values(this.uniforms).forEach(function(a){var b=a.type,e=a.location; a=a.value;b=b.match(/vec/)?"".concat(b[b.length-1],"fv"):"1".concat(b[0]);c["uniform".concat(b)](e,a)});c.drawArrays(c.TRIANGLES,0,this.vertices.length/2);this.ticking=!1;this.animationFrame=requestAnimationFrame(this.render)}}},{key:"mouseDown",value:function(a){if(this.useST){this.mousedown=!0;var c=this.rect,b=c.top,d=c.height;this.uniforms.mouse.value[2]=a.clientX-Math.floor(c.left);this.uniforms.mouse.value[3]=Math.floor(d)-(a.clientY-Math.floor(b))}}},{key:"mouseMove",value:function(a){if(!this.ticking&& (!this.useST||this.mousedown)){var c=this.rect,b=c.top,d=c.height;this.uniforms.mouse.value[0]=a.clientX-Math.floor(c.left);this.uniforms.mouse.value[1]=Math.floor(d)-(a.clientY-Math.floor(b));this.ticking=!0}}},{key:"mouseUp",value:function(a){this.useST&&(this.mousedown=!1,this.uniforms.mouse.value[2]=0,this.uniforms.mouse.value[3]=0)}},{key:"updateTimeUniforms",value:function(a){var c=this.lastTime?(a-this.lastTime)/1E3:0;this.lastTime=a;this.uniforms.time.value+=c;this.uniforms.delta.value=c; this.uniforms.frame.value++;a=new Date;this.uniforms.date.value[0]=a.getFullYear();this.uniforms.date.value[1]=a.getMonth()+1;this.uniforms.date.value[2]=a.getDate();this.uniforms.date.value[3]=3600*a.getHours()+60*a.getMinutes()+a.getSeconds()+.001*a.getMilliseconds()}},{key:"updateRect",value:function(){var a=this.rect=this.canvas.getBoundingClientRect(),c=a.width;a=a.height;var b=this.canvas.width!==c,d=this.canvas.height!==a;b&&(this.canvas.width=this.uniforms.resolution.value[0]=c);d&&(this.canvas.height= this.uniforms.resolution.value[1]=a);(b||d)&&this.gl.viewport(0,0,this.canvas.width,this.canvas.height)}},{key:"makeShader",value:function(a,c){var b=this.gl;a=b.createShader(a);b.shaderSource(a,c);b.compileShader(a);if(!b.getShaderParameter(a,b.COMPILE_STATUS)){var d=b.getShaderInfoLog(a);b.deleteShader(a);console.warn(d,"\nin shader:\n",c)}return a}},{key:"makeProgram",value:function(){for(var a=this.gl,c=a.createProgram(),b=arguments.length,d=Array(b),g=0;g<b;g++)d[g]=arguments[g];d.forEach(function(b){a.attachShader(c, b)});a.linkProgram(c);a.getProgramParameter(c,a.LINK_STATUS)||(b=a.getProgramInfoLog(this.program),console.warn(b));return c}},{key:"_bind",value:function(){for(var a=this,b=arguments.length,d=Array(b),f=0;f<b;f++)d[f]=arguments[f];d.forEach(function(b){return a[b]=a[b].bind(a)})}}]);return b}(_wrapNativeSuper(HTMLElement));customElements.define("shader-doodle",ShaderDoodle);