分享three.js实现粒子背景

three.js中粒子效果的实现方式大概分为三种:
1、Javascript直接计算粒子的状态变化,即基于CPU实现;
2、Javascript通知顶点着色器粒子的生命周期,由顶点着色器运行,即基于GPU实现;
3、粒子生成与状态维护全部由片元着色器负责,即屏幕特效,同样是基于GPU中实现。

9a674d5348ee4deeb63f5475900ffb4d.png

粒子特效可以实现非常多的效果,如星空、烟雾、雨、灰尘、火等。粒子特效的优势是即使使用了成百上千的例子,也能保证比较高的帧率。

42a3522119674b61b15273d81a3a95c1.png

缺点是每个粒子都由一个始终面向相机的平面(两个三角形)组成。

点材质也是three.js最简单的类之一,相对于基类Material,它多做的事情只是传递了size,即点的尺寸这个值。

申明type是Points,执行渲染时,WebGL会绘制Point,即调用gl.drawArrays(gl.POINTS)。
type为Mesh时,three.js会调用gl.drawArrays(gl.TRIANGLES)。

着色器1

79272992e02646d58ad7c35db2da1a7a.png

<script id="vertex-shader" type="x-shader/x-vertex">
    //
    // GLSL textureless classic 2D noise "cnoise",
    // with an RSL-style periodic variant "pnoise".
    // Author:  Stefan Gustavson (stefan.gustavson@liu.se)
    // Version: 2011-08-22
    //
    // Many thanks to Ian McEwan of Ashima Arts for the
    // ideas for permutation and gradient selection.
    //
    // Copyright (c) 2011 Stefan Gustavson. All rights reserved.
    // Distributed under the MIT license. See LICENSE file.
    // https://github.com/ashima/webgl-noise
    //

    vec4 mod289(vec4 x)
    {
      return x - floor(x * (1.0 / 289.0)) * 289.0;
    }

    vec4 permute(vec4 x)
    {
      return mod289(((x*34.0)+1.0)*x);
    }

    vec4 taylorInvSqrt(vec4 r)
    {
      return 1.79284291400159 - 0.85373472095314 * r;
    }

    vec2 fade(vec2 t) {
      return t*t*t*(t*(t*6.0-15.0)+10.0);
    }

    // Classic Perlin noise
    float cnoise(vec2 P)
    {
      vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
      vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
      Pi = mod289(Pi); // To avoid truncation effects in permutation
      vec4 ix = Pi.xzxz;
      vec4 iy = Pi.yyww;
      vec4 fx = Pf.xzxz;
      vec4 fy = Pf.yyww;

      vec4 i = permute(permute(ix) + iy);

      vec4 gx = fract(i * (1.0 / 41.0)) * 2.0 - 1.0 ;
      vec4 gy = abs(gx) - 0.5 ;
      vec4 tx = floor(gx + 0.5);
      gx = gx - tx;

      vec2 g00 = vec2(gx.x,gy.x);
      vec2 g10 = vec2(gx.y,gy.y);
      vec2 g01 = vec2(gx.z,gy.z);
      vec2 g11 = vec2(gx.w,gy.w);

      vec4 norm = taylorInvSqrt(vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
      g00 *= norm.x;
      g01 *= norm.y;
      g10 *= norm.z;
      g11 *= norm.w;

      float n00 = dot(g00, vec2(fx.x, fy.x));
      float n10 = dot(g10, vec2(fx.y, fy.y));
      float n01 = dot(g01, vec2(fx.z, fy.z));
      float n11 = dot(g11, vec2(fx.w, fy.w));

      vec2 fade_xy = fade(Pf.xy);
      vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
      float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
      return 2.3 * n_xy;
    }

    float map(float value, float oldMin, float oldMax, float newMin, float newMax) {
        return newMin + (newMax - newMin) * (value - oldMin) / (oldMax - oldMin);
    }

    varying vec3 vUv;
    varying float vTime;
    varying float vZ;
    uniform float time;
    void main()
    {
        vUv = position;
        vTime = time;
        vec3 newPos = position;
        vec2 peak = vec2(1.0 - abs(.5 - uv.x), 1.0 - abs(.5 - uv.y));
        vec2 noise = vec2(
            map(cnoise(vec2(0.3 * time + uv.x * 5., uv.y * 5.)), 0., 1., -2., (peak.x * peak.y * 30.)),
            map(cnoise(vec2(-0.3 * time + uv.x * 5., uv.y * 5.)), 0., 1., -2., 25.)
        );

        //newPos.x += noise.x * 10.;
        newPos.z += noise.x * .06 * noise.y;
        vZ = newPos.z;
        vec4 mvPosition = modelViewMatrix * vec4( newPos, 1.0 );
        gl_PointSize = 5.0;
        gl_Position = projectionMatrix * mvPosition;
    }
    </script>

    <script id="fragment-shader" type="x-shader/x-fragment">
    varying vec3 vUv;
    varying float vTime;
    varying float vZ;
    uniform sampler2D texture;

    float map(float value, float oldMin, float oldMax, float newMin, float newMax) {
        return newMin + (newMax - newMin) * (value - oldMin) / (oldMax - oldMin);
    }


    void main()
    {
        vec3 colorA = vec3(.6, 0.17, 0.17);
        vec3 colorB = vec3(0.17, 0.8, .7); 
        //vec3 color = mix(colorA, colorB, vUv.x * vUv.y);
        float alpha = map(vZ / 2., -1. / 2., 30. / 2., 0.17, 1.); 
        vec3 color = vec3(.5, .5, .6);

        gl_FragColor = vec4( color, alpha);
        //gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
    }
    </script>

着色器2

89d5593710154beb88e0de3cba39b888.png

<!-- built files will be auto injected -->
  <!--粒子背景相关脚本-->
  <script id="vertexShader" type="x-shader/x-vertex">
    attribute vec4 position;
    attribute float scale;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    void main() {
      vec4 mvPosition = modelViewMatrix * position;
      gl_PointSize = scale*1.0 * ( 200.0 / - mvPosition.z );
      gl_Position = projectionMatrix * mvPosition;
    }
  </script>

  <script id="fragmentShader" type="x-shader/x-fragment">
    void main() {
      if ( length( gl_PointCoord - vec2( 0.5, 0.5 ) ) > 0.49 ) discard;
      //gl_FragColor = vec4(0.0,1.0,1.0,1.0);
      // 根据片元的x坐标,来设置片元的像素值
      if(gl_FragCoord.x < 120.0){
        // canvas画布上[0,20)之间片元像素值设置
        //gl_FragColor = vec4(1.0,0.0,0.0,1.0);
        // 片元沿着x方向渐变
        gl_FragColor = vec4(gl_FragCoord.x/1000.0*0.1,1.0,1.0,0.1);
      }else if (gl_FragCoord.x <= 1800.0) {
        // canvas画布上(20,1900]之间片元像素值设置
        //gl_FragColor = vec4(0.0,1.0,0.0,1.0);
        // 片元沿着y方向渐变
        gl_FragColor = vec4(0.0,gl_FragCoord.y/3000.0*1.0,1.0,0.1);
      }else {
        // canvas画布上(1900,1920]之间片元像素值设置
        //gl_FragColor = vec4(0.0,0.0,1.0,1.0);
        // 片元沿着z方向渐变
        gl_FragColor = vec4(0.0,1.0,gl_FragCoord.z/1000.0*1.0,0.1);
      }
    }
  </script>

依赖importmap

<script type="importmap">
    {
      "imports": {
        "three": "https://cdn.jsdelivr.net/npm/three@0.162.0/+esm",
        "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.162.0/examples/jsm/",
		"lil-gui": "https://threejsfundamentals.org/3rdparty/dat.gui.module.js",
        "@tweenjs/tween.js": "https://cdn.jsdelivr.net/npm/@tweenjs/tween.js@23.1.1/dist/tween.esm.js",
        "canvas-confetti": "https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/+esm"
      }
    }
  </script>

模块module代码

<script type="module">
	import * as THREE from 'three';
	import * as TWEEN from '@tweenjs/tween.js';
	import confetti from 'canvas-confetti';
	import { GUI } from 'lil-gui';
	import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

    function drawWaveParticle(){
      let div = document.getElementById('webgl');
      let canvasWebgl = document.createElement('canvas');
      canvasWebgl.width = parseInt(window.innerWidth);
      canvasWebgl.height = parseInt(window.innerHeight);
	  canvasWebgl.style.position = 'absolute';
	  canvasWebgl.style.zIndex = -1;
      div.appendChild(canvasWebgl);

      let gl = canvasWebgl.getContext('webgl');
      let vertexShaderSource = document.getElementById('vertexShader').innerText;
      let fragShaderSource = document.getElementById('fragmentShader').innerText;
      let program = initShader(gl, vertexShaderSource, fragShaderSource);
      let aposLocation = gl.getAttribLocation(program, 'position');
      let scale = gl.getAttribLocation(program, 'scale');
      let modelViewMatrixLoc = gl.getUniformLocation(program, 'modelViewMatrix');
      let projectionMatrixLoc = gl.getUniformLocation(program, 'projectionMatrix');

      let SEPARATION = 100,AMOUNTX = 50,AMOUNTY = 50;
      let numParticles = AMOUNTX * AMOUNTY;
      let positions = new Float32Array(numParticles * 3);
      let scales = new Float32Array(numParticles);

      let i = 0, j = 0;
      for (let ix = 0; ix < AMOUNTX; ix++) {
        for (let iy = 0; iy < AMOUNTY; iy++) {
          positions[i] = ix * SEPARATION - ((AMOUNTX * SEPARATION) / 2); // x
          positions[i + 1] = 0; // y
          positions[i + 2] = iy * SEPARATION - ((AMOUNTY * SEPARATION) / 2); // z
          scales[j] = 1;
          i += 3;
          j++;
        }
      }

      let colorBuffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
      gl.bufferData(gl.ARRAY_BUFFER, scales, gl.STATIC_DRAW);
      gl.vertexAttribPointer(scale, 1, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(scale);

      let buffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
      gl.vertexAttribPointer(aposLocation, 3, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(aposLocation);
      gl.enable(gl.DEPTH_TEST);

      let width = window.innerWidth; 
      let height = window.innerHeight; 
      let camera = new THREE.PerspectiveCamera(60, width / height, 1, 10000);
      camera.position.set(200, 300, 200); 
      camera.position.set(944, 206, -262);
      camera.lookAt(new THREE.Vector3(0, 0, 0)); 
      camera.updateProjectionMatrix()
      camera.updateMatrixWorld(true)

      let mat4 = new THREE.Matrix4();
      mat4.copy(camera.projectionMatrix)
      let mxArr = new Float32Array(mat4.elements);
      gl.uniformMatrix4fv(projectionMatrixLoc, false, mxArr);
      let mat4y = new THREE.Matrix4();
      mat4y.copy(camera.matrixWorldInverse);
      //console.log(camera.matrixWorldInverse);
      let myArr = new Float32Array(mat4y.elements);
      gl.uniformMatrix4fv(modelViewMatrixLoc, false, myArr);

      let count = 0;
      let mouseX = 0,mouseY = 0;
      let windowHalfX = window.innerWidth / 2;
      let windowHalfY = window.innerHeight / 2;

      function draw() {
        camera.position.x += (mouseX - camera.position.x) * 0.001;
        camera.updateMatrixWorld(true)
        mat4y.copy(camera.matrixWorldInverse);
        let myArr = new Float32Array(mat4y.elements);
        gl.uniformMatrix4fv(modelViewMatrixLoc, false, myArr);
        let i = 0,j = 0;
        for (let ix = 0; ix < AMOUNTX; ix++) {
          for (let iy = 0; iy < AMOUNTY; iy++) {
            positions[i + 1] = (Math.sin((ix + count) * 0.3) * 50) +
              (Math.sin((iy + count) * 0.5) * 50);
            scales[j] = (Math.sin((ix + count) * 0.3) + 1.3) * 8 +
              (Math.sin((iy + count) * 0.5) + 1.3) * 8;
            i += 3;
            j++;
          }
        }
        count += 0.1;
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, scales, gl.STATIC_DRAW);
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        requestAnimationFrame(draw);
        gl.drawArrays(gl.POINTS, 0, 2500);
      }

      draw();

      function initShader(gl, vertexShaderSource, fragmentShaderSource) {
        let vertexShader = gl.createShader(gl.VERTEX_SHADER);
        let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(vertexShader, vertexShaderSource);
        gl.shaderSource(fragmentShader, fragmentShaderSource);
        gl.compileShader(vertexShader);
        gl.compileShader(fragmentShader);
        let program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);
        gl.useProgram(program);
        return program;
      }

      document.addEventListener('mousemove', onDocumentMouseMove, false);
      document.addEventListener('touchstart', onDocumentTouchStart, false);
      document.addEventListener('touchmove', onDocumentTouchMove, false);

      function onDocumentMouseMove(event) {
        mouseX = event.clientX - windowHalfX;
        mouseY = event.clientY - windowHalfY;
      }

      function onDocumentTouchStart(event) {
        if (event.touches.length === 1) {
          event.preventDefault();
          mouseX = event.touches[0].pageX - windowHalfX;
          mouseY = event.touches[0].pageY - windowHalfY;
        }
      }
      
      function onDocumentTouchMove(event) {
        if (event.touches.length === 1) {
          event.preventDefault();
          mouseX = event.touches[0].pageX - windowHalfX;
          mouseY = event.touches[0].pageY - windowHalfY;
        }
      }
    }
	
	class SceneViewer {
	  constructor(options) {
		this.$el = options.el;
		this.time = 0;

		this.bindAll();
		this.init();
	  }

	  bindAll() {
		this.render = this.render.bind(this);
		this.resize = this.resize.bind(this);
	  }

	  init() {
		this.textureLoader = new THREE.TextureLoader();
		this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);

		this.camera.lookAt(new THREE.Vector3(0, 0, 0));
		
		let boxSize = {width: 1,height: 1, thickness: 1};
		
		const fov = 45;
		const angle = fov / 2;  // 夹角
		const rad = THREE.MathUtils.degToRad(angle);  // 转为弧度值
		const distanceZ = boxSize.width / 2 / Math.tan(rad) * 10;
		/**
		 * 调整相机的 X 轴位置,让视野能同时看到盒子顶部和侧面
		 * 调整相机的 Z 轴位置,使盒子完整显示到场景 
		 */
		this.camera.position.set(0, 1, distanceZ);
		

		this.scene = new THREE.Scene();
		
		
		this.renderer = new THREE.WebGLRenderer({antialias: true, alpha: true});
		this.renderer.setPixelRatio(window.devicePixelRatio);
		this.renderer.setSize(window.innerWidth, window.innerHeight);
		
		let geometry = new THREE.BoxGeometry(boxSize.width, boxSize.height, boxSize.tickness);
        let material = new THREE.MeshNormalMaterial();

        this.mesh = new THREE.Mesh(geometry, material);
        this.scene.add(this.mesh);
		
		/* 相机轨道控制器 */
		new OrbitControls(this.camera, this.renderer.domElement);

		const axesHelper = new THREE.AxesHelper(10);  // 辅助坐标轴
		const gridHelper = new THREE.GridHelper(10, 10);  // 辅助网格线
		this.scene.add(axesHelper, gridHelper);
		
		const ambientLight = new THREE.AmbientLight('#fff', 1);  // 环境光
		const directLight = new THREE.DirectionalLight('#fff', 3);  // 平行光
		this.scene.add(ambientLight, directLight);
		

		const cubeMaterial = new THREE.MeshLambertMaterial({
			'color': 'gray',
		  })
		const cubeGeometry = new THREE.CylinderGeometry(0.5, 1, 1)
		const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
		this.scene.add(cube)
		
		this.$el.appendChild(this.renderer.domElement);


		this.createParticles();
		this.createLights();
		this.bindEvents();
		this.resize();
		this.render();
	  }
		
		createLights(){
			  let directionX = 10, directionY = 10, directionZ = 10;
			  const hemisphere = new THREE.HemisphereLight(0xffffff, 0xffffff, 0.6);
			  // move the light right, up, and towards us
			  hemisphere.position.set(10, 10, 10);
			 
			  const ambient = new THREE.AmbientLight(0xffffff, 1);  // 环境光
			  const spot = new THREE.SpotLight(0xfdf4d5);
			  spot.position.set(5, directionY * 4, 0);
			  spot.angle = Math.PI / 2;
			  spot.power = 2000;
			  // eslint-disable-next-line @typescript-eslint/no-unused-vars
			  const spotLightHelper = new THREE.SpotLightHelper(spot, 0x00f);
			 
			  const direct = new THREE.DirectionalLight(0xffffff, 3);  // 平行光
			  direct.position.set(-directionX / 3, directionY * 4, directionZ * 1.5);
			  direct.castShadow = true;
			  direct.shadow.camera.left = -directionX;
			  direct.shadow.camera.right = directionX;
			  direct.shadow.camera.top = directionZ;
			  direct.shadow.camera.bottom = -directionZ;
			 
			  // eslint-disable-next-line @typescript-eslint/no-unused-vars
			  const directLightHelper = new THREE.DirectionalLightHelper(direct, 1, 0xf00);
			 
			  this.scene.add(hemisphere)
			  this.scene.add(ambient)
			  this.scene.add(spot)
			  this.scene.add(direct)
			  

		}

	  createParticles() {
		//const plane = new THREE.PlaneBufferGeometry(500, 250, 250, 125);
		const plane = new THREE.PlaneGeometry(500, 250, 250, 125);

		const textureLoader = new THREE.TextureLoader();
		textureLoader.crossOrigin = '';

		const material = new THREE.ShaderMaterial({
		  uniforms: {
			time: { value: 1.0 },
			texture: { value: textureLoader.load("https://s3-us-west-2.amazonaws.com/s.cdpn.io/1081752/spark1.png") },
			resolution: { value: new THREE.Vector2() } 
		  },
		  vertexShader: document.getElementById('vertex-shader').textContent,
		  fragmentShader: document.getElementById('fragment-shader').textContent,
		  blending: THREE.AdditiveBlending,
		  depthTest: false,
		  transparent: true 
		});

		//console.log(material.uniforms.texture);

		//const material = new THREE.PointsMaterial( { size: 1 } );
		this.particles = new THREE.Points(plane, material);
		this.particles.rotation.x = this.degToRad(-90);

		this.scene.add(this.particles);
	  }


	  bindEvents() {
		// window.addEventListener('mousemove', this.mousemove);
		window.addEventListener('resize', this.resize);
	  }


	  resize() {
		const w = window.innerWidth;
		const h = window.innerHeight;
		this.renderer.setSize(w, h);
		this.camera.aspect = w / h;
		this.camera.updateProjectionMatrix();
	  }

	  moveParticles() {
		this.particles.material.uniforms.time.value = this.time;
		this.particles.material.needsUpdate = true;
	  }

	  // Animations

	  render() {
		requestAnimationFrame(this.render);
		this.time += .01;
		this.mesh.rotation.x += 0.01;
        this.mesh.rotation.y += 0.02;
		this.moveParticles();
		this.renderer.render(this.scene, this.camera);
	  }
	  
	  // Utils
	  degToRad(angle) {
		return angle * Math.PI / 180;
	  }
	  
	}

	initViewer = ()=>{
        drawWaveParticle();
		//let container = document.getElementById(domId);
		let container = document.querySelector('#webgl');
		let element = {el: container};
		new SceneViewer(element);
	}
		
  </script>

