分享一个鬼~

news2024/11/18 12:37:27

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

先看效果:
在这里插入图片描述
上源码:

import GUI from "https://cdn.jsdelivr.net/npm/lil-gui@0.18.2/+esm"

const canvasEl = document.querySelector("#ghost");

const mouseThreshold = .1;
const devicePixelRatio = Math.min(window.devicePixelRatio, 2);

const mouse = {
    x: .3 * window.innerWidth,
    y: .3 * window.innerHeight,
    tX: .25 * window.innerWidth,
    tY: .45 * window.innerHeight,
    moving: false,
    controlsPadding: 0
}

const params = {
    size: .1,
    tail: {
        dotsNumber: 25,
        spring: 1.4,
        friction: .3,
        maxGravity: 50,
        gravity: 25,
    },
    smile: 1,
    mainColor: [.98, .96, .96],
    borderColor: [.2, .5, .7],
    isFlatColor: false,
};


const textureEl = document.createElement("canvas");
const textureCtx = textureEl.getContext("2d");
const pointerTrail = new Array(params.tail.dotsNumber);
let dotSize = (i) => params.size * window.innerHeight * (1. - .2 * Math.pow(3. * i / params.tail.dotsNumber - 1., 2.));
for (let i = 0; i < params.tail.dotsNumber; i++) {
    pointerTrail[i] = {
        x: mouse.x,
        y: mouse.y,
        vx: 0,
        vy: 0,
        opacity: .04 + .3 * Math.pow(1 - i / params.tail.dotsNumber, 4),
        bordered: .6 * Math.pow(1 - i / pointerTrail.length, 1),
        r: dotSize(i)
    }
}


let uniforms;
const gl = initShader();
createControls();

window.addEventListener("resize", resizeCanvas);
resizeCanvas();
render();

window.addEventListener("mousemove", e => {
    updateMousePosition(e.clientX, e.clientY);
});
window.addEventListener("touchmove", e => {
    updateMousePosition(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
});
window.addEventListener("click", e => {
    updateMousePosition(e.clientX, e.clientY);
});

let movingTimer = setTimeout(() => mouse.moving = false, 300);

function updateMousePosition(eX, eY) {
    mouse.moving = true;
    if (mouse.controlsPadding < 0) {
        mouse.moving = false;
    }
    clearTimeout(movingTimer);
    movingTimer = setTimeout(() => {
        mouse.moving = false;
    }, 300);

    mouse.tX = eX;

    const size = params.size * window.innerHeight;
    eY -= .6 * size;
    mouse.tY = eY > size ? eY : size;
    mouse.tY -= mouse.controlsPadding;
}


function initShader() {
    const vsSource = document.getElementById("vertShader").innerHTML;
    const fsSource = document.getElementById("fragShader").innerHTML;

    const gl = canvasEl.getContext("webgl") || canvasEl.getContext("experimental-webgl");

    if (!gl) {
        alert("WebGL is not supported by your browser.");
    }

    function createShader(gl, sourceCode, type) {
        const shader = gl.createShader(type);
        gl.shaderSource(shader, sourceCode);
        gl.compileShader(shader);

        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            console.error("An error occurred compiling the shaders: " + gl.getShaderInfoLog(shader));
            gl.deleteShader(shader);
            return null;
        }

        return shader;
    }

    const vertexShader = createShader(gl, vsSource, gl.VERTEX_SHADER);
    const fragmentShader = createShader(gl, fsSource, gl.FRAGMENT_SHADER);

    function createShaderProgram(gl, vertexShader, fragmentShader) {
        const program = gl.createProgram();
        gl.attachShader(program, vertexShader);
        gl.attachShader(program, fragmentShader);
        gl.linkProgram(program);

        if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
            console.error("Unable to initialize the shader program: " + gl.getProgramInfoLog(program));
            return null;
        }

        return program;
    }

    const shaderProgram = createShaderProgram(gl, vertexShader, fragmentShader);
    uniforms = getUniforms(shaderProgram);

    function getUniforms(program) {
        let uniforms = [];
        let uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
        for (let i = 0; i < uniformCount; i++) {
            let uniformName = gl.getActiveUniform(program, i).name;
            uniforms[uniformName] = gl.getUniformLocation(program, uniformName);
        }
        return uniforms;
    }

    const vertices = new Float32Array([-1., -1., 1., -1., -1., 1., 1., 1.]);

    const vertexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

    gl.useProgram(shaderProgram);

    const positionLocation = gl.getAttribLocation(shaderProgram, "a_position");
    gl.enableVertexAttribArray(positionLocation);

    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

    const canvasTexture = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, canvasTexture);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureEl);
    gl.uniform1i(uniforms.u_texture, 0);

    gl.uniform1f(uniforms.u_size, params.size);
    gl.uniform3f(uniforms.u_main_color, params.mainColor[0], params.mainColor[1], params.mainColor[2]);
    gl.uniform3f(uniforms.u_border_color, params.borderColor[0], params.borderColor[1], params.borderColor[2]);

    return gl;
}

