Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
210 views
in Technique[技术] by (71.8m points)

PHP scale number up/down based on input?

Using the length of a string, I want to scale the font size up/down based on that.

So, lower string length, higher number. Higher string length, lower number.

But I don't want to do dozens upon dozens of if/else or a switch statement. Ideally I'd programmatically scale the output based on the input.

Something like...

  text_length = strlen($full_text)
  size_range = range(0, 5)
  
  // if text_length = 1 then 100% of size_range
  // if text_length = 280 then 0% of size_range

In this case, the maximum text length is 280 (they're tweets).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

If the plot of y = 1/-279x + 280/279 reflects what you want.

plot of requested result

I did the following script in Ruby that should be easy to translate to PHP:

require "bundler/inline"

gemfile do
  gem "rspec"
end

require "rspec/autorun"

MAX_SIZE_PERCENTAGE = 1.0

def size_it(text_length, maximum_length)
  alpha = - MAX_SIZE_PERCENTAGE / (maximum_length - MAX_SIZE_PERCENTAGE)
  beta = maximum_length / (maximum_length - MAX_SIZE_PERCENTAGE)
  ((alpha * text_length) + beta).round(2)
end

RSpec.describe "dynamic size calculation" do
  it "100% when minimal size" do
    text_length = 1
    maximum_size = 280
    expect(size_it(text_length, maximum_size)).to eq(1)
  end

  it "75% when almost too short" do
    text_length = 70
    maximum_size = 280
    expect(size_it(text_length, maximum_size)).to eq(0.75)
  end

  it "50% when half point" do
    text_length = 140
    maximum_size = 280
    expect(size_it(text_length, maximum_size)).to eq(0.5)
  end

  it "25% when almost too long" do
    text_length = 210
    maximum_size = 280
    expect(size_it(text_length, maximum_size)).to eq(0.25)
  end

  it "0% when maximum size" do
    text_length = 280
    maximum_size = 280
    expect(size_it(text_length, maximum_size)).to eq(0)
  end
end

The math is intuitive, a few landmines:

  • integer division, e.g 1/280 resulting in 0 instead of 0.0003, I prevented this by calling .to_f, Ruby way to cast to float.
  • rounding errors, expecting 0.25 and getting 0.2503213, I adjusted this by calling round(2), Ruby way to round to nearest decimal point.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...