Diep.IO 3D

Turns diep.io into real 3D

当前为 2021-09-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Diep.IO 3D
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.0.5
  5. // @description Turns diep.io into real 3D
  6. // @author Zertalious (Zert)
  7. // @match *://diep.io/*
  8. // @icon https://www.google.com/s2/favicons?domain=diep.io
  9. // @grant none
  10. // @require https://unpkg.com/three@latest/build/three.min.js
  11. // @require https://unpkg.com/three@latest/examples/js/controls/OrbitControls.js
  12. // ==/UserScript==
  13.  
  14. const OUTLINE_LAYER = 0;
  15. const MAIN_LAYER = 1;
  16.  
  17. let renderer, scene, camera, canvas;
  18. let ortho;
  19.  
  20. let currentCamera;
  21.  
  22. init();
  23.  
  24. const tempObject = new THREE.Object3D();
  25. const tempColor = new THREE.Color();
  26.  
  27. const material = new THREE.MeshToonMaterial( { transparent: true } );
  28. const outlineMaterial = new THREE.MeshBasicMaterial( { transparent: true } );
  29.  
  30. material.onBeforeCompile = outlineMaterial.onBeforeCompile = function ( shader ) {
  31.  
  32. shader.vertexShader = shader.vertexShader.replace( 'void', `
  33.  
  34. attribute vec2 scale;
  35. attribute float alpha;
  36.  
  37. varying float vAlpha;
  38.  
  39. void` ).replace( '<begin_vertex>', `<begin_vertex>
  40.  
  41. if ( scale.x != 0.0 && scale.y != 0.0 ) {
  42.  
  43. if ( transformed.x == 1.0 || transformed.x == 0.5 ) {
  44.  
  45. transformed.yz *= scale.x;
  46.  
  47. } else if ( transformed.x == - 1.0 || transformed.x == - 0.5 ) {
  48.  
  49. transformed.yz *= scale.y;
  50.  
  51. }
  52.  
  53. }
  54.  
  55. vAlpha = alpha;
  56.  
  57. ` );
  58.  
  59. shader.fragmentShader = shader.fragmentShader.replace( 'void', `
  60.  
  61. varying float vAlpha;
  62.  
  63. void` ).replace( '}', `
  64.  
  65. gl_FragColor.a *= vAlpha;
  66.  
  67. }` );
  68.  
  69. }
  70.  
  71. const instances = {};
  72.  
  73. const array = [ {
  74. name: 'sphere',
  75. geometry: new THREE.SphereGeometry( 1, 16 ),
  76. count: 150
  77. }, {
  78. name: 'cylinder',
  79. geometry: new THREE.CylinderGeometry( 0.5, 0.5, 1, 16 ).rotateZ( Math.PI / 2 ),
  80. count: 75,
  81. hasScaling: true
  82. }, {
  83. name: 'poly3',
  84. geometry: new THREE.CylinderGeometry( 1, 1, 1, 3, 1, false, - Math.PI / 6 ).rotateX( Math.PI / 2 ),
  85. count: 75
  86. }, {
  87. name: 'poly4',
  88. geometry: new THREE.BoxGeometry( 1, 1, 1 ),
  89. count: 75
  90. }, {
  91. name: 'poly5',
  92. geometry: new THREE.CylinderGeometry( 1, 1, 1, 5, 1, false, Math.PI / 10 ).rotateX( Math.PI / 2 ),
  93. count: 40
  94. }, {
  95. name: 'poly6',
  96. geometry: new THREE.CylinderGeometry( 1, 1, 1, 6, 1, false, - Math.PI / 12 ).rotateX( Math.PI / 2 ),
  97. count: 10
  98. } ];
  99.  
  100. for ( let i = 0; i < array.length; i ++ ) {
  101.  
  102. const { name, geometry, count, hasScaling } = array[ i ];
  103.  
  104. if ( hasScaling ) {
  105.  
  106. geometry.setAttribute( 'scale', new THREE.InstancedBufferAttribute( new Float32Array( count * 2 ), 2 ) );
  107.  
  108. }
  109.  
  110. geometry.setAttribute( 'alpha', new THREE.InstancedBufferAttribute( new Float32Array( count ), 1 ) );
  111.  
  112. const main = new THREE.InstancedMesh( geometry, material, count );
  113. main.layers.set( MAIN_LAYER );
  114. scene.add( main );
  115.  
  116. const outline = new THREE.InstancedMesh( geometry, outlineMaterial, count );
  117. outline.layers.set( OUTLINE_LAYER );
  118. scene.add( outline );
  119.  
  120. main.setColorAt( 0, tempColor );
  121. outline.setColorAt( 0, tempColor );
  122.  
  123. instances[ name ] = {
  124. main,
  125. outline,
  126. count,
  127. hasScaling,
  128. index: 0
  129. };
  130.  
  131. }
  132.  
  133. const stack = [];
  134.  
  135. function getStack( index ) {
  136.  
  137. const result = stack[ stack.length - 1 - index ];
  138.  
  139. if ( result ) {
  140.  
  141. return result;
  142.  
  143. }
  144.  
  145. return { name: 'none' };
  146.  
  147. }
  148.  
  149. function setObject( name, x, y, z, sx, sy, sz, angle, color, alpha = 1, scaleX = 1, scaleY = 1 ) {
  150.  
  151. tempObject.position.set( x, y, z );
  152. tempObject.scale.set( sx, sy, sz );
  153. tempObject.rotation.set( 0, 0, angle );
  154.  
  155. tempObject.updateMatrix();
  156.  
  157. tempColor.set( color );
  158.  
  159. const instance = instances[ name ];
  160.  
  161. instance.main.setMatrixAt( instance.index, tempObject.matrix );
  162. instance.main.setColorAt( instance.index, tempColor );
  163.  
  164. instance.main.geometry.attributes.alpha.setX( instance.index, alpha );
  165. instance.outline.geometry.attributes.alpha.setX( instance.index, alpha );
  166.  
  167. const outlineSize = 4 / window.innerHeight * ( name === 'sphere' ? 0.7 : 1 );
  168.  
  169. if ( instance.hasScaling ) {
  170.  
  171. tempObject.scale.x += outlineSize;
  172. tempObject.scale.y += outlineSize / scaleY;
  173. tempObject.scale.z += outlineSize / scaleY;
  174.  
  175. } else {
  176.  
  177. tempObject.scale.addScalar( outlineSize );
  178.  
  179. }
  180.  
  181. tempObject.updateMatrix();
  182.  
  183. tempColor.multiplyScalar( 0.6 );
  184.  
  185. instance.outline.setMatrixAt( instance.index, tempObject.matrix );
  186. instance.outline.setColorAt( instance.index, tempColor );
  187.  
  188. if ( instance.hasScaling ) {
  189.  
  190. instance.main.geometry.attributes.scale.setXY( instance.index, scaleX, scaleY );
  191. instance.outline.geometry.attributes.scale.setXY( instance.index, scaleX, scaleY );
  192.  
  193. }
  194.  
  195. instance.index ++;
  196.  
  197. stack.push( { name, x, y, z, sx, sy, sz, angle, color, outlineSize, alpha } );
  198.  
  199. }
  200.  
  201. function init() {
  202.  
  203. canvas = document.getElementById( 'canvas' );
  204.  
  205. renderer = new THREE.WebGLRenderer( {
  206. antialias: true,
  207. alpha: true
  208. } );
  209.  
  210. renderer.autoClear = false;
  211.  
  212. renderer.setPixelRatio( window.devicePixelRatio );
  213. renderer.setSize( canvas.width, canvas.height, false );
  214.  
  215. renderer.domElement.style.position = 'absolute';
  216. renderer.domElement.style.left = '0';
  217. renderer.domElement.style.top = '0';
  218. renderer.domElement.style.width = '100%';
  219. renderer.domElement.style.height = '100%';
  220. renderer.domElement.style.pointerEvents = 'none';
  221.  
  222. canvas.parentNode.insertBefore( renderer.domElement, canvas.nextSibling );
  223.  
  224. scene = new THREE.Scene();
  225.  
  226. camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 1000 );
  227.  
  228. ortho = new THREE.OrthographicCamera( - camera.aspect / 2, camera.aspect / 2, 0.5, - 0.5, 0, 1000 );
  229.  
  230. currentCamera = camera;
  231.  
  232. const oldZ = Math.sin( Math.PI / 3 );
  233. camera.position.z = ortho.position.z = oldZ;
  234.  
  235. const ambLight = new THREE.AmbientLight( 0xffffff, 0.5 );
  236. ambLight.layers.set( MAIN_LAYER );
  237. scene.add( ambLight );
  238.  
  239. const dirLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
  240. dirLight.layers.set( MAIN_LAYER );
  241. dirLight.position.z = 1;
  242. scene.add( dirLight );
  243.  
  244. const controls = new THREE.OrbitControls( camera, canvas );
  245.  
  246. controls.enabled = false;
  247.  
  248. window.addEventListener( 'keyup', function ( event ) {
  249.  
  250. const key = String.fromCharCode( event.keyCode );
  251.  
  252. if ( key === 'V' ) {
  253.  
  254. controls.enabled = ! controls.enabled;
  255.  
  256. if ( ! controls.enabled ) {
  257.  
  258. camera.position.set( 0, 0, oldZ );
  259. camera.rotation.set( 0, 0, 0 );
  260.  
  261. controls.target.set( 0, 0, 0 );
  262.  
  263. ortho.position.set( 0, 0, oldZ );
  264. ortho.rotation.set( 0, 0, 0 );
  265.  
  266. ortho.zoom = 1;
  267.  
  268. }
  269.  
  270. } else if ( key === 'P' ) {
  271.  
  272. currentCamera = currentCamera === camera ? ortho : camera;
  273.  
  274. currentCamera.position.copy( controls.object.position );
  275. currentCamera.rotation.copy( controls.object.rotation );
  276.  
  277. controls.object = currentCamera;
  278.  
  279. }
  280.  
  281. } );
  282.  
  283. window.addEventListener( 'resize', onWindowResize );
  284.  
  285. }
  286.  
  287. function onWindowResize() {
  288.  
  289. renderer.setSize( canvas.width, canvas.height, false );
  290. camera.aspect = canvas.width / canvas.height;
  291. camera.updateProjectionMatrix();
  292.  
  293. ortho.left = - camera.aspect / 2;
  294. ortho.right = camera.aspect / 2;
  295. ortho.updateProjectionMatrix();
  296.  
  297. }
  298.  
  299. window.requestAnimationFrame = new Proxy( window.requestAnimationFrame, {
  300. apply( target, thisArgs, args ) {
  301.  
  302. args[ 0 ] = new Proxy( args[ 0 ], {
  303. apply( target, thisArgs, args ) {
  304.  
  305. stack.length = 0;
  306.  
  307. tempObject.position.setScalar( 0 );
  308. tempObject.scale.setScalar( 0 );
  309. tempObject.rotation.set( 0, 0, 0 );
  310.  
  311. tempObject.updateMatrix();
  312.  
  313. tempColor.setRGB( 0, 0, 0 );
  314.  
  315. for ( let key in instances ) {
  316.  
  317. const { main, outline, count, hasScaling } = instances[ key ];
  318.  
  319. for ( let i = 0; i < count; i ++ ) {
  320.  
  321. main.setMatrixAt( i, tempObject.matrix );
  322. outline.setMatrixAt( i, tempObject.matrix );
  323.  
  324. }
  325.  
  326. main.instanceMatrix.needsUpdate = true;
  327. main.instanceColor.needsUpdate = true;
  328.  
  329. outline.instanceMatrix.needsUpdate = true;
  330. outline.instanceColor.needsUpdate = true;
  331.  
  332. if ( hasScaling ) {
  333.  
  334. main.geometry.attributes.scale.needsUpdate = true;
  335. outline.geometry.attributes.scale.needsUpdate = true;
  336.  
  337. }
  338.  
  339. main.geometry.attributes.alpha.needsUpdate = true;
  340. outline.geometry.attributes.alpha.needsUpdate = true;
  341.  
  342. instances[ key ].index = 0;
  343.  
  344. }
  345.  
  346. arcCounter = 0;
  347.  
  348. Reflect.apply( ...arguments );
  349.  
  350. renderer.clear();
  351.  
  352. currentCamera.layers.set( OUTLINE_LAYER );
  353.  
  354. renderer.render( scene, currentCamera );
  355.  
  356. renderer.clearDepth();
  357.  
  358. currentCamera.layers.set( MAIN_LAYER );
  359.  
  360. renderer.render( scene, currentCamera );
  361.  
  362. }
  363. } );
  364.  
  365. return Reflect.apply( ...arguments );
  366.  
  367. }
  368. } );
  369.  
  370. const Context2D = CanvasRenderingContext2D.prototype;
  371.  
  372. let arcCounter = 0;
  373.  
  374. Context2D.arc = new Proxy( Context2D.arc, {
  375. apply( target, thisArgs, args ) {
  376.  
  377. if ( args[ 4 ] === Math.PI * 2 ) {
  378.  
  379. if ( arcCounter === 0 ) {
  380.  
  381. const matrix = thisArgs.getTransform();
  382.  
  383. const r = matrix.a / canvas.height;
  384.  
  385. const x = ( matrix.e / canvas.width - 0.5 ) * camera.aspect;
  386. const y = 0.5 - matrix.f / canvas.height;
  387.  
  388. let z = 0;
  389.  
  390. const s0 = getStack( 0 );
  391. const s1 = getStack( 1 );
  392.  
  393. if ( s0.name === 'cylinder' && s1.name === 'sphere' && Math.hypot( x - s1.x, y - s1.y ) < 0.001 ) {
  394.  
  395. z = s1.sz;
  396.  
  397. const index = ( instances.cylinder.index - 1 ) * 16 + 14;
  398.  
  399. const newDepth = z + r - s0.sz / 2;
  400.  
  401. instances.cylinder.main.instanceMatrix.array[ index ] = newDepth;
  402. instances.cylinder.outline.instanceMatrix.array[ index ] = newDepth;
  403.  
  404. } else myBlock: {
  405.  
  406. if ( getStack( 0 ).name === 'cylinder' &&
  407. getStack( 1 ).name === 'sphere' &&
  408. getStack( 2 ).name === 'cylinder' &&
  409. getStack( 3 ).name === 'sphere' &&
  410. getStack( 4 ).name === 'cylinder' &&
  411. getStack( 5 ).name === 'poly3' &&
  412. getStack( 6 ).name === 'cylinder' ) {
  413.  
  414. z = getStack( 5 ).sz / 2;
  415.  
  416. const tr = getStack( 2 ).sz;
  417.  
  418. for ( let i = 0; i < 3; i ++ ) {
  419.  
  420. const index = ( instances.cylinder.index - 1 - i ) * 16 + 14;
  421.  
  422. const newDepth = z + r - tr / 2;
  423.  
  424. instances.cylinder.main.instanceMatrix.array[ index ] = newDepth;
  425. instances.cylinder.outline.instanceMatrix.array[ index ] = newDepth;
  426.  
  427. }
  428.  
  429. for ( let i = 0; i < 2; i ++ ) {
  430.  
  431. const index = ( instances.sphere.index - 1 - i ) * 16 + 14;
  432.  
  433. instances.sphere.main.instanceMatrix.array[ index ] = z;
  434. instances.sphere.outline.instanceMatrix.array[ index ] = z;
  435.  
  436. }
  437.  
  438. break myBlock;
  439.  
  440. }
  441.  
  442. for ( let i = 0; i < 5; i ++ ) {
  443.  
  444. if ( getStack( i ).name !== 'cylinder' ) {
  445.  
  446. break myBlock;
  447.  
  448. }
  449.  
  450. }
  451.  
  452. if ( getStack( 0 ).angle !== getStack( 2 ).angle ) {
  453.  
  454. break myBlock;
  455.  
  456. }
  457.  
  458. const a = r - getStack( 0 ).sy;
  459.  
  460. for ( let i = 0; i < 5; i ++ ) {
  461.  
  462. const index = ( instances.cylinder.index - 1 - i ) * 16 + 14;
  463.  
  464. const newDepth = a - a * 2 * i / 4;
  465.  
  466. instances.cylinder.main.instanceMatrix.array[ index ] = newDepth;
  467. instances.cylinder.outline.instanceMatrix.array[ index ] = newDepth;
  468.  
  469. }
  470.  
  471. }
  472.  
  473. checkIfIsMainCanvas( thisArgs, 'sphere' );
  474.  
  475. setObject(
  476. 'sphere',
  477. x,
  478. y,
  479. z,
  480. r,
  481. r,
  482. r,
  483. 0,
  484. thisArgs.fillStyle,
  485. thisArgs.globalAlpha
  486. );
  487.  
  488. } else if ( arcCounter === 1 ) {
  489.  
  490. tempColor.set( thisArgs.fillStyle );
  491. instances.sphere.main.setColorAt( instances.sphere.index - 1, tempColor );
  492.  
  493. tempColor.multiplyScalar( 0.6 );
  494. instances.sphere.outline.setColorAt( instances.sphere.index - 1, tempColor );
  495.  
  496. }
  497.  
  498. arcCounter = ( arcCounter + 1 ) % 3;
  499.  
  500. }
  501.  
  502. return Reflect.apply( ...arguments );
  503.  
  504. }
  505. } );
  506.  
  507. Context2D.rect = new Proxy( Context2D.rect, {
  508. apply( target, thisArgs, args ) {
  509.  
  510. const matrix = thisArgs.getTransform();
  511.  
  512. const isTurret = matrix.b !== 0 && matrix.c !== 0;
  513.  
  514. if ( isTurret || ( thisArgs.canvas === canvas && Math.hypot( matrix.c, matrix.d ) > 100 && thisArgs.globalAlpha === 1 ) ) {
  515.  
  516. const center = new DOMPoint( 0.5, 0.5 ).matrixTransform( matrix );
  517.  
  518. const scaleYZ = Math.hypot( matrix.c, matrix.d ) / canvas.height;
  519.  
  520. const name = isTurret ? 'cylinder' : 'poly4';
  521.  
  522. checkIfIsMainCanvas( thisArgs, name );
  523.  
  524. setObject(
  525. name,
  526. ( center.x / canvas.width - 0.5 ) * camera.aspect,
  527. 0.5 - center.y / canvas.height,
  528. isTurret ? 0 : 0.05,
  529. Math.hypot( matrix.a, matrix.b ) / canvas.height,
  530. scaleYZ,
  531. isTurret ? scaleYZ : 0.1,
  532. Math.atan2( matrix.c, matrix.d ),
  533. thisArgs.fillStyle,
  534. thisArgs.globalAlpha
  535. );
  536.  
  537. }
  538.  
  539. return Reflect.apply( ...arguments );
  540.  
  541. }
  542. } );
  543.  
  544. const points = [];
  545. let hasCurve = true;
  546.  
  547. Context2D.beginPath = new Proxy( Context2D.beginPath, {
  548. apply( target, thisArgs, args ) {
  549.  
  550. points.length = 0;
  551. hasCurve = false;
  552.  
  553. return Reflect.apply( ...arguments );
  554.  
  555. }
  556. } );
  557.  
  558. const addPoint = {
  559. apply( target, thisArgs, [ x, y ] ) {
  560.  
  561. points.push( new DOMPoint( x, y ).matrixTransform( thisArgs.getTransform() ) );
  562.  
  563. return Reflect.apply( ...arguments );
  564.  
  565. }
  566. };
  567.  
  568. Context2D.moveTo = new Proxy( Context2D.moveTo, addPoint );
  569. Context2D.lineTo = new Proxy( Context2D.lineTo, addPoint );
  570.  
  571. Context2D.arc = new Proxy( Context2D.arc, {
  572. apply( target, thisArgs, args ) {
  573.  
  574. hasCurve = true;
  575.  
  576. return Reflect.apply( ...arguments );
  577.  
  578. }
  579. } );
  580.  
  581. Context2D.fill = new Proxy( Context2D.fill, {
  582. apply( target, thisArgs, args ) {
  583.  
  584. if ( ! hasCurve ) {
  585.  
  586. if ( points.length > 2 && points.length < 7 ) myBlock: {
  587.  
  588. const center = { x: 0, y: 0 };
  589.  
  590. const count = points.length;
  591.  
  592. for ( let i = 0; i < count; i ++ ) {
  593.  
  594. center.x += points[ i ].x;
  595. center.y += points[ i ].y;
  596.  
  597. }
  598.  
  599. center.x /= count;
  600. center.y /= count;
  601.  
  602. if ( points.length === 6 ) {
  603.  
  604. const d1 = Math.hypot( points[ 0 ].x - center.x, points[ 0 ].y - center.y );
  605. const d2 = Math.hypot( points[ 1 ].x - center.x, points[ 1 ].y - center.y );
  606.  
  607. if ( Math.abs( d1 - d2 ) > 0.01 ) {
  608.  
  609. break myBlock;
  610.  
  611. }
  612.  
  613. }
  614.  
  615. let s, sx, angle, scaleX, scaleY;
  616.  
  617. let name = 'poly' + points.length;
  618.  
  619. if ( points.length === 4 ) {
  620.  
  621. const [ p0, p1, p2 ] = points;
  622. const pl = points[ points.length - 1 ];
  623.  
  624. scaleX = Math.hypot( p1.x - p2.x, p1.y - p2.y ) / canvas.height;
  625. scaleY = Math.hypot( p0.x - pl.x, p0.y - pl.y ) / canvas.height;
  626.  
  627. const dx = ( p1.x + p2.x ) / 2 - ( p0.x + pl.x ) / 2;
  628. const dy = ( p1.y + p2.y ) / 2 - ( p0.y + pl.y ) / 2;
  629.  
  630. sx = Math.hypot( dx, dy ) / canvas.height;
  631. angle = Math.atan2( dx, dy ) - Math.PI / 2;
  632.  
  633. if ( Math.abs( scaleX - scaleY ) > 0.001 ) {
  634.  
  635. s = 1;
  636. name = 'cylinder';
  637.  
  638. } else {
  639.  
  640. s = sx = scaleY;
  641.  
  642. }
  643.  
  644. } else {
  645.  
  646. s = sx = Math.hypot( points[ 0 ].x - center.x, points[ 0 ].y - center.y ) / canvas.height;
  647.  
  648. angle = - Math.atan2( points[ 0 ].y - center.y, points[ 0 ].x - center.x );
  649.  
  650. }
  651.  
  652. checkIfIsMainCanvas( thisArgs, name );
  653.  
  654. setObject(
  655. name,
  656. ( center.x / canvas.width - 0.5 ) * camera.aspect,
  657. 0.5 - center.y / canvas.height,
  658. 0,
  659. sx,
  660. s,
  661. s,
  662. angle,
  663. thisArgs.fillStyle,
  664. thisArgs.globalAlpha,
  665. scaleX,
  666. scaleY
  667. );
  668.  
  669. }
  670.  
  671. }
  672.  
  673. return Reflect.apply( ...arguments );
  674.  
  675. }
  676. } );
  677.  
  678. Context2D.drawImage = new Proxy( Context2D.drawImage, {
  679. apply( target, thisArgs, args ) {
  680.  
  681. if ( thisArgs.canvas === canvas && args[ 0 ].objects ) {
  682.  
  683. const matrix = thisArgs.getTransform();
  684.  
  685. const x = matrix.e / canvas.width;
  686. const y = matrix.f / canvas.height;
  687.  
  688. const sx = Math.hypot( matrix.a, matrix.b );
  689. const sy = Math.hypot( matrix.c, matrix.d );
  690.  
  691. for ( let i = 0; i < args[ 0 ].objects.length; i ++ ) {
  692.  
  693. const { name, index } = args[ 0 ].objects[ i ];
  694.  
  695. const instance = instances[ name ];
  696.  
  697. const ma = instance.main.instanceMatrix.array;
  698. const oa = instance.outline.instanceMatrix.array;
  699.  
  700. const idx = index * 16;
  701.  
  702. const ox = ma[ idx + 12 ] / camera.aspect + 0.5;
  703. const oy = - ma[ idx + 13 ] + 0.5;
  704.  
  705. const outlineOldSx = Math.hypot( oa[ idx + 0 ], oa[ idx + 1 ] );
  706. const outlineOldSy = Math.hypot( oa[ idx + 4 ], oa[ idx + 5 ] );
  707.  
  708. const outlineSizeX = outlineOldSx - Math.hypot( ma[ idx + 0 ], ma[ idx + 1 ] );
  709. const outlineSizeY = outlineOldSy - Math.hypot( ma[ idx + 4 ], ma[ idx + 5 ] );
  710.  
  711. ma[ idx + 0 ] *= sx;
  712. ma[ idx + 1 ] *= sx;
  713. ma[ idx + 4 ] *= sy;
  714. ma[ idx + 5 ] *= sy;
  715. ma[ idx + 10 ] *= sy;
  716.  
  717. const nsx = Math.hypot( ma[ idx + 0 ], ma[ idx + 1 ] ) + outlineSizeX;
  718. const nsy = Math.hypot( ma[ idx + 4 ], ma[ idx + 5 ] ) + outlineSizeY;
  719.  
  720. oa[ idx + 0 ] *= nsx / outlineOldSx;
  721. oa[ idx + 1 ] *= nsx / outlineOldSx;
  722. oa[ idx + 4 ] *= nsy / outlineOldSy;
  723. oa[ idx + 5 ] *= nsy / outlineOldSy;
  724. oa[ idx + 10 ] *= sy;
  725.  
  726. ma[ idx + 12 ] = oa[ idx + 12 ] = ( ( ox * sx + x ) - 0.5 ) * camera.aspect;
  727. ma[ idx + 13 ] = oa[ idx + 13 ] = 0.5 - ( oy * sy + y );
  728.  
  729. instance.main.geometry.attributes.alpha.array[ index ] = thisArgs.globalAlpha;
  730. instance.outline.geometry.attributes.alpha.array[ index ] = thisArgs.globalAlpha;
  731.  
  732. }
  733.  
  734. delete args[ 0 ][ 'objects' ];
  735.  
  736. }
  737.  
  738. return Reflect.apply( ...arguments );
  739.  
  740. }
  741. } );
  742.  
  743. function checkIfIsMainCanvas( ctx, name ) {
  744.  
  745. if ( ctx.canvas !== canvas ) {
  746.  
  747. const { index } = instances[ name ];
  748.  
  749. if ( ctx.canvas.objects ) {
  750.  
  751. ctx.canvas.objects.push( { name, index } );
  752.  
  753. } else {
  754.  
  755. ctx.canvas.objects = [ { name, index } ];
  756.  
  757. }
  758.  
  759. }
  760.  
  761. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址