live2d(Web SDK 4.x)Web看板娘进阶

本教程详细讲解如何使用Live2D WebSDK4.x自定义看板娘项目,包括移除背景图案、切换模型按钮,设置透明背景,调整模型比例,修改鼠标交互,控制模型属性,以及模块化项目。通过了解并配置模型参数,实现更丰富的交互体验。同时,教程提供了一步步的代码修改指南,帮助开发者实现个性化看板娘。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接上篇文章

Live2D(WebSDK 4.X)网页看板娘设置(一)

欢迎大家阅读本篇教程

该篇教程为进阶版的看板娘设置教程,阅读完后可以极大程度的自定义你的看板娘项目。

教程内容:

  • 去掉canvas中的背景图案和切换模型按钮,并将背景设置为透明
  • 新增配置类,对需要自定义的属性进行修改,同时在模型中新建mapper
  • 设置模型放大倍率
  • 修改鼠标交互方式
  • 适配模型的控制属性,自定义模型加载的位置
  • 模块化该项目

1.修改canvas绘制的内容

打开【Sample\TypeScript\Demo\src\lappview.ts】文件,定位至以下位置,将我们不需要的功能注释掉。

定位到initializeSprite()函数

  /**
     * 执行图像初始化
     */
    public initializeSprite(): void
    {
        let width: number = canvas.width;
        let height: number = canvas.height;

        let textureManager = LAppDelegate.getInstance().getTextureManager();
        const resourcesPath = LAppDefine.ResourcesPath;
        let imageName: string = "";
        //注释掉所有图片加载方法
    /** 
        // 背景画像初期化
        imageName = LAppDefine.BackImageName;
        // 创建回调函数,因为它是异步的
        let initBackGroundTexture = (textureInfo: TextureInfo): void =>
        {
            let x: number = width * 0.5;
            let y: number = height * 0.5;
            let fwidth = textureInfo.width * 2.0;
            let fheight = height * 0.95;
            this._back = new LAppSprite(x, y, fwidth, fheight, textureInfo.id);
        };
         //将背景图片的注释掉
        textureManager.createTextureFromPngFile(resourcesPath + imageName, false, initBackGroundTexture);
        // 歯車画像初期化
        imageName = LAppDefine.GearImageName;
        let initGearTexture = (textureInfo: TextureInfo): void =>
        {
            let x = width - textureInfo.width * 0.5;
            let y = height - textureInfo.height * 0.5;
            let fwidth = textureInfo.width;
            let fheight = textureInfo.height;
            this._gear = new LAppSprite(x, y, fwidth, fheight, textureInfo.id);
        };
        textureManager.createTextureFromPngFile(resourcesPath + imageName, false, initGearTexture);
*/
        -------
        省略其他代码
        -------
    }

onTouchesEnded函数

public onTouchesEnded(pointX: number, pointY: number): void
    {
        // 触摸结束
        let live2DManager: LAppLive2DManager = LAppLive2DManager.getInstance();
        live2DManager.onDrag(0.0, 0.0);
        {
            let x: number = this._deviceToScreen.transformX(this._touchManager.getX()); // 論理座標変換した座標を取得。
            let y: number = this._deviceToScreen.transformY(this._touchManager.getY()); // 論理座標変化した座標を取得。
            if(LAppDefine.DebugTouchLogEnable)
            {
                LAppPal.printLog("[APP]touchesEnded x: {0} y: {1}", x, y);
            }
            live2DManager.onTap(x, y);
          /*
            // 点击了齿轮,调用live2D管理器切换人物模型
            if(this._gear.isHit(pointX, pointY))
            {
                live2DManager.nextScene();
            }
          */
        }
    }

完成后我们找到Sample\TypeScript\Demo\src\lappdelegate.tsrun函数

 /**
     * 実行処理。
     */
    public run(): void
    {
        // メインループ
        let loop = () =>
        {
            // インスタンスの有無の確認
            if(s_instance == null)
            { return;}
            // 時間更新
            LAppPal.updateTime();
            
            // 画面の初期化
            //这里时初始化背景的,四个参数分别是 r g b a
            //原本的参数是0,0,0,1
            //我们把它改成0,0,0,0
            gl.clearColor(0.0, 0.0, 0.0, 0.0);
            ----------------------
                    省略.....
            ----------------------
        };
        loop();
    }

