马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
自定义人潮涌动主要增加了以下功能:
支持自定义人物角色图片的行数列数
支持对人物大小,密度,移动速度进行调节
支持隐藏右侧推荐大标签,扩展左侧宽度
调节home_top高度
自定义人潮涌动背景图
定义多张人物总图,每次访问时随机选取
people.js魔改
实现了可以输入任意长,宽,图片大小的功能。
也懒得对比哪里修改了,大家直接把下面覆盖自己的people.js得了(主要是忘了修改了那里了)
- //Hexo\themes\anzhiyu\source\js\anzhiyu\people.js
- "use strict";
- function _toConsumableArray(e) {
- return _arrayWithoutHoles(e) || _iterableToArray(e) || _unsupportedIterableToArray(e) || _nonIterableSpread();
- }
- function _nonIterableSpread() {
- throw new TypeError(
- "Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
- );
- }
- function _unsupportedIterableToArray(e, r) {
- if (e) {
- if ("string" == typeof e) return _arrayLikeToArray(e, r);
- var t = Object.prototype.toString.call(e).slice(8, -1);
- return (
- "Object" === t && e.constructor && (t = e.constructor.name),
- "Map" === t || "Set" === t
- ? Array.from(e)
- : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)
- ? _arrayLikeToArray(e, r)
- : void 0
- );
- }
- }
- function _iterableToArray(e) {
- if (("undefined" != typeof Symbol && null != e[Symbol.iterator]) || null != e["@@iterator"]) return Array.from(e);
- }
- function _arrayWithoutHoles(e) {
- if (Array.isArray(e)) return _arrayLikeToArray(e);
- }
- function _arrayLikeToArray(e, r) {
- (null == r || r > e.length) && (r = e.length);
- for (var t = 0, a = new Array(r); t < r; t++) a[t] = e[t];
- return a;
- }
- function _classCallCheck(e, r) {
- if (!(e instanceof r)) throw new TypeError("Cannot call a class as a function");
- }
- function _defineProperties(e, r) {
- for (var t = 0; t < r.length; t++) {
- var a = r[t];
- (a.enumerable = a.enumerable || !1),
- (a.configurable = !0),
- "value" in a && (a.writable = !0),
- Object.defineProperty(e, a.key, a);
- }
- }
- function _createClass(e, r, t) {
- return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), e;
- }
- var peopleConfig = {
- src: Array.isArray(GLOBAL_CONFIG.peoplecanvas.img)
- ? GLOBAL_CONFIG.peoplecanvas.img[Math.floor(Math.random() * GLOBAL_CONFIG.peoplecanvas.img.length)]
- : GLOBAL_CONFIG.peoplecanvas.img,
- background_image: GLOBAL_CONFIG.peoplecanvas.background_image || '',
- rows: GLOBAL_CONFIG.peoplecanvas.rows || 15,
- cols: GLOBAL_CONFIG.peoplecanvas.cols || 7,
- scale: GLOBAL_CONFIG.peoplecanvas.scale || 0.3,
- density: GLOBAL_CONFIG.peoplecanvas.density || 1.0,
- speed: GLOBAL_CONFIG.peoplecanvas.speed || 1.0,
- offsetY: GLOBAL_CONFIG.peoplecanvas.offsetY || 0,
- },
- randomRange = function (e, r) {
- return e + Math.random() * (r - e);
- },
- randomIndex = function (e) {
- return 0 | randomRange(0, e.length);
- },
- removeFromArray = function (e, r) {
- return e.splice(r, 1)[0];
- },
- removeItemFromArray = function (e, r) {
- return removeFromArray(e, e.indexOf(r));
- },
- removeRandomFromArray = function (e) {
- return removeFromArray(e, randomIndex(e));
- },
- getRandomFromArray = function (e) {
- return e[0 | randomIndex(e)];
- },
- resetPeep = function (e) {
- var r,
- t,
- a = e.stage,
- n = e.peep,
- o = 0.5 < Math.random() ? 1 : -1,
- i = 100 - 250 * gsap.parseEase("power2.in")(Math.random()),
- s = a.height - n.height + i + peopleConfig.offsetY;
- return (
- 1 == o ? ((r = -n.width), (t = a.width), (n.scaleX = 1)) : ((r = a.width + n.width), (t = 0), (n.scaleX = -1)),
- (n.x = r),
- (n.y = s),
- {
- startX: r,
- startY: (n.anchorY = s),
- endX: t,
- }
- );
- },
- normalWalk = function (e) {
- var r = e.peep,
- t = e.props,
- a = (t.startX, t.startY),
- n = t.endX,
- o = gsap.timeline(),
- speedMultiplier = peopleConfig.speed;
- return (
- o.timeScale(randomRange(0.5 * speedMultiplier, 1.5 * speedMultiplier)),
- o.to(
- r,
- {
- duration: 10 / speedMultiplier,
- x: n,
- ease: "none",
- },
- 0
- ),
- o.to(
- r,
- {
- duration: 0.25 / speedMultiplier,
- repeat: 40,
- yoyo: !0,
- y: a - 10,
- },
- 0
- ),
- o
- );
- },
- walks = [normalWalk],
- Peep = (function () {
- function a(e) {
- var r = e.image,
- t = e.rect;
- _classCallCheck(this, a),
- (this.image = r),
- this.setRect(t),
- (this.x = 0),
- (this.y = 0),
- (this.anchorY = 0),
- (this.scaleX = 1),
- (this.walk = null);
- }
- return (
- _createClass(a, [
- {
- key: "setRect",
- value: function (e) {
- (this.rect = e),
- (this.width = e[2]),
- (this.height = e[3]),
- (this.drawArgs = [this.image].concat(_toConsumableArray(e), [0, 0, this.width, this.height]));
- },
- },
- {
- key: "render",
- value: function (e, scale) {
- var s = scale || 1;
- e.save(),
- e.translate(this.x, this.y),
- e.scale(this.scaleX * s, s),
- e.drawImage.apply(e, _toConsumableArray(this.drawArgs)),
- e.restore();
- },
- },
- ]),
- a
- );
- })(),
- img = document.createElement("img");
- (img.onload = init), (img.src = peopleConfig.src);
- let peoplecanvasEl = document.getElementById("peoplecanvas");
- let ctx = peoplecanvasEl ? peoplecanvasEl.getContext("2d") : undefined,
- stage = {
- width: 0,
- height: 0,
- },
- allPeeps = [],
- availablePeeps = [],
- crowd = [];
- // 添加全局变量来跟踪初始化状态
- let isInitializing = false;
- let currentImageSrc = '';
- // 修改PJAX事件监听器
- document.addEventListener("pjax:success", e => {
- const newPeoplecanvasEl = document.getElementById("peoplecanvas");
- if (newPeoplecanvasEl && !isInitializing) {
- isInitializing = true;
- // 完全清理之前的状态
- cleanupPeopleCanvas();
- peoplecanvasEl = newPeoplecanvasEl;
- ctx = peoplecanvasEl ? peoplecanvasEl.getContext("2d") : undefined;
- // 重新选择随机图片(如果配置了多张图片)
- let newImageSrc;
- if (Array.isArray(GLOBAL_CONFIG.peoplecanvas.img)) {
- newImageSrc = GLOBAL_CONFIG.peoplecanvas.img[Math.floor(Math.random() * GLOBAL_CONFIG.peoplecanvas.img.length)];
- } else {
- newImageSrc = GLOBAL_CONFIG.peoplecanvas.img;
- }
- // 只有当图片真的改变时才重新加载
- if (newImageSrc !== currentImageSrc) {
- currentImageSrc = newImageSrc;
- peopleConfig.src = newImageSrc;
- // 创建新的图片对象
- const newImg = document.createElement("img");
- newImg.onload = function () {
- // 替换全局图片引用
- img.src = newImg.src;
- img.onload = null; // 清除旧的onload
- setTimeout(() => {
- if (!peoplecanvasEl || !isInitializing) return;
- initializePeopleCanvas();
- isInitializing = false;
- console.log('人潮汹涌模块重新初始化完成');
- }, 100);
- };
- newImg.onerror = function () {
- console.error('人潮汹涌图片加载失败:', newImageSrc);
- isInitializing = false;
- };
- newImg.src = newImageSrc;
- } else {
- // 图片相同,直接重新初始化
- setTimeout(() => {
- if (!peoplecanvasEl || !isInitializing) return;
- initializePeopleCanvas();
- isInitializing = false;
- console.log('人潮汹涌模块重新初始化完成(相同图片)');
- }, 100);
- }
- }
- });
- // 新增清理函数
- function cleanupPeopleCanvas() {
- // 停止所有动画
- crowd.forEach(function (peep) {
- if (peep.walk) {
- peep.walk.kill();
- peep.walk = null;
- }
- });
- // 移除事件监听器
- window.removeEventListener("resize", resize);
- gsap.ticker.remove(render);
- // 清空所有数组
- crowd.length = 0;
- availablePeeps.length = 0;
- allPeeps.length = 0;
- // 清空画布
- if (peoplecanvasEl && ctx) {
- ctx.clearRect(0, 0, peoplecanvasEl.width, peoplecanvasEl.height);
- }
- }
- // 新增初始化函数
- function initializePeopleCanvas() {
- if (!peoplecanvasEl) return;
- // 设置背景图片
- if (peopleConfig.background_image) {
- document.documentElement.style.setProperty('--peoplecanvas-bg-image', `url(${peopleConfig.background_image})`);
- }
- // 重新创建人物精灵图
- createPeeps();
- // 重新初始化
- resize();
- gsap.ticker.add(render);
- window.addEventListener("resize", resize);
- }
- // 修改原有的init函数
- function init() {
- if (!peoplecanvasEl || isInitializing) return;
- currentImageSrc = peopleConfig.src;
- initializePeopleCanvas();
- }
- function createPeeps() {
- for (
- var e = peopleConfig.rows,
- r = peopleConfig.cols,
- t = e * r,
- a = img.naturalWidth / e,
- n = img.naturalHeight / r,
- o = 0;
- o < t;
- o++
- )
- allPeeps.push(
- new Peep({
- image: img,
- rect: [(o % e) * a, ((o / e) | 0) * n, a, n],
- })
- );
- }
- function resize() {
- if (peoplecanvasEl && peoplecanvasEl.clientWidth != 0) {
- (stage.width = peoplecanvasEl.clientWidth),
- (stage.height = peoplecanvasEl.clientHeight),
- (peoplecanvasEl.width = stage.width * devicePixelRatio),
- (peoplecanvasEl.height = stage.height * devicePixelRatio),
- crowd.forEach(function (e) {
- e.walk.kill();
- }),
- (crowd.length = 0),
- (availablePeeps.length = 0),
- availablePeeps.push.apply(availablePeeps, allPeeps),
- initCrowd();
- }
- }
- function initCrowd() {
- var targetCount = Math.floor(allPeeps.length * peopleConfig.density);
- for (var i = 0; i < targetCount && availablePeeps.length; i++) {
- addPeepToCrowd().walk.progress(Math.random());
- }
- }
- function addPeepToCrowd() {
- var e = removeRandomFromArray(availablePeeps),
- r = getRandomFromArray(walks)({
- peep: e,
- props: resetPeep({
- peep: e,
- stage: stage,
- }),
- }).eventCallback("onComplete", function () {
- removePeepFromCrowd(e);
- if (crowd.length < Math.floor(allPeeps.length * peopleConfig.density)) {
- addPeepToCrowd();
- }
- });
- return (
- (e.walk = r),
- crowd.push(e),
- crowd.sort(function (e, r) {
- return e.anchorY - r.anchorY;
- }),
- e
- );
- }
- function removePeepFromCrowd(e) {
- removeItemFromArray(crowd, e), availablePeeps.push(e);
- }
- function render() {
- if (!peoplecanvasEl) return;
- (peoplecanvasEl.width = peoplecanvasEl.width),
- ctx.save(),
- ctx.scale(devicePixelRatio, devicePixelRatio),
- crowd.forEach(function (e) {
- e.render(ctx, peopleConfig.scale);
- }),
- ctx.restore();
- }
复制代码
然后在主题配置文件中peoplecanvas项添加以下配置,这里ai生成的时候行和列搞反了,实际上rows是总图的列数,cols是总图的行数,反正能跑就懒得改了。 有些图片因为拆分后单个人物大小的问题,需要调整缩放比例和垂直偏移,如果加载出来看不到有人在跑,可能就是太高了或低了,可以先想缩放调小点,看看是高还是低,先调了垂直偏移。 具体参数搭配要看使用的总图的单个人物大小,大家多试一试找到合适的参数。
- peoplecanvas:
- enable: true
- img: https://testingcf.jsdelivr.net/gh/kingkare/owo/img/ahugecrowd.webp
- background_image: https://testingcf.jsdelivr.net/gh/kingkare/owo/img/2025-04-01.png #背景图
- #下面是新增的
- rows: 13 # 精灵图列数,默认15
- cols: 4 # 精灵图行数,默认7
- scale: 0.5 # 人物大小缩放比例 (0.1-1.0),默认1.0
- density: 0.6 # 人物密度 (0.1-2.0),默认1.0
- speed: 0.8 # 人物移动速度 (0.1-3.0),默认1.0
- offsetY: 148 # 垂直位置偏移 (-200 到 200,负值向上,正值向下),默认0
复制代码 大家根据自己的来调
自定义背景图
找到这个文件修改样式 Hexo\themes\anzhiyu\source\css\_layout\home_top.styl
- #peoplecanvas
- width: 100%;
- height: 100%;
- background-image: var(--peoplecanvas-bg-image, none);
- background-size: cover;
- background-position: center;
- background-repeat: no-repeat;
- border-radius: 12px;
复制代码 找到这个文件修改样式:Hexo\themes\anzhiyu\source\js\anzhiyu\people.js 注意看里面注释的新增位置
- var peopleConfig = {
- src: GLOBAL_CONFIG.peoplecanvas.img,
- //在此新增
- background_image: GLOBAL_CONFIG.peoplecanvas.background_image || '',
- //...
- function init() {
- if (!peoplecanvasEl) return;
-
- // 在此新增
- if (peopleConfig.background_image) {
- document.documentElement.style.setProperty('--peoplecanvas-bg-image', `url(${peopleConfig.background_image})`);
- }
- createPeeps(), resize(), gsap.ticker.add(render), window.addEventListener("resize", resize);
- }
- setTimeout(() => {
- if (!peoplecanvasEl) return;
-
- //在此新增
- if (peopleConfig.background_image) {
- document.documentElement.style.setProperty('--peoplecanvas-bg-image', `url(${peopleConfig.background_image})`);
- }
- resize(), gsap.ticker.add(render), window.addEventListener("resize", resize);
复制代码 修改_config.anzhiyu.yml,设定背景图片
- # 首页随便逛逛people模式 而非技能点模式,关闭后为技能点模式需要配置creativity.yml
- peoplecanvas:
- enable: true
- img: #总图
- background_image: #背景图 只要添加一行这个设置背景图地址既可
- ...
复制代码 然后执行Hexo三步命令即可!
|
|