0

I'm not looking for any code at all, just looking for feedback from the smart people that are generally extremely helpful on this site.

Say I have an image like this:

image

And I want to have that image on my website, with options for the user to change the eye color and the hair color (either select or radio buttons).

So image would start with blue eyes and I'd have a select list for Eye color with:

Brown Green Blue Hazel

If user selects Green, I'd want the image to now have green eyes.

My question: What do you feel is best way to approach this type of thing? I feel like my options are...

  1. Use an SVG of the face and somehow trigger changes to the paths that makes up the eye color and the hair color. This is doable but maybe overly complicated?

  2. Create separate PNGs for each combo (red hair/blue eyes, red hair/green eyes, etc, etc) and have the image change every time a different selection is made.

  3. Maybe the eyes could be updated using CSS if I make them perfectly round? Guess that isnt feasible with the hair.

  4. Some other approach that I'm probably missing???

Any thoughts? The site could potentially have a lot of traffic, so I am definitely concerned with making whatever approach I use be the least intensive (if possible)

Community
  • 1
  • 1
user3304303
  • 1,027
  • 12
  • 31
  • If you are using a canvas, I recently saw a pallet swapping demo that was very cool. A simple version of it might be applied to swap the pallet to re-define you colors. check out: http://www.effectgames.com/demos/canvascycle/ – JonSG Aug 17 '16 at 19:04

4 Answers4

3

You would use multiple svgs that would be layered on top of each other. And then using javascript you could modify the color and replace content of svg with different variation.

You would have different layer for hair, eyes, lips, face, nose, ears, and so on. User would be able to just change one item at a time, and it'd affect one layer.

Once user is happy he would click save, and then you could save information about all layers in json format and this way always be able to recreate it, but if you wanted you can also convert it to png.

One way to do it would be this: Drawing an SVG file on a HTML5 canvas

But ideally i'd want backend to take just information on configuration like below and build picture there.

 {
  face: {
    eyes: 3,
    nose: 1,
    hair: 4,
    skin: 3
  },
  colors: {
    eyes: 3,
    general: 1,
    nose: 4
  },
  accessories: [{
    {
      name: 'hat',
      x: 30,
      y: 10,
      type: 3
    }, {
      name: 'sticker_star',
      x: 20,
      y: 10,
      type: 1
    }, {
      name: 'glasses',
      x: 550,
      y: 30,
      type: 1
    }
  }]
}
Community
  • 1
  • 1
Muhammad Umer
  • 17,263
  • 19
  • 97
  • 168
  • I agree with using a config file to store selected options. – zsawaf Aug 17 '16 at 19:23
  • I'd definitely want to save the info so that the image could be recreated later. Are you saying to save the info to a database (I use php/mysql so that is easily possible) or save it some other way (sorry, I think I'm confused by the idea of saving it to a "config file" that @zsawaf mentioned) – user3304303 Aug 17 '16 at 20:14
  • 1
    you save info into a database. However, as i said you can use this info two ways: 1) Recreate Avatar from info every time. 2) Only recreate avatar in edit mode, and everywhere else use a picture that you have generated using the settings. And to get a picture you have two ways a) generate it on client side or b) generate it on server side. ( i think server side is better, since it allows user to modify request and send any other picture, but could be overkill depending on what you are doing) – Muhammad Umer Aug 17 '16 at 20:20
  • 1
    The way I would think of it is the following: You would have tables for each accessory/feature/colour and all the options. Then you would have another table that maps what each user selected for each option. When you load the app, you select the latter table, and you load the data into a state object. Then from that object, you'd know what to display. Whenever the user changes something, you can update the user's database with the new values. – zsawaf Aug 17 '16 at 20:25
  • one last thing @MuhammadUmer, when you say "You would use multiple svgs that would be layered on top of each other.", does that mean I would just layer/position the various SVGs using CSS (position and z-index)? – user3304303 Aug 19 '16 at 13:38
  • 1
    Yes That is easier to me. But you can easily do it with svg as well https://jsfiddle.net/vL0rqyb8/1/ click image to move it – Muhammad Umer Aug 19 '16 at 16:36
2

I can't comment on questions yet, so I will write a few things in here with my thoughts.

Doing this by an SVG is intriguing, and I feel like that would be an avenue that you should research a bit more. I have only done some minor things using SVG's so I am in no way an expert. The major bonus to using an SVG over something like your multiple PNG idea would really just be performance as SVG's are generally very small.

Making multiple PNG's is not a bad idea either, but definitely not your optimal solution. With today's technology, though, and the speed of some front end materials (AngularJS, Ajax, etc.) make serving up images extremely fast. If you are looking to get this developed quickly, this approach is probably your best bet.

Side note: look into webkits to do this for you as well. Webkits are newer, so they won't be supported on many browsers. Webkits are also generally predefined through filters for images or something of the sort, so I am not sure you would have as much customization as you are looking for.

I hope this helps!

hmiedema9
  • 948
  • 4
  • 17
2

I think the best way to approach changing the color of the eyes is option 1.

A partial change to SVG is low intensive.

To do this, one option is to assign an 'id' for each dynamic SVG part of the face and create individual updatable functions to trigger the change.

This approach is low bandwidth (just a couple lines of javascript) and can be done client-side with no additional requests to the server.

Here is a crude example of an SVG circle representing the eyes, notice the id='eyes':

<svg width="100" height="100">
   <circle id="eyes" cx="50" cy="50" r="40" fill="yellow" />
</svg>

You can then create an input (selector, checkbox, button, etc) to find the SVG element using its id then change it's color fill style attribute from green to brown, hazel or blue. Here is an example of a button that changes the fill to hazel 'onclick':

<button onclick=eyes.style.fill="hazel">Click to change eyes to Hazel</button>

This is just one way to get this done demonstrating the process. You can then create an entire function for 'onclick' triggering a select list you would create in HTML.

2

I guess you just answered yourself. All the 3 options are good to reach your needs.

  1. You can trigger the fill and outline of any SVG with CSS transitions. It's not complicated since you use only inline SVGs (I don't know if there is an option to change fill colors dinamically on a background SVG).

  2. PNGs are bitmap images, thus has better detail level. The caveat is the need to use a lot of files—thus more http requests, unless you use sprites.

  3. CSS-only could be tricky even if you're planning to use it just with the eyes, in this case.

  4. You can try to use CSS3 filters, like:

    .eyes {
        filter: saturate(1);
        filter: hue-rotate(0deg);
        filter: brightness(1);
    }

There are other CSS filters, of course. But I guess these 3 above could help.

ed1nh0
  • 1,532
  • 13
  • 17