修改完背景后,我们修改模型在页面中的布局。这里我是参考的别人的布局方式:是帐篷啊

完成以上步骤后我们可以运行一下看看效果

2.了解自己准备使用的模型

为了使项目兼容更多的模型,我们需要先了解不同模型直接的差异

  • 首先是版本问题,该项目只支持模型入口文件为 *.moc3.json的模型
  • 其次是模型的控制参数,这个是我们最需要关注的,因为这关系到你能不能控制人物的交互行为

控制参数我们可以使用官方的Cubism Viewer打开文件,之后点击moc文件,来查看。这里我们主要关注和控制身体、面部、眼球相关的参数(官方标准值为:ParamAngleX、Y、Z,ParamBodyAngleX和ParamEyeBallX、Y)

有了以上的了解,我们可以进行下一步,接下来我们要做的就是将当前模型的非标准值与标准值进行映射

首先,我们打开进入到你准备的模型的根目录(moc3.json文件同级),在这里新建mapper.json文件,内容如下:

{
    "parameter": [
      //  标准值:模型中所对应的值,如果你的模型用的就是标准值,也需要这样操作
        {"ParamAngleX": "PARAM_ANGLE_X"},
        {"ParamAngleY": "PARAM_ANGLE_Y"},
        {"ParamAngleZ": "PARAM_ANGLE_Z"},
        {"ParamEyeBallX": "PARAM_EYE_BALL_X"},
        {"ParamBodyAngleX": "PARAM_BODY_ANGLE_X"},
        {"ParamEyeBallY": "PARAM_EYE_BALL_Y"}
    ],
      //这个暂时不用,后续更新的话有可能会使用到
    "url": [],
      //如果你想调整模型的位置,修改这个值,分别对应X轴和Y轴
    "center":[2,1]
}

该文件是根据我自己在源码中修改的加载逻辑而额外加的,方便来回切换模型时使用,你根据你自己的情况来决定要不要进行这一步。

第一步和第二步准备工作做好后,我们开始修改源码中与模型有关的内容

3. 修改资源路径等文件

  1. 新建MocMapper.ts文件
/**
 * 将Moc文件中的id值和资源文件名称及对应的url映射到程序中
 */
import {resourcesConfig } from './lappdefine'

export class MocMapper {
    private parameterIdMAp: Map<string, string> = new Map();
    private resourcesPathToUrlMap = new Map();
    private jsonResources = null;
    public static mapper: MocMapper = null;

/**
 * 根据url地址获取资源路径和url的映射对象
 * @param url 保存映射关系的json的url地址
 */
    public static  getInstance() {
        if (this.mapper == null) {
            this.mapper = new MocMapper();
        }
        return this.mapper;
    }
    /**
     * 将当前模型的id值保存到键值对中
     * @param defaultParameter 官方默认的id值
     * @param currentModParameter  当前模型中与官方默认值效果相同的id值
     * @note 一般只需要设置 ParamEyeBall[X,Y]  ParamAngle[X,Y,Z]
     */
    public setParameter(defaultParameter: string, currentModParameter: string) {
        this.parameterIdMAp.set(defaultParameter,currentModParameter)
    }
    /**
     * 
     * @param defaultParameter 根据默认id值获取当前模型对应的id值
     * @returns 
     */
    public getParemeter(defaultParameter: string): string {
        return this.parameterIdMAp.get(defaultParameter)
    }
/**
 * 
 * @param resourcesPath moc3.json中的资源路径
 * @param url 服务器中该路径对应文件的访问地址
 */
    public setPathToUrl(resourcesPath:string, url:string) {
        this.resourcesPathToUrlMap.set(resourcesPath, url);
    }
/**
 *  根据资源路径获取url
 * @param resourcesPath 资源路径
 * @returns 
 */
    public getUrl(resourcesPath: string): string {
        return this.resourcesPathToUrlMap.get(resourcesPath)
    }
    public getJsonConfig() {
        return this.jsonResources;
    }
/**
 * 从指定url读取模型目录中的mapper.json【自定义的变量映射关系文件】文件
 * @param url mapper文件的url
 */
    public async setMapperJson(url: string) {
        this.jsonResources = await fetch(url).then(async function (response) {
            const json = await response.json();
            return json;
        })

        let arrayOfparameters = this.getJsonConfig().parameter;
        let arrayOfUrl = this.getJsonConfig().url;
        //将id值存入map中
        for (let i = 0; i < arrayOfparameters.length; i++) {
          let item = arrayOfparameters[i]
          for (let key in item) {
            this.setParameter(key,item[key])
          }
        }
        //将资源路径和url映射关系存入map中
        for (let i = 0; i < arrayOfUrl.length;i++) {
          let item = arrayOfUrl[i]
          for (let key in item) {
            this.setParameter(key,item[key])
          }
        }
        //设置模型的中心位置
        let centerPointScal = this.getJsonConfig().center;
        resourcesConfig.setXscal(centerPointScal[0]);
        resourcesConfig.setYscal(centerPointScal[1]);
    }
}
  1. 打开【Samples\TypeScript\Demo\src\lappdefine.ts】文件