function updateTexture() {
    textureCtx.fillStyle = 'black';
    textureCtx.fillRect(0, 0, textureEl.width, textureEl.height);

    pointerTrail.forEach((p, pIdx) => {
        if (pIdx === 0) {
            p.x = mouse.x;
            p.y = mouse.y;
        } else {
            p.vx += (pointerTrail[pIdx - 1].x - p.x) * params.tail.spring;
            p.vx *= params.tail.friction;

            p.vy += (pointerTrail[pIdx - 1].y - p.y) * params.tail.spring;
            p.vy *= params.tail.friction;
            p.vy += params.tail.gravity;

            p.x += p.vx;
            p.y += p.vy;
        }

        const grd = textureCtx.createRadialGradient(p.x, p.y, p.r * p.bordered, p.x, p.y, p.r);
        grd.addColorStop(0, 'rgba(255, 255, 255, ' + p.opacity + ')');
        grd.addColorStop(1, 'rgba(255, 255, 255, 0)');

        textureCtx.beginPath();
        textureCtx.fillStyle = grd;
        textureCtx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
        textureCtx.fill();
    });
}


function render() {
    const currentTime = performance.now();
    gl.uniform1f(uniforms.u_time, currentTime);

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

    if (mouse.moving) {
        params.smile -= .05;
        params.smile = Math.max(params.smile, -.1);
        params.tail.gravity -= 10 * params.size;
        params.tail.gravity = Math.max(params.tail.gravity, 0);
    } else {
        params.smile += .01;
        params.smile = Math.min(params.smile, 1);
        if (params.tail.gravity > 30 * params.size) {
            params.tail.gravity = (30 + 9 * (1 + Math.sin(.002 * currentTime))) * params.size;
        } else {
            params.tail.gravity += params.size;
        }
    }

    mouse.x += (mouse.tX - mouse.x) * mouseThreshold;
    mouse.y += (mouse.tY - mouse.y) * mouseThreshold;

    gl.uniform1f(uniforms.u_smile, params.smile);
    gl.uniform2f(uniforms.u_pointer, mouse.x / window.innerWidth, 1. - mouse.y / window.innerHeight);
    gl.uniform2f(uniforms.u_target_pointer, mouse.tX / window.innerWidth, 1. - mouse.tY / window.innerHeight);

    updateTexture();

    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureEl);
    requestAnimationFrame(render);
}

function resizeCanvas() {
    canvasEl.width = window.innerWidth * devicePixelRatio;
    canvasEl.height = window.innerHeight * devicePixelRatio;
    textureEl.width = window.innerWidth;
    textureEl.height = window.innerHeight;
    gl.viewport(0, 0, canvasEl.width, canvasEl.height);
    gl.uniform1f(uniforms.u_ratio, canvasEl.width / canvasEl.height);
    for (let i = 0; i < params.tail.dotsNumber; i++) {
        pointerTrail[i].r = dotSize(i);
    }
}

function createControls() {
    const gui = new GUI();
    gui.add(params, "size", .02, .3, .01)
        .onChange(v => {
            for (let i = 0; i < params.tail.dotsNumber; i++) {
                pointerTrail[i].r = dotSize(i);
            }
            gl.uniform1f(uniforms.u_size, params.size);
        });
    gui.addColor(params, "mainColor").onChange(v => {
        gl.uniform3f(uniforms.u_main_color, v[0], v[1], v[2]);
    });
    const borderColorControl = gui.addColor(params, "borderColor").onChange(v => {
        gl.uniform3f(uniforms.u_border_color, v[0], v[1], v[2]);
    });
    gui.add(params, "isFlatColor")
        .onFinishChange(v => {
            borderColorControl.disable(v);
            gl.uniform1f(uniforms.u_flat_color, v ? 1 : 0);
        });

    const controlsEl = document.querySelector(".lil-gui");
    controlsEl.addEventListener("mouseenter", () => {
        mouse.controlsPadding = -controlsEl.getBoundingClientRect().height;
    });
    controlsEl.addEventListener("mouseleave", () => {
        mouse.controlsPadding = 0;
    });
}
<div class="page">
    WebGL Ghost Cursor
