diff --git a/languages/yoone-snow-zh_CN.mo b/languages/yoone-snow-zh_CN.mo index cd1a4a9..acefc57 100644 Binary files a/languages/yoone-snow-zh_CN.mo and b/languages/yoone-snow-zh_CN.mo differ diff --git a/languages/yoone-snow-zh_CN.po b/languages/yoone-snow-zh_CN.po index d2524d9..708351f 100644 --- a/languages/yoone-snow-zh_CN.po +++ b/languages/yoone-snow-zh_CN.po @@ -128,8 +128,8 @@ msgid "Weight controls relative probability Weight is a non negative integer Wei msgstr "权重用于控制随机生成的相对概率 权重为非负整数 权重为 0 表示禁用 某形状概率等于其权重除以所有形状权重之和 例如 dot 1 flake 4 flake 概率约为 dot 的四倍" # Other settings -msgid "Home Display Duration Seconds" -msgstr "首页显示时长 秒" +msgid "Display Duration Seconds" +msgstr "显示时长 秒" msgid "Duration in seconds for snow on home 0 means infinite" msgstr "首页雪花显示时长 单位秒 0 表示无限" @@ -166,3 +166,28 @@ msgstr "水平摆动幅度基值在最小与最大之间随机 应用偏移缩 msgid "Select images or SVG" msgstr "选择图片或 SVG" + +# Route display mode +msgid "Display Routes Mode" +msgstr "显示路由模式" + +msgid "Home" +msgstr "首页" + +msgid "All Pages" +msgstr "所有页面" + +msgid "Match URL Path" +msgstr "匹配 URL 路径" + +msgid "Default Home Only choose All Pages to enable globally choose Match URL Path to enable only for matched routes" +msgstr "默认仅首页显示 选择所有页面开启全站显示 选择匹配 URL 路径仅在匹配的路径显示" + +msgid "Match Routes" +msgstr "匹配规则" + +msgid "One rule per line compare against request path example exact path /about prefix match with trailing star /blog/*" +msgstr "每行一条规则 与请求路径比较 例如精确路径 /about 前缀匹配可使用尾部星号 /blog/*" + +msgid "Example /about\n/blog/*\n/shop" +msgstr "示例 /about\n/blog/*\n/shop" diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..d3a3aa7 --- /dev/null +++ b/readme.txt @@ -0,0 +1,78 @@ +=== Yoone Snow === +Contributors: yoone +Tags: snow, snowfall, christmas, effects, canvas +Requires at least: 5.6 +Tested up to: 6.6 +Requires PHP: 7.4 +Stable tag: 1.1.0 +License: GPLv2 or later +License URI: https://www.gnu.org/licenses/gpl-2.0.html + +== Description == +Yoone Snow 是一个在站点页面顶部绘制雪花效果的插件 使用 canvas 在前端生成不同形状的飘落元素 并提供后台设置页面进行配置 支持默认形状 emoji 字符 媒体图片以及文本作为雪花元素 每个元素都可以单独设置权重用来控制出现概率 插件同时提供尺寸范围 漂移速度范围 摆动幅度范围 最大在屏数量和首页显示时长等参数 便于在性能和效果之间做平衡 + +主要特性 +- 形状类型支持 dot flake yuanbao coin santa hat candy cane christmas sock christmas tree reindeer christmas berry +- 支持添加 emoji 作为雪花元素 支持别名搜索与直接输入 +- 支持添加媒体图片包括普通图片和 SVG 作为雪花元素 +- 支持文本元素作为雪花元素 +- 每类元素支持权重设置 权重为非负整数 权重为 0 时禁用该元素 +- 提供尺寸范围 漂移速度范围 摆动幅度范围 最大在屏数量和首页显示时长等设置 +- 后台形状选择下拉带内嵌预览 每项左侧显示绘制图案 便于直观选择 + +== Installation == +手动安装 +- 将插件文件夹上传到 `wp-content/plugins` 目录 +- 在后台插件页面启用 Yoone Snow 插件 +- 打开后台 `Settings -> Yoone Snow` 进入设置页进行配置 + +== Usage == +- 在设置页的 Shapes 字段卡片区域管理所有雪花元素 支持 Default Emoji Media Text 四种类型 +- Default 类型下可从下拉内嵌列表选择默认形状 左侧有图案预览 点击后会添加到下方卡片列表 +- Emoji 类型可通过别名下拉或直接输入字符加入元素 别名示例 snow tree bell 等 +- Media 类型通过按钮从媒体库选择图片或 SVG 并加入元素列表 +- Text 类型输入文本并加入元素列表 +- 每个元素卡片包含一个权重输入框 权重为非负整数 非法值会在保存时被矫正 + +== Settings == +- Shapes 卡片列表 管理默认形状 emoji 媒体和文本元素 每个元素支持权重输入 +- Display Duration Seconds 主页显示时长 单位秒 0 表示无限 +- Max Snowflakes On Screen 在屏最大数量 0 表示根据视口面积自动控制 上限为 1000 +- Snow Size 最小与最大半径 随机范围 在前端根据此范围生成不同尺寸 +- Drift Speed Random Range 垂直漂移速度的随机范围 控制落下速度基线 +- Swing Amplitude Random Range 水平摆动幅度随机范围 控制左右摆动基线 + +== FAQ == +问 如何控制某个形状出现概率 +答 在对应形状卡片的权重输入框设置权重 权重越大出现概率越高 权重为 0 时禁用该形状 + +问 如何添加自定义图片或 SVG 作为雪花 +答 在 Media 面板点击 Add Images 按钮 从媒体库选择图片或 SVG 将自动添加到卡片列表并可设置权重 + +问 Emoji 如何快速添加 +答 在 Emoji 面板通过下拉选择常用别名或在输入框中直接输入 emoji 字符 支持别名搜索和粘贴识别 + +问 性能如何设置 +答 通过 Max Snowflakes On Screen 限制在屏数量 通过尺寸 漂移和摆动范围控制动画强度 如需更节省资源可调小上限与范围值 + +== Screenshots == +1 设置页形状选择下拉内嵌预览示例 +2 元素卡片列表与权重输入示例 +3 媒体元素与 emoji 元素示例 + +== Changelog == += 1.1.0 = +- 增加形状选择下拉内嵌预览 每项左侧显示图案 +- 将权重输入整合到卡片列表中 支持默认形状 emoji 媒体和文本 +- 增强后台交互 包括 emoji 别名选择与建议列表 媒体多选以及文本快速添加 + += 1.0.0 = +- 初始版本 支持基础雪花效果与默认形状选择 + +== Upgrade Notice == += 1.1.0 = +升级后请在设置页检查各元素权重与在屏最大数量 以确保性能与效果符合预期 + +== Localization == +- 文本域为 `yoone-snow` 插件已加载本地化文本 可在 `languages` 目录提供翻译文件 + diff --git a/yoone-snow.php b/yoone-snow.php index 4ab1d5a..86700f6 100644 --- a/yoone-snow.php +++ b/yoone-snow.php @@ -2,13 +2,44 @@ /* Plugin Name: Yoone Snow Description: 首页 canvas 雪花效果 -Version: 1.7.0 +Version: 1.9.0 Author: Yoone */ if (!defined('ABSPATH')) { exit; } function yoone_snow_is_enabled() { + $mode = get_option('yoone_snow_display_routes_mode', 'home'); + if ($mode === 'all') { + return true; + } + if ($mode === 'match') { + $routes = get_option('yoone_snow_display_routes', array()); + if (is_string($routes)) { + $routes = array_filter(array_map('trim', explode("\n", $routes))); + } + if (!is_array($routes)) { + $routes = array(); + } + $requestUri = isset($_SERVER['REQUEST_URI']) ? (string)$_SERVER['REQUEST_URI'] : ''; + $path = parse_url($requestUri, PHP_URL_PATH); + $path = is_string($path) ? $path : ''; + foreach ($routes as $rule) { + $r = trim((string)$rule); + if ($r === '') { continue; } + if (substr($r, -1) === '*') { + $prefix = substr($r, 0, -1); + if ($prefix === '' || strpos($path, $prefix) === 0) { + return true; + } + } else { + if ($path === $r) { + return true; + } + } + } + return false; + } return function_exists('is_front_page') ? is_front_page() : false; } @@ -64,6 +95,14 @@ function yoone_snow_enqueue_assets() { $script_ver = @filemtime(plugin_dir_path(__FILE__) . 'js/snow-canvas.js'); $deps = array($shape_index_handle); $needs_utils = false; + $mixed_items_option = get_option('yoone_snow_mixed_items', array('dot','flake')); + if (is_string($mixed_items_option)) { + $mixed_items_option = array_filter(array_map('trim', explode(',', $mixed_items_option))); + } + $allowed_shapes = array('dot','flake','yuanbao','coin','santa_hat','candy_cane','christmas_sock','christmas_tree','reindeer','christmas_berry'); + $mixed_items_sanitized = array_values(array_unique(array_intersect(is_array($mixed_items_option) ? $mixed_items_option : array('dot','flake'), $allowed_shapes))); + if (empty($mixed_items_sanitized)) { $mixed_items_sanitized = array('dot','flake'); } + $media_urls = array(); foreach ($mixed_items_sanitized as $key) { if ($key === 'dot') { $deps[] = $shape_dot_handle; } if ($key === 'flake') { $deps[] = $shape_flake_handle; } @@ -726,7 +765,7 @@ function yoone_snow_register_settings() { // 添加首页显示时长字段 输入为数字最小值为 0 add_settings_field( 'yoone_snow_home_duration', - esc_html__('Home Display Duration Seconds', 'yoone-snow'), + esc_html__('Display Duration Seconds', 'yoone-snow'), function() { // 读取当前设置值 并渲染数字输入框 $current = intval(get_option('yoone_snow_home_duration', 0)); @@ -861,6 +900,64 @@ function yoone_snow_register_settings() { 'yoone_snow', 'yoone_snow_section' ); + + // 路由显示模式设置 + register_setting('yoone_snow_options', 'yoone_snow_display_routes_mode', array( + 'type' => 'string', + 'sanitize_callback' => function($value) { + $val = strtolower(trim((string)$value)); + $allowed = array('home','all','match'); + return in_array($val, $allowed, true) ? $val : 'home'; + }, + 'default' => 'home', + )); + add_settings_field( + 'yoone_snow_display_routes_mode', + esc_html__('Display Routes Mode', 'yoone-snow'), + function() { + $current = get_option('yoone_snow_display_routes_mode', 'home'); + echo ''; + echo ''; + echo ''; + echo '
' . esc_html__('Default Home Only choose All Pages to enable globally choose Match URL Path to enable only for matched routes', 'yoone-snow') . '
'; + }, + 'yoone_snow', + 'yoone_snow_section' + ); + // 路由匹配规则列表设置 + register_setting('yoone_snow_options', 'yoone_snow_display_routes', array( + 'type' => 'array', + 'sanitize_callback' => function($value) { + if (is_string($value)) { + $value = preg_split('/\\r?\\n/', $value); + } + if (!is_array($value)) { $value = array(); } + $out = array(); + foreach ($value as $item) { + $s = trim((string)$item); + if ($s !== '') { $out[] = $s; } + } + return array_values(array_unique($out)); + }, + 'default' => array(), + )); + add_settings_field( + 'yoone_snow_display_routes', + esc_html__('Match Routes', 'yoone-snow'), + function() { + $current = get_option('yoone_snow_display_routes', array()); + if (is_string($current)) { + $current = preg_split('/\\r?\\n/', $current); + } + if (!is_array($current)) { $current = array(); } + $text = implode("\n", array_map('strval', $current)); + $placeholder = esc_attr__("Example /about\n/blog/*\n/shop", 'yoone-snow'); + echo ''; + echo '' . esc_html__('One rule per line compare against request path example exact path /about prefix match with trailing star /blog/*', 'yoone-snow') . '
'; + }, + 'yoone_snow', + 'yoone_snow_section' + ); } // 添加设置页面到后台菜单 条目在设置菜单下