修改源文件内容如下:

import { LogLevel } from '@framework/live2dcubismframework';


// Canvas width and height pixel values, or dynamic screen size ('auto').
export const CanvasSize: { width: number; height: number } | 'auto' = 'auto';

// 画面,默认放大倍率
export const ViewScale = 2;

export const ViewMaxScale = 4.0;
export const ViewMinScale = 0.4;
export const ViewLogicalLeft = -1.0;
export const ViewLogicalRight = 1.0;
export const ViewLogicalBottom = -1.0;
export const ViewLogicalTop = 1.0;
export const ViewLogicalMaxLeft = -2.0;
export const ViewLogicalMaxRight = 2.0;
export const ViewLogicalMaxBottom = -2.0;
export const ViewLogicalMaxTop = 2.0;

//新建ResouConfig对象
class ResourceConfig {
    public resourcesPath: string;
    public modelNames: string[];
    public modelSize: number;
    public canvasId: string = 'live2d';
    public x_scal: number = 2;
    public y_scal:number = 1
    constructor() {
        this.resourcesPath = '../../Resources/';
        this.modelNames = ['Haru', 'Hiyori', 'Mark', 'Natori', 'Rice'];
        this.modelSize = this.modelNames.length;
    }

    public setResourcesPath(path:string) {
         this.resourcesPath = path;
    }
    public setCanvasId(canvasId:string) {
        this.canvasId = canvasId;
   }

    public setModelNames(models:string[]) {
        this.modelNames = models;
        this.setModelSize();
    }

    public setModelSize() {
        this.modelSize = this.modelNames.length;
    }

    public getResourcesPath() {
        return this.resourcesPath;
    }

    public getModelNames() {
        return this.modelNames;
    }

    public getModelSize() { return this.modelSize;}
    public getCanvasId() {
       return  this.canvasId
    }
    
    public setXscal(scal:number) {  this.x_scal = scal }
    public setYscal(scal:number) {  this.y_scal = scal }
    public getXscal() { return this.x_scal }
    public getYscal() { return this.y_scal}

}
//将该对象导出,方便在其他文件中使用
export const resourcesConfig = new ResourceConfig();

// 相対パス
//export const ResourcesPath = '../../Resources/';

// モデルの後ろにある背景の画像ファイル
export const BackImageName = '';

// 歯車
export const GearImageName = '';

// 終了ボタン
export const PowerImageName = '';

// モデル定義---------------------------------------------
// モデルを配置したディレクトリ名の配列
// ディレクトリ名とmodel3.jsonの名前を一致させておくこと
//export const ModelDir: string[] = ['Haru', 'Hiyori', 'Mark', 'Natori', 'Rice'];
//export const ModelDirSize: number = ModelDir.length;

//下方省略.................
  1. 打开**【Samples\TypeScript\Demo\src\lappdelegate.ts】,导入lappdefine.ts中的resourceConfig对象,定位到initialize()**修改内容如下:
import * as LAppDefine from './lappdefine';
/**
省略其他方法
*/