</div>

<canvas id="ghost"></canvas>


<script type="x-shader/x-fragment" id="vertShader">
    precision mediump float;

    varying vec2 vUv;
    attribute vec2 a_position;

    void main() {
        vUv = .5 * (a_position + 1.);
        gl_Position = vec4(a_position, 0.0, 1.0);
    }
</script>


<script type="x-shader/x-fragment" id="fragShader">
    precision mediump float;

    varying vec2 vUv;
    uniform float u_time;
    uniform float u_ratio;
    uniform float u_size;
    uniform vec2 u_pointer;
    uniform float u_smile;
    uniform vec2 u_target_pointer;
    uniform vec3 u_main_color;
    uniform vec3 u_border_color;
    uniform float u_flat_color;
    uniform sampler2D u_texture;

    #define TWO_PI 6.28318530718
    #define PI 3.14159265358979323846

    vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
    vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
    vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); }
    float snoise(vec2 v) {
        const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);
        vec2 i = floor(v + dot(v, C.yy));
        vec2 x0 = v - i + dot(i, C.xx);
        vec2 i1;
        i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
        vec4 x12 = x0.xyxy + C.xxzz;
        x12.xy -= i1;
        i = mod289(i);
        vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));
        vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
        m = m*m;
        m = m*m;
        vec3 x = 2.0 * fract(p * C.www) - 1.0;
        vec3 h = abs(x) - 0.5;
        vec3 ox = floor(x + 0.5);
        vec3 a0 = x - ox;
        m *= 1.79284291400159 - 0.85373472095314 * (a0*a0 + h*h);
        vec3 g;
        g.x = a0.x * x0.x + h.x * x0.y;
        g.yz = a0.yz * x12.xz + h.yz * x12.yw;
        return 130.0 * dot(m, g);
    }
    vec2 rotate(vec2 v, float angle) {
        float r_sin = sin(angle);
        float r_cos = cos(angle);
        return vec2(v.x * r_cos - v.y * r_sin, v.x * r_sin + v.y * r_cos);
    }

    float eyes(vec2 uv) {
        uv.y -= .5;
        uv.x *= 1.;
        uv.y *= .8;
        uv.x = abs(uv.x);
        uv.y += u_smile * .3 * pow(uv.x, 1.3);
        uv.x -= (.6 + .2 * u_smile);

        float d = clamp(length(uv), 0., 1.);
        return 1. - pow(d, .08);
    }

    float mouth(vec2 uv) {
        uv.y += 1.5;

        uv.x *= (.5 + .5 * abs(1. - u_smile));
        uv.y *= (3. - 2. * abs(1. - u_smile));
        uv.y -= u_smile * 4. * pow(uv.x, 2.);

        float d = clamp(length(uv), 0., 1.);
        return 1. - pow(d, .07);
    }

    float face(vec2 uv, float rotation) {
        uv = rotate(uv, rotation);
        uv /= (.27 * u_size);

        float eyes_shape = 10. * eyes(uv);
        float mouth_shape = 20. * mouth(uv);

        float col = 0.;
        col = mix(col, 1., eyes_shape);
        col = mix(col, 1., mouth_shape);

        return col;
    }

    void main() {

        vec2 point = u_pointer;
        point.x *= u_ratio;

        vec2 uv = vUv;
        uv.x *= u_ratio;
        uv -= point;

        float texture = texture2D(u_texture, vec2(vUv.x, 1. - vUv.y)).r;
        float shape = texture;

        float noise = snoise(uv * vec2(.7 / u_size, .6 / u_size) + vec2(0., .0015 * u_time));
        noise += 1.2;
        noise *= 2.1;
        noise += smoothstep(-.8, -.2, (uv.y) / u_size);

        float face = face(uv, 5. * (u_target_pointer.x - u_pointer.x));
        shape -= face;

        shape *= noise;

        vec3 border = (1. - u_border_color);
        border.g += .2 * sin(.005 * u_time);
        border *= .5;

        vec3 color = u_main_color;
        color -= (1. - u_flat_color) * border * smoothstep(.0, .01, shape);

        shape = u_flat_color * smoothstep(.8, 1., shape) + (1. - u_flat_color) * shape;
        color *= shape;

        gl_FragColor = vec4(color, shape);
    }
