Basecamp does something like this but I do not know exactly how they've done it. This is my take on using an image for the user's avatar, uploaded using Active Storage.
My profile
model is setup with an has_one_attached
:
# profile.rb
has_one_attached :avatar
belongs_to :user
User model is not important here but it looks like this:
# user.rb
has_one :profile
The logic is that once the user has registered with their name, we generate the image initial then upload it.
def generate_avatar(user)
# The first character from the user's name.
# Basecamp does some extra checks to check for numbers
# and alphabet from the name. When invalid, they
# return a question mark: ?
initial = user.profile.name.first.upcase
# A colour that will not change for the user: red, green, hex value etc
colour = user.default_colour
# A HTML markup with background color; inline or in the css file
html = "<div style='background:#{colour};width:280px;height:280px' class='custom_avatar'><span>#{initial}</span></div>"
# See rest of post
kit = IMGKit.new(html, :width => 280, :quality => 50)
# A custom stylesheet
kit.stylesheets << "#{Rails.root}/app/assets/stylesheets_custom/custom_avatar.css"
# Store image in a temp folder
file_path = Tempfile.new(["file", '.jpg']).path
kit.to_file(file_path)
# Upload the image
user.profile.avatar.attach(io: File.open(file_path), filename: 'avatar.jpg')
end
The setup
Gemfile.rb
:
# https://github.com/csquared/IMGKit
gem 'imgkit'
gem 'wkhtmltoimage-binary'
Run bundle install
to install the gems above. I'm using IMGKit.
Custom Stylesheet
I put this in app/stylesheets_custom/*
* {
margin: 0;
padding: 0;
}
.custom_avatar {
width: 280px;
height: 280px;
padding: 0;
margin: 0;
font-size: 8rem;
font-weight: bold;
color: white;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
For reusable methods, I create a module and place in: controllers/concerns/*
:
# user_avatar_image.rb
module UserAvatarImage
def random_colour
["#A9294F", "#ED6663", "#389393", "#D82148", "#8C5425", "#6F38C5"].sample
end
def generate_avatar(user)
# The first character from the user's name
initial = user.profile.name.first.upcase
# A colour that will not change for the user: red, green, hex value etc
colour = user.default_colour
# A HTML markup with background color; inline or in the css file
html = "<div style='background:#{colour};width:280px;height:280px' class='custom_avatar'><span>#{initial}</span></div>"
# See rest of post
kit = IMGKit.new(html, :width => 280, :quality => 50)
# A custom style sheet
kit.stylesheets << "#{Rails.root}/app/assets/stylesheets_custom/custom_avatar.css"
# Store image in a temp folder
file_path = Tempfile.new(["file", '.jpg']).path
kit.to_file(file_path)
# Upload the image
user.profile.avatar.attach(io: File.open(file_path), filename: 'avatar.jpg')
end
end
The Flow
During user registration, random_colour
is used to set a random colour. Next, we call generate_avatar(resource)
to generate and upload the image. You would call generate_avatar
every time the user changes their name 😉
Feel free to to modify the font size and dimensions for the image. Enjoy!
Top comments (0)