public initialize(): boolean {
    // 修改成我们自己配置的canvas
    canvas = <HTMLCanvasElement>document.getElementById(LAppDefine.resourcesConfig.getCanvasId());
  
    // glコンテキストを初期化
    // @ts-ignore
    gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
    if (!gl) {
      alert('Cannot initialize WebGL. This browser does not support.');
      gl = null;
      document.body.innerHTML =
        'This browser does not support the <code>&lt;canvas&gt;</code> element.';
      // gl初期化失敗
      return false;
    }

    // キャンバスを DOM に追加
    // document.body.appendChild(canvas);

    if (!frameBuffer) {
      frameBuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
    }

    // 透過設定
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
 // 注释掉原有的点击和触摸事件
/*
    const supportTouch: boolean = 'ontouchend' in document;

     if (supportTouch) {
    // タッチ関連コールバック関数登録
    document.ontouchstart = onTouchBegan;
     document.ontouchmove = onTouchMoved;
     document.ontouchend = onTouchEnded;
    //document.ontouchend = onTouchEnded;
    //canvas.ontouchcancel = onTouchCancel;
     } else {
       */
    // マウス関連コールバック関数登録
    //只能在canvas的事件上调用on*Ended()方法,不然会影响人物的点击效果
    //onmousemove方法只能在onmousedown和onmouseup之间调用,不然没有效果
    //document.onmousemove = onMouseMoved;
    canvas.onmouseup = onClickEnded;
    document.addEventListener("mousemove", function (e) {
      if (!LAppDelegate.getInstance()._view) {
        LAppPal.printMessage("view notfound");
        return;
      }
      //之前我是使用documents对象来获取canvas,其实已经有全局变量了,这里也可以直接用
      let rect = canvas.getBoundingClientRect();
      let posX: number = e.clientX - rect.left;
      let posY: number = e.clientY - rect.top;
      LAppDelegate.getInstance()._view.onTouchesMoved(posX, posY);
    }, false);
    //在这里加上鼠标离开浏览器后,一切归位
    document.addEventListener("mouseout", function (e) {
      //鼠标离开document后,将其位置置为(0,0)  
      let live2DManager: LAppLive2DManager = LAppLive2DManager.getInstance();
      live2DManager.onDrag(0.0, 0.0);
    }, false);
    // AppViewの初期化
    this._view.initialize();
    // Cubism SDKの初期化
    this.initializeCubism();
    return true;
  }

  1. 打开【Samples\TypeScript\Demo\src\lapplive2dmanager.ts】文件,添加或修改以下方法
//开头导入相关文件
import { MocMapper}from './MocMapper'
import * as LAppDefine from './lappdefine';
-----------------------------下边是对象内容----------------------------------------------

public nextScene(): void {
    const no: number = (this._sceneIndex + 1) % LAppDefine.resourcesConfig.getModelSize();
    this.changeScene(no);
  }
  /**
   * 随机加载模型 
   */
   public randomScene(): void {
      //设置随机的模型选项
      let randomNum= Math.random()*(LAppDefine.resourcesConfig.getModelSize()+1)//取值范围[0,size+1)包含小数
      //转为整数后再次取余防止出现数组越界问题
      let indexOfModel = Math.floor(randomNum)%LAppDefine.resourcesConfig.getModelSize()
      this.changeScene(indexOfModel);
  }


  public  async changeScene(index: number): Promise<void> {
    this._sceneIndex = index;
    if (LAppDefine.DebugLogEnable) {
      LAppPal.printMessage(`[APP]model index: ${this._sceneIndex}`);
    }
    // ModelDir[]に保持したディレクトリ名から
    // model3.jsonのパスを決定する。
    // ディレクトリ名とmodel3.jsonの名前を一致させておくこと。
    const model: string = LAppDefine.resourcesConfig.getModelNames()[index];
    const modelPath: string = LAppDefine.resourcesConfig.getResourcesPath() + model + '/';
    let modelJsonName: string = LAppDefine.resourcesConfig.getModelNames()[index];
    modelJsonName += '.model3.json';

    let mapperJsonOfModel = modelPath + 'mapper.json';
    let mapper = MocMapper.getInstance();
    await mapper.setMapperJson(mapperJsonOfModel)
    this.releaseAllModel();
    this._models.pushBack(new LAppModel());
    this._models.at(0).loadAssets(modelPath, modelJsonName);
  }
  1. 打开【Sample\TypeScript\Demo\src\lappview.ts】文件,initializeSprite()函数
//修改
const resourcesPath = LAppDefine.resourcesConfig.getResourcesPath();
  1. 打开【Framework\src\math\cubismmodelmatrix.ts】,导入resourcesConfig,然后找到构造方法
//在开头加上 
import { resourcesConfig } from '../../../Samples/TypeScript/Demo/src/lappdefine';