</script>

body, html {
    margin: 0;
    padding: 0;
    overflow: hidden;
    background-color: #2C3E50;
}

canvas#ghost {
    position: fixed;
    top: 0;
    left: 0;
    display: block;
    width: 100%;
    z-index: 10000;
    pointer-events: none;
}

.page {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    text-align: center;
    font-size: 4vw;
    text-shadow: 0 0 5px #000000;
}

.lil-gui {
    --width: 300px;
    max-width: 90%;
    --widget-height: 20px;
    font-size: 15px;
    --input-font-size: 15px;
    --padding: 10px;
    --spacing: 10px;
    --slider-knob-width: 5px;
    --background-color: rgba(5, 0, 15, .8);
    --widget-color: rgba(255, 255, 255, .3);
    --focus-color: rgba(255, 255, 255, .4);
    --hover-color: rgba(255, 255, 255, .5);
    --font-family: monospace;
    z-index: 1;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

为社会做贡献的EasyDarwin 4.0.1发布了,支持视频点播、文件直播、摄像机直播、直播录像、直播回放、录像MP4合成下载

经过几个月的不懈努力和测试&#xff0c;最新的EasyDarwin 4.0版本总算是发布出来了&#xff0c;功能还是老几样&#xff1a;文件点播、视频直播&#xff08;支持各种视频源&#xff09;、直播录像与回放、录像合成MP4下载&#xff0c;稍稍看一下细节&#xff1a; 文件上传与点…

【UCAS自然语言处理作业二】训练FFN, RNN, Attention机制的语言模型,并计算测试集上的PPL

文章目录 前言前馈神经网络数据组织Dataset网络结构训练超参设置 RNN数据组织&Dataset网络结构训练超参设置 注意力网络数据组织&Dataset网络结构Attention部分完整模型 训练部分超参设置 结果与分析训练集Loss测试集PPL 前言 本次实验主要针对前馈神经网络&#xff0…

SRM供应商、采购管理系统

前言&#xff1a; 随着互联网和数字技术的不断发展&#xff0c;企业采购管理逐渐走向数字化和智能化。数字化采购平台作为企业采购管理的新模式&#xff0c;能够提高采购效率、降低采购成本、优化供应商合作效率&#xff0c;已成为企业实现效益提升的关键手段。 软件开发资料…

Oracle登录认证方式详解

文章目录 一、简介二、OS认证三、口令认证四、remote_login_passwordfile 详解 一、简介 在数据库管理中&#xff0c;登录认证是确保数据库安全性的重要环节。Oracle数据库提供 了两种认证方式&#xff0c;一种是“操作系统认证”&#xff0c;一种是“口令文件认证&#xff0c…

基于Vue+SpringBoot的家庭个人记帐理财系统

登陆 注册 (用户账号&#xff0c;密码&#xff0c;再次确 认密码&#xff0c;手机号) 用户注销功能&#xff0c;用户能注销就行 管理员不需要注销功能 用户个人信息修改删除 (头像&#xff0c;性 别&#xff0c;账号&#xff0c;密码&#xff0c;手机号&#xff0c;地址) 新闻页…

基于Scapy修改ClientHello的SNI(三)

需求:修改HTTPS的ClientHello中的SNI字段 目标:修改成功,wireshark显示正常 语言:Python 三方库:Scapy 下面是一个标准的ClientHello报文,是从一个完整的HTTPS流中保存出来的,原始报文中的SNI是www.baidu.com 在上一篇文章中 记录基于scapy构造ClientHello报文的尝试…

【教学类-06-08】20231125(55格版)X-Y之间“减法-题”(以10-20之间为例)(必须A>B,题目少)

图片展示 需求&#xff1a; 20以内减法&#xff0c;不需要再练习其中10以内部分&#xff0c;改为10-20以内的减法&#xff0c;X-Y大于10&#xff0c;小于20的所有减法题。 代码展示&#xff1a; “-”减法 X-Y 之间的所有减法-题&#xff08;如10-20之间的所有减法&#xff0…

C3 多媒体查询

文章目录 前言CSS3 多媒体查询CSS2 多媒体类型CSS3 多媒体查询浏览器支持多媒体查询语法CSS3 多媒体类型多媒体查询简单实例 媒体类型媒体功能更多实例后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;CSS &#x1f431;‍&#x1f453;博…

nginx反向代理解决跨域实践

需求实现 本地请求百度的一个搜索接口&#xff0c;用nginx代理解决跨域思路&#xff1a;前端和后端都用nginx代理到同一个地址8080&#xff0c;这样访问接口就不存在跨域限制 本地页面 查询一个百度搜索接口&#xff0c;运行在http://localhost:8035 index.js const path …

5.7 Windows驱动开发:取进程模块函数地址

在笔者上一篇文章《内核取应用层模块基地址》中简单为大家介绍了如何通过遍历PLIST_ENTRY32链表的方式获取到32位应用程序中特定模块的基地址&#xff0c;由于是入门系列所以并没有封装实现太过于通用的获取函数&#xff0c;本章将继续延申这个话题&#xff0c;并依次实现通用版…

国产航顺HK32F030M: 简易篮球计分器(便携计分器)

【自制】《基于航顺HKF030MF4P6手持比赛计分牌》&#xff08;便携计分器&#xff09; 1. 简介 便携篮球计分器是一种小型化设计的设备&#xff0c;主要用于记录和显示篮球比赛的得分和计时。以下是由Type-C充电电路TP5400/ASM1117电路、HK32F030MF4单片机最小系统、数码管显示…

小程序如何禁止指定用户访问?如何设置指定用户才能访问?

​有些商家为了价格保密或者实行严格的会员制等原因&#xff0c;希望小程序能够限制某些人的访问或者设置指定人员才能访问。这种功能在小程序中&#xff0c;怎么支持这些功能呢&#xff1f;下面具体介绍。 一、禁止指定用户访问 禁止指定用户访问&#xff0c;可以通过小程序…

论文笔记:详解NEUPSL DSI

《Using Domain Knowledge to Guide Dialog Structure Induction via Neural Probabilistic 》 名词解释 Dialog Structure Induction&#xff08;DSI&#xff09;是推断给定目标导向对话的潜在对话结构&#xff08;即一组对话状态及其时间转换&#xff09;的任务。它是现代对…

基于springboot+Web实现社区医院管理服务系统项目【项目源码+论文说明】计算机毕业设计

基于springbootWeb实现社区医院管理服务系统演示 摘要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括社区医院管理服务系统的网络应用&#xff0c;在外国线上管理系统已经是很普遍的方式&#xff0c;不过国内的管理系统可…

面试官:知道JVM中一次完整的 GC 流程吗

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

转行要趁早!盘点网络安全的岗位汇总

前段时间&#xff0c;知名机构麦可思研究院发布了《2023年中国本科生就业报告》&#xff0c;其中详细列出近五年的本科绿牌专业&#xff0c;信息安全位列第一。 对于网络安全的发展与就业前景&#xff0c;知了姐说过很多&#xff0c;作为当下应届生收入较高的专业之一&#xf…

栈和队列的实现(详解+图解!文末附完整代码)

栈 栈的基本概念 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&#xff1a;栈的…

【Mybatis】基础增删改查

一.创建SpringBoot项目 创建新项目需要添加的依赖 当然如果是以前的项目也可以直接在pom.xml文件中添加依赖: MySQL Driver依赖 <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</…

如何通过 Al 的能力提升编程的效率?

通过人工智能&#xff08;AI&#xff09;的技术&#xff0c;可以提升编程效率和能力。以下是一些建议和方法&#xff1a; 代码自动生成&#xff1a;使用AI技术&#xff0c;可以根据程序员的需求和输入&#xff0c;自动生成代码。这可以提高编程效率&#xff0c;减少编写代码所需…

Fedora 36 ARM 镜像源更换与软件安装

1、什么是Fedora Fedora Linux是较具知名度的Linux发行套件之一&#xff0c;由Fedora专案社群开发、红帽公司赞助&#xff0c;目标是建立一套新颖、多功能并且自由的作业系统。 Fedora是商业化的Red Hat Enterprise Linux发行版的上游原始码。 2、Fedora软件安装 64 位 .deb&a…