refactor(雪花效果): 简化尺寸缩放逻辑并使用最小半径和摆动作为缩放因子

移除单独的尺寸与偏移缩放设置,直接使用最小半径和最小摆动作为缩放系数
将半径设置合并为单一选项组,简化后台配置界面
This commit is contained in:
tikkhun 2025-12-11 11:22:25 +08:00
parent 0c063d304e
commit 3cd9cfa987
2 changed files with 42 additions and 85 deletions

View File

@ -36,14 +36,7 @@
const val = typeof shapeWeightsRaw[key] !== 'undefined' ? parseInt(shapeWeightsRaw[key], 10) : defaultShapeWeights[key]; const val = typeof shapeWeightsRaw[key] !== 'undefined' ? parseInt(shapeWeightsRaw[key], 10) : defaultShapeWeights[key];
shapeWeights[key] = isNaN(val) ? defaultShapeWeights[key] : Math.max(0, val); shapeWeights[key] = isNaN(val) ? defaultShapeWeights[key] : Math.max(0, val);
} }
const sizeScaleRaw = (window.YooneSnowSettings && typeof window.YooneSnowSettings.sizeScale !== 'undefined') // 移除单独的尺寸与偏移缩放 直接使用最小半径与最小摆动作为缩放系数
? parseFloat(window.YooneSnowSettings.sizeScale)
: 1.0;
const offsetScaleRaw = (window.YooneSnowSettings && typeof window.YooneSnowSettings.offsetScale !== 'undefined')
? parseFloat(window.YooneSnowSettings.offsetScale)
: 1.0;
const sizeScale = isNaN(sizeScaleRaw) ? 1.0 : Math.max(0.1, sizeScaleRaw);
const offsetScale = isNaN(offsetScaleRaw) ? 1.0 : Math.max(0, offsetScaleRaw);
const radiusMinRaw = (window.YooneSnowSettings && typeof window.YooneSnowSettings.radiusMin !== 'undefined') const radiusMinRaw = (window.YooneSnowSettings && typeof window.YooneSnowSettings.radiusMin !== 'undefined')
? parseFloat(window.YooneSnowSettings.radiusMin) ? parseFloat(window.YooneSnowSettings.radiusMin)
: 1.0; : 1.0;
@ -62,8 +55,8 @@
const swingMaxRaw = (window.YooneSnowSettings && typeof window.YooneSnowSettings.swingMax !== 'undefined') const swingMaxRaw = (window.YooneSnowSettings && typeof window.YooneSnowSettings.swingMax !== 'undefined')
? parseFloat(window.YooneSnowSettings.swingMax) ? parseFloat(window.YooneSnowSettings.swingMax)
: 1.0; : 1.0;
const radiusMin = isNaN(radiusMinRaw) ? 1.0 : Math.max(0, radiusMinRaw); const radiusMin = isNaN(radiusMinRaw) ? 1 : Math.max(0, radiusMinRaw);
const radiusMax = isNaN(radiusMaxRaw) ? 3.0 : Math.max(radiusMin, radiusMaxRaw); const radiusMax = isNaN(radiusMaxRaw) ? 3 : Math.max(radiusMin, radiusMaxRaw);
const driftMin = isNaN(driftMinRaw) ? 0.4 : Math.max(0, driftMinRaw); const driftMin = isNaN(driftMinRaw) ? 0.4 : Math.max(0, driftMinRaw);
const driftMax = isNaN(driftMaxRaw) ? 1.0 : Math.max(driftMin, driftMaxRaw); const driftMax = isNaN(driftMaxRaw) ? 1.0 : Math.max(driftMin, driftMaxRaw);
const swingMin = isNaN(swingMinRaw) ? 0.2 : Math.max(0, swingMinRaw); const swingMin = isNaN(swingMinRaw) ? 0.2 : Math.max(0, swingMinRaw);
@ -130,9 +123,11 @@
return { return {
positionX: Math.random() * viewportWidth, positionX: Math.random() * viewportWidth,
positionY: -5 - Math.random() * 20, positionY: -5 - Math.random() * 20,
radius: (Math.random() * (radiusMax - radiusMin) + radiusMin) * sizeScale, // 半径使用随机范围并乘以最小半径作为缩放因子
radius: (Math.random() * (radiusMax - radiusMin) + radiusMin) * radiusMin,
driftSpeed: Math.random() * (driftMax - driftMin) + driftMin, driftSpeed: Math.random() * (driftMax - driftMin) + driftMin,
swingAmplitude: (Math.random() * (swingMax - swingMin) + swingMin) * offsetScale, // 水平摆动使用随机范围并乘以最小摆动作为缩放因子
swingAmplitude: (Math.random() * (swingMax - swingMin) + swingMin) * swingMin,
shapeType: chosenType, shapeType: chosenType,
imageUrl: chosenImageUrl, imageUrl: chosenImageUrl,
// 标记该粒子是否已经移出视口 用于停止后清理 // 标记该粒子是否已经移出视口 用于停止后清理
@ -152,9 +147,11 @@
if (!hasReachedDuration){ if (!hasReachedDuration){
flake.positionY = -5; flake.positionY = -5;
flake.positionX = Math.random() * viewportWidth; flake.positionX = Math.random() * viewportWidth;
flake.radius = (Math.random() * (radiusMax - radiusMin) + radiusMin) * sizeScale; // 重生时应用同样的半径缩放逻辑
flake.radius = (Math.random() * (radiusMax - radiusMin) + radiusMin) * radiusMin;
flake.driftSpeed = Math.random() * (driftMax - driftMin) + driftMin; flake.driftSpeed = Math.random() * (driftMax - driftMin) + driftMin;
flake.swingAmplitude = (Math.random() * (swingMax - swingMin) + swingMin) * offsetScale; // 重生时应用同样的摆动缩放逻辑
flake.swingAmplitude = (Math.random() * (swingMax - swingMin) + swingMin) * swingMin;
} else { } else {
flake.outOfView = true; flake.outOfView = true;
} }

View File

@ -2,7 +2,7 @@
/* /*
Plugin Name: Yoone Snow Plugin Name: Yoone Snow
Description: 首页 canvas 雪花效果 Description: 首页 canvas 雪花效果
Version: 1.3.0 Version: 1.5.0
Author: Yoone Author: Yoone
*/ */
@ -114,14 +114,19 @@ function yoone_snow_enqueue_assets() {
if ($val < 0) { $val = 0; } if ($val < 0) { $val = 0; }
$shape_weights[$k] = $val; $shape_weights[$k] = $val;
} }
// 读取尺寸组合设置 包含最小与最大半径 如未设置则回退到旧选项与默认值
$size_group = get_option('yoone_snow_size', array('min' => 1.0, 'max' => 3.0));
$radius_min_val = isset($size_group['min']) ? floatval($size_group['min']) : floatval(get_option('yoone_snow_radius_min', 1.0));
$radius_max_val = isset($size_group['max']) ? floatval($size_group['max']) : floatval(get_option('yoone_snow_radius_max', 3.0));
if ($radius_min_val < 0) { $radius_min_val = 0.0; }
if ($radius_max_val < $radius_min_val) { $radius_max_val = $radius_min_val; }
wp_localize_script($script_handle, 'YooneSnowSettings', array( wp_localize_script($script_handle, 'YooneSnowSettings', array(
'selectedShapes' => $mixed_items_sanitized, 'selectedShapes' => $mixed_items_sanitized,
'mediaItems' => $media_urls, 'mediaItems' => $media_urls,
'displayDurationSeconds' => intval(get_option('yoone_snow_home_duration', 0)), 'displayDurationSeconds' => intval(get_option('yoone_snow_home_duration', 0)),
'sizeScale' => floatval(get_option('yoone_snow_size_scale', 1.0)), 'radiusMin' => $radius_min_val,
'offsetScale' => floatval(get_option('yoone_snow_offset_scale', 1.0)), 'radiusMax' => $radius_max_val,
'radiusMin' => floatval(get_option('yoone_snow_radius_min', 1.0)),
'radiusMax' => floatval(get_option('yoone_snow_radius_max', 3.0)),
'driftMin' => floatval(get_option('yoone_snow_drift_min', 0.4)), 'driftMin' => floatval(get_option('yoone_snow_drift_min', 0.4)),
'driftMax' => floatval(get_option('yoone_snow_drift_max', 1.0)), 'driftMax' => floatval(get_option('yoone_snow_drift_max', 1.0)),
'swingMin' => floatval(get_option('yoone_snow_swing_min', 0.2)), 'swingMin' => floatval(get_option('yoone_snow_swing_min', 0.2)),
@ -421,83 +426,38 @@ function yoone_snow_register_settings() {
'yoone_snow_section' 'yoone_snow_section'
); );
register_setting('yoone_snow_options', 'yoone_snow_size_scale', array( // 尺寸组合设置 使用单一选项 snow size 存储最小与最大半径
'type' => 'number', register_setting('yoone_snow_options', 'yoone_snow_size', array(
'type' => 'array',
'sanitize_callback' => function($value) { 'sanitize_callback' => function($value) {
$num = floatval($value); // 将输入统一为包含 min 与 max 的数值数组 并保证非负与 max 不小于 min
if ($num < 0.1) { $num = 0.1; } if (!is_array($value)) { $value = array(); }
return $num; $min = isset($value['min']) ? floatval($value['min']) : 1.0;
$max = isset($value['max']) ? floatval($value['max']) : 3.0;
if ($min < 0) { $min = 0.0; }
if ($max < $min) { $max = $min; }
return array('min' => $min, 'max' => $max);
}, },
'default' => 1.0, 'default' => array('min' => 1.0, 'max' => 3.0),
)); ));
add_settings_field( add_settings_field(
'yoone_snow_size_scale', 'yoone_snow_size',
'Snow Size Scale', 'Snow Size',
function() { function() {
$current = floatval(get_option('yoone_snow_size_scale', 1.0)); // 渲染组合输入 使用同一选项保存最小与最大半径
echo '<input type="number" min="0.1" step="0.1" name="yoone_snow_size_scale" value="' . esc_attr($current) . '" style="width:120px;" />'; $grp = get_option('yoone_snow_size', array('min' => 1.0, 'max' => 3.0));
echo '<p class="description">Multiply snowflake radius default is 1.0</p>'; $min = isset($grp['min']) ? floatval($grp['min']) : 1.0;
$max = isset($grp['max']) ? floatval($grp['max']) : 3.0;
echo '<label style="margin-right:12px;">Min <input type="number" min="0" step="0.1" name="yoone_snow_size[min]" value="' . esc_attr($min) . '" style="width:120px;" /></label>';
echo '<label>Max <input type="number" min="0" step="0.1" name="yoone_snow_size[max]" value="' . esc_attr($max) . '" style="width:120px;" /></label>';
echo '<p class="description">Random radius in [min max] single option</p>';
}, },
'yoone_snow', 'yoone_snow',
'yoone_snow_section' 'yoone_snow_section'
); );
register_setting('yoone_snow_options', 'yoone_snow_offset_scale', array( // 漂移速度与摆动幅度的随机范围设置 保持独立选项
'type' => 'number',
'sanitize_callback' => function($value) {
$num = floatval($value);
if ($num < 0) { $num = 0; }
return $num;
},
'default' => 1.0,
));
add_settings_field(
'yoone_snow_offset_scale',
'Snow Horizontal Offset Scale',
function() {
$current = floatval(get_option('yoone_snow_offset_scale', 1.0));
echo '<input type="number" min="0" step="0.1" name="yoone_snow_offset_scale" value="' . esc_attr($current) . '" style="width:120px;" />';
echo '<p class="description">Multiply horizontal swing amplitude default is 1.0</p>';
},
'yoone_snow',
'yoone_snow_section'
);
// 随机范围设置 注册与字段渲染 包含半径 漂移速度 摆动幅度的最小与最大
register_setting('yoone_snow_options', 'yoone_snow_radius_min', array(
'type' => 'number',
'sanitize_callback' => function($value) {
$num = floatval($value);
if ($num < 0) { $num = 0; }
return $num;
},
'default' => 1.0,
));
register_setting('yoone_snow_options', 'yoone_snow_radius_max', array(
'type' => 'number',
'sanitize_callback' => function($value) {
$min = floatval(get_option('yoone_snow_radius_min', 1.0));
$num = floatval($value);
if ($num < $min) { $num = $min; }
return $num;
},
'default' => 3.0,
));
add_settings_field(
'yoone_snow_radius_range',
'Radius Random Range',
function() {
$min = floatval(get_option('yoone_snow_radius_min', 1.0));
$max = floatval(get_option('yoone_snow_radius_max', 3.0));
echo '<label style="margin-right:12px;">Min <input type="number" min="0" step="0.1" name="yoone_snow_radius_min" value="' . esc_attr($min) . '" style="width:120px;" /></label>';
echo '<label>Max <input type="number" min="0" step="0.1" name="yoone_snow_radius_max" value="' . esc_attr($max) . '" style="width:120px;" /></label>';
echo '<p class="description">Random radius in [min max] before size scale</p>';
},
'yoone_snow',
'yoone_snow_section'
);
register_setting('yoone_snow_options', 'yoone_snow_drift_min', array( register_setting('yoone_snow_options', 'yoone_snow_drift_min', array(
'type' => 'number', 'type' => 'number',