---------------------------------下面是构造方法内容----------------------------------------------
constructor(w?: number, h?: number) {
    super();

    this._width = w !== undefined ? w : 0.0;
    this._height = h !== undefined ? h : 0.0;
    //这个是官方随便给的一个数,调整后会影响模型的放大倍率
    this.setHeight(2.0);
    //设置模型中心位置
    this.setCenterPosition(w*resourcesConfig.getXscal()/2, h*resourcesConfig.getYscal()/2);
  }

  1. 修改【Sample\TypeScript\Demo\src\main.ts】
import { LAppDelegate } from './lappdelegate';
import { resourcesConfig} from './lappdefine';
import { LAppLive2DManager} from './lapplive2dmanager'

function  start() {

   // create the application instance
   if (LAppDelegate.getInstance().initialize() == false) {
    return;
  }
  LAppDelegate.getInstance().run();
}
function stop() {
  LAppDelegate.releaseInstance();
}
/**
 * 根据index来控制切换模型,只能填整数
 * @param index 模型的次序
 * 从1开始。 小于0:随机加载
 * >0加载数组下标为index-1的模型
 * ==0 加载下一个模型
 */
function changeScene(index: number) {
  let manager = LAppLive2DManager.getInstance();
  if (index < 0) {
    manager.randomScene();
  } else if (index > 0 ) {
    manager.changeScene(index-1)
  } else if (index ==0) {
    manager.nextScene();
  }
}
module.exports = { start , stop , changeScene , resourcesConfig}
  1. 打开【Samples\TypeScript\Demo\src\lappmodel.ts】,导入MocMapper,定位到构造方法
 public constructor() {
    super();

    this._modelSetting = null;
    this._modelHomeDir = null;
    this._userTimeSeconds = 0.0;

    this._eyeBlinkIds = new csmVector<CubismIdHandle>();
    this._lipSyncIds = new csmVector<CubismIdHandle>();

    this._motions = new csmMap<string, ACubismMotion>();
    this._expressions = new csmMap<string, ACubismMotion>();

    this._hitArea = new csmVector<csmRect>();
    this._userArea = new csmVector<csmRect>();
    let mapper = MocMapper.mapper;
    if (mapper != null) {
      this._idParamAngleX = CubismFramework.getIdManager().getId(
        mapper.getParemeter("ParamAngleX")
      );
      this._idParamAngleY = CubismFramework.getIdManager().getId(
        mapper.getParemeter("ParamAngleY")
      );
      this._idParamAngleZ = CubismFramework.getIdManager().getId(
        mapper.getParemeter("ParamAngleZ")
      );
      this._idParamEyeBallX = CubismFramework.getIdManager().getId(
        mapper.getParemeter("ParamEyeBallX")
      );
      this._idParamEyeBallY = CubismFramework.getIdManager().getId(
        mapper.getParemeter("ParamEyeBallY")
      );
      this._idParamBodyAngleX = CubismFramework.getIdManager().getId(
        mapper.getParemeter("ParamBodyAngleX")
      );
    } else {
      this._idParamAngleX = CubismFramework.getIdManager().getId(
        CubismDefaultParameterId.ParamAngleX
      );
      this._idParamAngleY = CubismFramework.getIdManager().getId(
        CubismDefaultParameterId.ParamAngleY
      );
      this._idParamAngleZ = CubismFramework.getIdManager().getId(
        CubismDefaultParameterId.ParamAngleZ
      );
      this._idParamEyeBallX = CubismFramework.getIdManager().getId(
        CubismDefaultParameterId.ParamEyeBallX
      );
      this._idParamEyeBallY = CubismFramework.getIdManager().getId(
        CubismDefaultParameterId.ParamEyeBallY
      );
      this._idParamBodyAngleX = CubismFramework.getIdManager().getId(
        CubismDefaultParameterId.ParamBodyAngleX
      );
    }
    this._state = LoadStep.LoadAssets;
    this._expressionCount = 0;
    this._textureCount = 0;
    this._motionCount = 0;
    this._allMotionCount = 0;
    this._wavFileHandler = new LAppWavFileHandler();
  }
  1. 打开【Samples\TypeScript\Demo\webpack.config.js】,修改打包输出方式