挂载到DOM渲染

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="theme-color" content="#000000" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="renderer" content="webkit">
  <meta name="force-rendering" content="webkit">
  <meta name="google-site-verification" content="FTeR0c8arOPKh8c5DYh_9uu98_zJbaWw53J-Sch9MTg">
  <meta data-rh="true" name="keywords" content="three.js实现粒子动画">
  <meta data-rh="true" name="description" content="three.js实现粒子动画">
  <meta data-rh="true" property="og:title" content="three.js实现粒子动画">
  <link rel="icon" href="./favicon.ico">
  <title>three.js实现粒子动画</title>
  
  <style>
    body {
		padding: 0;
		margin: 0;
		font: normal 14px/1.42857 Tahoma;
		background: radial-gradient(#a1b2c3, #123456);
    }
 
    .container {
		position: relative;
	}
	
	.mask{
	    width: 100vw;
		height: 100vh;
		position: absolute;
		left: 0;
	    background: radial-gradient(#123456, #c1d1e1);
		z-index: -1;
	}
	
	#webgl{
		position: absolute;
		left: 0;
		z-index: 1;
	}
	
 
  </style>
</head>
<body onload="initViewer()">

  <div class="container">
    <!-- 遮罩 -->
    <div class="mask"></div>
    <div id="webgl"></div>
  </div>

  <script>
       let initViewer = null
  </script>
  
</body>
</html>

粒子场景效果

e42ae32527264230b0e4e7c154632d5b.png

5ed99cf765834902a903a142448d17ad.png

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/515023.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT实现NTP功能

一.NTP基础 1.NTP定义 NTP&#xff08;Network Time Protocol&#xff0c;网络时间协议&#xff09;是由RFC 1305定义的时间同步协议&#xff0c;用于分布式设备&#xff08;比如电脑、手机、智能手表等&#xff09;进行时间同步&#xff0c;避免人工校时的繁琐和由此引入的误…

【漏洞复现】极简云 download.php 接口处存在任意文件读取漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

什么是线程安全、怎么保证线程安全

目录 什么是线程安全 多线程编程中的三个核心概念 JMM内存模型 JMM内存模型怎么实现原子性、可见性 怎么保证线程安全 什么是线程安全 当多个线程访问一个对象时&#xff0c;如果不用考虑这些线程在运行时环境下的调度和交替执行&#xff0c;也不需要进行额外的同步&#x…

Rust---复合数据类型之结构体

目录 结构体的使用输出结果 结构体简化创建结构体更新语法元组结构体单元结构体&#xff08;unit struct&#xff09;结构体中的引用使用#[derive(Debug)]再次介绍 代码综合展示 与元组不同的是&#xff0c;结构体可以为内部的每个字段起一个富有含义的名称&#xff0c;因此无需…

基于SpringBoot+Vue的汽车租赁管理系统的设计和实现【附源码】

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要交流和学习请联系

vivado适用于 UltraScale 和 UltraScale+ 器件的 eFUSE 寄存器访问和编程

FUSE_DNA &#xff1a; 唯一的器件 DNA 每个 UltraScale 器件都有唯一的器件 ID &#xff0c; 称为器件 DNA &#xff0c; 且赛灵思已将此 DNA 编程到器件中。用户无法对 FUSE_DNA 进行编程。 UltraScale 器件具有 96 位 DNA 。您可在 Vivado Design Suite Tcl 控制台中…

Matlab梁单元有限元编程:铁木辛柯梁VS欧拉梁

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

openplc Linux 地址映射io,读写驱动数据等使用记录

1. 上一篇记录 openplc使用C语言文件读写驱动实现基本流程。 openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录_openplc c 编程-CSDN博客 2. 下面通过映射地址的方式控制io和读写驱动数据。 在runtime 环境的 hardware 硬件配置中 选择 python on Linux(PSM)&#…

成为先进企业应该从用飞书开始,还是应该从裁员开始?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 大家都觉得飞书不行了&#xff0c;我们反而不这么看。 众所周知&#xff0c;飞书最近裁员的消息在业界引起了巨大的反响&#xff0c;大…

基于SSM+Jsp+Mysql的快递管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

62、服务攻防——框架安全CVE复现SpringStrutsLaravelThinkphp

文章目录 常见语言开发框架&#xff08;主流&#xff09;&#xff1a; PHP&#xff1a;ThinkPHP、Laravel、YIIJAVA&#xff1a;Spring、SpringbootPython&#xff1a;FlaskJavaScript&#xff1a;Vue.js、Node.js 框架判断()&#xff1a; 通过插件Wappalyzer&#xff08;可能…

练手项目层初阶1—《详解静态版本——通讯录管理系统》

文章目录 &#x1f6a9;前言&#x1f50a; 项目需求&#x1f4da; 项目知识点包含&#x1f9e9;项目框架&#x1f4dd;框架拆解分析✨Struct_book.h 头文件解析✨Struct_book.c文件解析✨test_book.c文件解析 &#x1f4fa;演示效果&#x1f680;完整代码 &#x1f6a9;前言 俗…

联想 Y9000P 连接网线速度慢 的 问题解决

参考帖子&#xff1a;求助&#xff0c;拯救者Y9000P 2022 i73060版本 有线网非常慢 无线网正常【笔记本吧】_百度贴吧 问题原因&#xff1a; 网卡驱动版本不对。不能用Win11版&#xff0c;要用Win10版。 问题解决&#xff1a; 1、卸载原驱动 2、下载Win10 驱动 并安装 下载…

C语言——常用库函数的使用及模拟实现

C语言编译系统为使用者提供了很多的预定义库函数。用户在编写程序时&#xff0c;可以直接调用这些库函数。这里选择了一些常用的库函数&#xff0c;简单介绍各个函数的使用方法&#xff1a; 字符串函数 字符串函数函数分为长度不受限制的字符串函数&#xff0c;和长度受限制的…

手搓链表(java)(不完整)

手搓链表&#xff08;java&#xff09;&#xff08;不完整&#xff09; 文章目录 手搓链表&#xff08;java&#xff09;&#xff08;不完整&#xff09;前言一、代码1.MyLinkedList类&#xff1a;2.测试类&#xff1a; 总结 前言 提示&#xff1a;以下是本篇文章正文内容&…

Git 术语及中英文对照

完毕&#xff01;&#xff01;感谢您的收看 ----------★★历史博文集合★★---------- 我的零基础Python教程&#xff0c;Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字…

保姆级教程——VLAN综合实验(不同VLAN通过动态路由访问外网)

前言&#xff1a; 部署了VLAN的传统交换机不能实现不同VLAN间的二层报文转发&#xff0c;因此必须引入路由技术来实现不同VLAN间的通信。VLAN路由可以通过二层交换机配合路由器来实现&#xff0c;也可以通过三层交换机来实现 VLAN间通信的限制 每个VLAN都是一个独立的…

vue 使用自定义标签URL Protocol 调用本地exe 并传参

创建注册表文件reg&#xff0c;并运行 里面的路径需要替换成实际exe的绝对路径 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\App] "URL:App Protocol Handler" "URL Protocol""" [HKEY_CLASSES_ROOT\App\DefaultIcon] &qu…

启动mysql

删除C:\Program Files (x86)\MySQL\MySQL Server 5.7这个路径下的data文件夹&#xff0c;这个很难删除&#xff0c;因为一开机&#xff0c;mysql的某些服务就启动了&#xff0c;每次重新启动mysql之前&#xff0c;都要删除这个文件夹 因为这个文件夹在后端执行一些我们看不到的…

pycharm打包python文件为exe文件(图文教程)

1.安装pyinstaller库 pip3 install pyinstaller 2.使用pyinstaller 打包文件 首先确保Terminal命令行中&#xff0c;你的路径和你的项目是同一个路径 我的项目就是放在golden_dev中的。 3.命令行内输入打包代码 pyinstaller -F -w gold_miner.py gold_miner.py 是我的项目…