module.exports = {
  mode: 'production',
  target: ['web', 'es5'],
  entry: './src/main.ts',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/dist/',
    library: 'live2dLoader',
    libraryTarget:'umd'
  },
  resolve: {
    extensions: ['.ts', '.js'],
    //省略。。。。。。。。。。。
  1. 打开【index.html】,添加js代码
 <script type="text/javascript">
    var loader  = live2dLoader 
    //这两个是必须设置的
    loader.resourcesConfig.setResourcesPath("./live2d/models/")
    loader.resourcesConfig.setModelNames(['a','b'])
    loader.start();
    console.log(loader)
  </script>

以上修改完成后,打包运行即可。

结尾

修改完成后的项目我上传到GitHub:https://github.com/cqc233/live2dDemo

如果对于某个细节不是很明白可以参考我的旧版文章:

Live2D(Cubism3.x)网页看板娘设置(二)

Live2D(Cubism3.x)网页看板娘设置(三)

live2d-widget是一个可以在网页中添加可爱的看板的网页插件。live2d-widget特性在网页中添加Live2D看板。兼容PJAX,支持无刷新加载。 警告:本项目使用了大量 ES6 语法,不支持 IE 11 等老旧浏览器。你也可以在允许的范围内进行二次开发,这里有一些示例 demo.html ,展现基础效果 login.html ,仿NPM的登陆界面live2d-widget安装使用网页看板简短安装 只需要把下面3行代码放到页面中,即可实现网页看板效果。(格式自己进行添加下即可) script src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js" link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css" script src="https://cdn.jsdelivr.net/gh/stevenjoezhang/live2d-widget/autoload.js" live2d-widget详细安装说明: 依赖Dependencies 本插件需要Font Awesome(v4 或 v5)图标支持,请确保相关样式表已在页面中加载。以Font Awesome v4 为例,请在 中加入: link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css" 否则图标将无法正常显示。(如果网页中已经加载了任何版本的Font Awesome,就不要重复加载了)使用Usage 将这一行代码加入或,即可展现出效果: script src="https://cdn.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/autoload.js" 如果网站启用了PJAX,由于看板不必每页刷新,因此要注意将相关脚本放到PJAX刷新区域之外。 换句话说,如果你是小白,或者只需要最基础的功能,就只用把这一行代码,连同前面加载Font Awesome的一行代码,一起放到html的中即可。 对于用各种模版引擎(例如 Nunjucks,Jinja 或者 PHP)生成的页面,也要自行修改,方法类似,只是可能略为麻烦。以Hexo为例,需要在主题相关的ejs或njk模版中正确配置路径,才可以加载。 但是!我们强烈推荐自己进行配置,否则很多功能是不完整的,并且可能产生问题! 如果你有兴趣自己折腾的话,请看下面的详细说明。Using CDN 要自定义有关内容,可以把这个仓库Fork一份,然后进行修改。这时,使用方法对应地变为 script src="https://cdn.jsdelivr.net/gh/username/live2d-widget@latest/autoload.js" 将此处的username 替换为你的 GitHub 用户名。为了使 CDN 的内容正常刷新,需要创建新的git tag 并推送至GitHub仓库中,否则此处的 @latest 仍然指向更新前的文件。此外CDN本身存在缓存,因此改动可能需要一定的时间生效。Self-host 你也可以直接把这些文件放到服务器上,而不是通过CDN加载。 如果你能够通过ssh访问你的主机,请把整个仓库克隆到服务器上。执行: cd /path/to/your/webroot # Clone this repository git clone https://github.com/stevenjoezhang/live2d-widget.git 如果你的主机无法用ssh连接(例如一般的虚拟主机),请选择 Download ZIP,然后通过ftp等方式上传到主机上,再解压到网站的目录下。 如果你是通过 Hexo 等工具部署的静态博客,请在博客源文件(即 source)目录下,执行前述的 git clone 命令。重新部署博客时,相关文件就会自动上传到对应的路径下。为了避免这些文件被 Hexo 插件错误地修改,可能需要设置 skip_render。 这样,整个项目就可以通过你的服务器 IP 或者域名从公网访问了。不妨试试能否正常地通过浏览器打开autoload.js 和 live2d.min.js 等文件,并确认这些文件的内容是完整和正确的。 一切正常的话,接下来修改一些配置就行了。(需要通过服务器上的文本编辑器修改;你也可以先在本地完成这一步骤,再上传到服务器上
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值