├── assets ├── img │ ├── hero.png │ ├── hero-rowan.png │ └── sprite-sheet-01.png ├── scss │ ├── inc │ │ ├── _vars.scss │ │ ├── _tools.scss │ │ └── _base-maker-data-vars.scss │ └── style.scss └── css │ └── style.css ├── .htaccess ├── .jshintrc ├── README.md ├── package.json ├── LICENSE ├── index.php ├── Gruntfile.js ├── .gitignore ├── data └── base-maker-data.json └── inc └── functions.php /assets/img/hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KawaiiHannah/pixel-character/HEAD/assets/img/hero.png -------------------------------------------------------------------------------- /assets/img/hero-rowan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KawaiiHannah/pixel-character/HEAD/assets/img/hero-rowan.png -------------------------------------------------------------------------------- /assets/img/sprite-sheet-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KawaiiHannah/pixel-character/HEAD/assets/img/sprite-sheet-01.png -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | SetOutputFilter DEFLATE 4 | 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise": false, 3 | "browser": false, 4 | "curly": false, 5 | "eqeqeq": false, 6 | "eqnull": false, 7 | "esnext": false, 8 | "immed": false, 9 | "jquery": false, 10 | "latedef": false, 11 | "newcap": false, 12 | "noarg": false, 13 | "node": false, 14 | "strict": false, 15 | "trailing": false 16 | } 17 | -------------------------------------------------------------------------------- /assets/scss/inc/_vars.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------------- 2 | * 3 | * Pixel Maker - Variables 4 | * 5 | -------------------------------------------------------------------------------------*/ 6 | 7 | // Colours 8 | $pm-color--primary: #3e3936; 9 | $pm-color--secondary: #bae6cd; 10 | $pm-color--secondary-dark: #95cecb; 11 | $pm-color--tertiary: #deac6c; 12 | 13 | 14 | // Typefaces 15 | $pm-typeface--primary: 'Verdana', sans-serif; 16 | 17 | 18 | // Spritemap sizes 19 | $pm-sprite-item--width: 64px; 20 | $pm-sprite-item--height: 136px; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 10KB Pixel Art Character 2 | A pixel art character generator that delivers in under 10kb 3 | 4 | This was a project made for 10k Apart 2016. The project works without any Javascript. All interactions are managed with CSS and the resulting choices saved with PHP to create the final image. 5 | 6 | Can you change images made with this generator? Yes, you're welcome to edit them to make them more personalised. Feel free to tweet these @kawaiihannahart ^_^ 7 | 8 | If you want to resize the image to make it larger/smaller, use 'Nearest Neighbour' interpolation and save as a PNG or GIF. This will keep the pixels nice and crisp. 9 | 10 | Copyright 2016 Hannah Malcolm. -------------------------------------------------------------------------------- /assets/scss/inc/_tools.scss: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------------------- 2 | * 3 | * Pixel Maker - Tools 4 | * 5 | -------------------------------------------------------------------------------------*/ 6 | 7 | 8 | /** 9 | * Retrieve the sprite location (in pixels) 10 | */ 11 | @function pm-get-sprite-map-element( $x, $y, $width: $pm-sprite-item--width, $height: $pm-sprite-item--height ) { 12 | 13 | @return ( ( $x - 1 ) * $width * -1 ) ( ( $y - 1 ) * $height * -1 ); 14 | 15 | } 16 | 17 | 18 | 19 | 20 | /** 21 | * Include the markup for a sprite element 22 | */ 23 | @mixin pm-sprite-map-element( $item, $x, $y ) { 24 | 25 | #{ $item }:checked + label::after, 26 | #{ $item } + label::before { 27 | 28 | background-position: pm-get-sprite-map-element( $x, $y ); 29 | 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "10kbCharacter", 3 | "client_code": "pxlm", 4 | "version": "1.0.0", 5 | "description": "A pixel art character maker in less than 10kb", 6 | "author": "Hannah Malcolm ", 7 | "license": "MIT", 8 | "devDependencies": { 9 | "autoprefixer": "^6.4.0", 10 | "autoprefixer-core": "^5.2.0", 11 | "cssnano": "^3.7.4", 12 | "grunt": "^0.4.5", 13 | "grunt-browser-sync": "^2.1.3", 14 | "grunt-combine-media-queries": "^1.0.20", 15 | "grunt-contrib-concat": "^0.5.0", 16 | "grunt-contrib-sass": "^0.8.1", 17 | "grunt-contrib-uglify": "^0.7.0", 18 | "grunt-contrib-watch": "^0.6.1", 19 | "grunt-json-to-sass": "0.0.3", 20 | "grunt-modernizr": "^0.6.0", 21 | "grunt-postcss": "^0.8.0", 22 | "load-grunt-tasks": "^2.0.0", 23 | "sassport": "^0.8.0", 24 | "time-grunt": "^1.0.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Hannah Malcolm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/scss/inc/_base-maker-data-vars.scss: -------------------------------------------------------------------------------- 1 | $Skintones:(li:(name:"Light",x:1,y:1),me:(name:"Medium",x:2,y:1),da:(name:"Dark",x:3,y:1)); 2 | $Hairstyles:(h6:(name:"Medium - Brown",x:5,y:2),h7:(name:"Medium - Blonde",x:6,y:2),h8:(name:"Medium - Black",x:7,y:2),h9:(name:"Medium - Red",x:8,y:2),h10:(name:"Emo - Brown",x:1,y:3),h11:(name:"Emo - Blonde",x:2,y:3),h12:(name:"Emo - Black",x:3,y:3),h13:(name:"Emo - Red",x:4,y:3),h14:(name:"Short - Brown",x:5,y:3),h15:(name:"Short - Blonde",x:6,y:3),h16:(name:"Short - Red",x:8,y:3),h17:(name:"Ponytail - Brown",x:9,y:1),h18:(name:"Ponytail - Blonde",x:9,y:2),h19:(name:"Ponytail - Black",x:9,y:3),h20:(name:"Ponytail - Red",x:9,y:4)); 3 | $Pants:(p1:(name:"Jeans",x:1,y:2),p2:(name:"Pants - Black",x:2,y:2)); 4 | $Bottoms:(s0:(name:"No Skirt",x:0,y:0),s1:(name:"Skirt - Black with Pink Flowers",x:3,y:2),s2:(name:"Pencil Skirt - Grey",x:4,y:2)); 5 | $Tops:(t1:(name:"Hoodie - Grey",x:1,y:4),t2:(name:"Hoodie - Dark",x:2,y:4),t3:(name:"Jacket & T-Shirt - Dark",x:3,y:4),t4:(name:"Singlet - Black",x:4,y:4),t5:(name:"Long Sleeved - Black",x:5,y:4),t6:(name:"T Shirt - White",x:6,y:4)); 6 | $FacialHair:(f0:(name:"No Facial Hair",x:0,y:0),f1:(name:"Brown Beard",x:5,y:1),f2:(name:"Blonde Beard",x:6,y:1),f3:(name:"Black Beard",x:7,y:1),f4:(name:"Red Beard",x:8,y:1)); 7 | $Accessories:(a0:(name:"No Accessories",x:0,y:0),a1:(name:"Glasses",x:4,y:1)); 8 | $Shoes:(s1:(name:"Black Shoes",x:8,y:4),s2:(name:"White Shoes",x:7,y:4),s3:(name:"No Shoes",x:0,y:0)); -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | '; 10 | echo ''; 11 | 12 | echo ''; 13 | 14 | echo ''; 15 | echo ''; 16 | echo 'Create a pixel art character!'; 17 | echo ''; 18 | 19 | echo ''; 20 | 21 | echo ''; 22 | 23 | echo '
'; 24 | 25 | if ( isset( $_GET[ 'save' ] ) && isset( $_POST[ 'sk' ] ) ) { 26 | 27 | echo '
'; 28 | 29 | $choices = $maker->get_item_choices(); 30 | $image = $maker->create_image( $choices ); 31 | 32 | if ( $image ) { 33 | 34 | echo '
'; 35 | 36 | echo '

Your Pixel Art Character

'; 37 | echo '

Save your pixel art character below.

'; 38 | echo '
Generated Character Image
'; 39 | echo '

Download Start Again

'; 40 | 41 | echo '
'; 42 | 43 | } else { 44 | 45 | echo '

Oops!

'; 46 | echo '

Something went wrong! Please try again.

'; 47 | 48 | } 49 | 50 | echo '
'; 51 | 52 | } else { 53 | 54 | echo '
'; 55 | 56 | echo '
'; 57 | 58 | echo '

Make a Pixel Art Character

'; 59 | echo '

Start Designing

'; 60 | 61 | echo '
'; 62 | 63 | echo '
'; 64 | 65 | echo '
'; 66 | 67 | echo '
'; 68 | 69 | echo $maker->render_form(); 70 | 71 | echo '
'; 72 | 73 | echo '
'; 74 | 75 | } 76 | 77 | echo '
'; 78 | 79 | echo ''; 80 | 81 | echo ''; 82 | 83 | echo ''; -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function( grunt ) { 2 | 3 | // Load all tasks 4 | require( 'load-grunt-tasks' )( grunt ); 5 | 6 | // Show elapsed time 7 | require( 'time-grunt' )( grunt ); 8 | 9 | grunt.initConfig({ 10 | 11 | pkg: grunt.file.readJSON( 'package.json' ), 12 | 13 | sass: { 14 | dev: { 15 | files: [{ 16 | expand: true, 17 | cwd: 'assets/scss', 18 | src: ['*.scss'], 19 | dest: 'assets/css', 20 | ext: '.css' 21 | }], 22 | options: { 23 | style: 'extended', 24 | precision: 7, 25 | sourceMap: false, 26 | sourceMapEmbed: false 27 | } 28 | }, 29 | }, 30 | cmq: { 31 | options: { 32 | log: false 33 | }, 34 | your_target: { 35 | files: { 36 | 'assets/css/': [ 'assets/css/*.css' ] 37 | } 38 | } 39 | }, 40 | postcss: { 41 | options: { 42 | map: false, 43 | processors: [ 44 | require('autoprefixer-core')({ 45 | browsers: ['last 2 versions', 'ie 9', 'ie 10', 'android 4.3', 'android 4.4', 'firefox 34', 'firefox 35', 'opera 27', 'opera 26'] 46 | }), 47 | require('cssnano')({ 48 | 49 | 'discardDuplicates': true, 50 | 'discardEmpty': true, 51 | 'core': true, 52 | 'mergeRules': true, 53 | 54 | }) // minify the result 55 | ] 56 | }, 57 | dev: { 58 | options: { 59 | map: false, 60 | }, 61 | src: ['assets/css/style.css'] 62 | }, 63 | }, 64 | json_to_sass: { 65 | dev: { 66 | files: [ 67 | { 68 | src: [ 69 | 'data/base-maker-data.json' 70 | ], 71 | dest: 'assets/scss/inc/_base-maker-data-vars.scss' 72 | } 73 | ] 74 | }, 75 | }, 76 | watch: { 77 | sass: { 78 | files: [ 79 | '*.scss', 80 | '**/*.scss' 81 | ], 82 | tasks: ['sass:dev', 'postcss:dev'] 83 | }, 84 | }, 85 | browserSync: { 86 | dev: { 87 | bsFiles: { 88 | 89 | src : [ 90 | 'assets/css/*.css', 91 | '*.php', 92 | '**/*.php', 93 | ], 94 | 95 | }, 96 | options: { 97 | proxy: "10kb-character.localhost", 98 | watchTask: true, 99 | } 100 | } 101 | }, 102 | }); 103 | 104 | // Register tasks 105 | grunt.registerTask('default', [ 106 | 'dev' 107 | ]); 108 | grunt.registerTask('dev', [ 109 | 'json_to_sass', 110 | 'sass:dev', 111 | 'postcss:dev', 112 | 'cmq', 113 | 'browserSync', 114 | 'watch', 115 | ]); 116 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ============================================================================= 2 | # =OSX 3 | # ============================================================================= 4 | 5 | .DS_Store 6 | .AppleDouble 7 | .LSOverride 8 | 9 | ## Icon must end with two \r 10 | #Icon 11 | 12 | ## Thumbnails 13 | ._* 14 | 15 | ## Files that might appear on external disk 16 | 17 | .Spotlight-V100 18 | .Trashes 19 | 20 | ## Directories potentially created on remote AFP share 21 | 22 | .AppleDB 23 | .AppleDesktop 24 | Network Trash Folder 25 | Temporary Items 26 | .apdisk 27 | *~ 28 | .svn 29 | .cvs 30 | *.bak 31 | *.swp 32 | 33 | # ============================================================================= 34 | # =Windows 35 | # ============================================================================= 36 | 37 | ## Windows image file caches 38 | 39 | Thumbs.db 40 | ehthumbs.db 41 | 42 | 43 | ## Folder config file 44 | 45 | Desktop.ini 46 | 47 | ## Recycle Bin used on file shares 48 | 49 | $RECYCLE.BIN/ 50 | 51 | ## Windows Installer files 52 | 53 | *.cab 54 | *.msi 55 | *.msm 56 | *.msp 57 | # Windows shortcuts 58 | *.lnk 59 | 60 | # ============================================================================= 61 | # =WordPress 62 | # ============================================================================= 63 | 64 | *.log 65 | sitemap.xml 66 | sitemap.xml.gz 67 | wp-config.php 68 | wp-admin/ 69 | wp-includes/ 70 | wp-content/advanced-cache.php 71 | wp-content/backup-db/ 72 | wp-content/backups/ 73 | wp-content/blogs.dir/ 74 | wp-content/cache/ 75 | wp-content/upgrade/ 76 | wp-content/uploads/ 77 | wp-content/wp-cache-config.php 78 | wp-content/cache/supercache/* 79 | 80 | 81 | # ============================================================================= 82 | # =WPengine 83 | # ============================================================================= 84 | 85 | .smushit-status 86 | .gitattributes 87 | _wpeprivate 88 | wp-content/object-cache.php 89 | wp-content/mu-plugins/mu-plugin.php 90 | wp-content/mu-plugins/slt-force-strong-passwords.php 91 | wp-content/mu-plugins/limit-login-attempts 92 | wp-content/mu-plugins/wpengine-common 93 | wp-content/mysql.sql 94 | 95 | # ============================================================================= 96 | # =SASS / =SCSS 97 | # ============================================================================= 98 | 99 | .sass-cache 100 | *.css.map 101 | 102 | # ============================================================================= 103 | # =NODE.JS 104 | # ============================================================================= 105 | 106 | ## Logs 107 | 108 | logs 109 | *.log 110 | 111 | ## Runtime data 112 | 113 | pids 114 | *.pid 115 | *.seed 116 | 117 | ## Directory for instrumented libs generated by jscoverage/JSCover 118 | 119 | lib-cov 120 | 121 | ## Coverage directory used by tools like istanbul 122 | 123 | coverage 124 | 125 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 126 | 127 | .grunt 128 | 129 | ## node-waf configuration 130 | 131 | .lock-wscript 132 | 133 | ## Compiled binary addons (http://nodejs.org/api/addons.html) 134 | 135 | build/Release 136 | 137 | ## Dependency directory 138 | ## https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 139 | node_modules 140 | 141 | ## CodeKit 142 | codekit.cache 143 | 144 | 145 | 146 | # ============================================================================= 147 | # =large/disallowed file types 148 | # a CDN should be used for these 149 | # ============================================================================= 150 | 151 | *.hqx 152 | *.bin 153 | *.exe 154 | *.dll 155 | *.deb 156 | *.dmg 157 | *.iso 158 | *.img 159 | *.msi 160 | *.msp 161 | *.msm 162 | *.mid 163 | *.midi 164 | *.kar 165 | *.mp3 166 | *.ogg 167 | *.m4a 168 | *.ra 169 | *.3gpp 170 | *.3gp 171 | *.mp4 172 | *.mpeg 173 | *.mpg 174 | *.mov 175 | *.webm 176 | *.flv 177 | *.m4v 178 | *.mng 179 | *.asx 180 | *.asf 181 | *.wmv 182 | *.avi 183 | -------------------------------------------------------------------------------- /data/base-maker-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "Skintones": { 3 | 4 | "li": { 5 | 6 | "name": "Light", 7 | "x":"1", 8 | "y":"1" 9 | 10 | }, 11 | "me": { 12 | 13 | "name": "Medium", 14 | "x":"2", 15 | "y":"1" 16 | 17 | }, 18 | "da": { 19 | 20 | "name": "Dark", 21 | "x":"3", 22 | "y":"1" 23 | 24 | } 25 | 26 | }, 27 | "Hairstyles": { 28 | "h6": { 29 | 30 | "name":"Medium - Brown", 31 | "x":"5", 32 | "y":"2" 33 | 34 | }, 35 | "h7": { 36 | 37 | "name":"Medium - Blonde", 38 | "x":"6", 39 | "y":"2" 40 | 41 | }, 42 | "h8": { 43 | 44 | "name":"Medium - Black", 45 | "x":"7", 46 | "y":"2" 47 | 48 | }, 49 | "h9": { 50 | 51 | "name":"Medium - Red", 52 | "x":"8", 53 | "y":"2" 54 | 55 | }, 56 | "h10": { 57 | 58 | "name":"Emo - Brown", 59 | "x":"1", 60 | "y":"3" 61 | 62 | }, 63 | "h11": { 64 | 65 | "name":"Emo - Blonde", 66 | "x":"2", 67 | "y":"3" 68 | 69 | }, 70 | "h12": { 71 | 72 | "name":"Emo - Black", 73 | "x":"3", 74 | "y":"3" 75 | 76 | }, 77 | "h13": { 78 | 79 | "name":"Emo - Red", 80 | "x":"4", 81 | "y":"3" 82 | 83 | }, 84 | "h14": { 85 | 86 | "name":"Short - Brown", 87 | "x":"5", 88 | "y":"3" 89 | 90 | }, 91 | "h15": { 92 | 93 | "name":"Short - Blonde", 94 | "x":"6", 95 | "y":"3" 96 | 97 | }, 98 | "h16": { 99 | 100 | "name":"Short - Black", 101 | "x":"7", 102 | "y":"3" 103 | 104 | }, 105 | "h16": { 106 | 107 | "name":"Short - Red", 108 | "x":"8", 109 | "y":"3" 110 | 111 | }, 112 | "h17": { 113 | 114 | "name":"Ponytail - Brown", 115 | "x":"9", 116 | "y":"1" 117 | 118 | }, 119 | "h18": { 120 | 121 | "name":"Ponytail - Blonde", 122 | "x":"9", 123 | "y":"2" 124 | 125 | }, 126 | "h19": { 127 | 128 | "name":"Ponytail - Black", 129 | "x":"9", 130 | "y":"3" 131 | 132 | }, 133 | "h20": { 134 | 135 | "name":"Ponytail - Red", 136 | "x":"9", 137 | "y":"4" 138 | 139 | } 140 | 141 | }, 142 | "Pants": { 143 | 144 | "p1": { 145 | 146 | "name":"Jeans", 147 | "x":"1", 148 | "y":"2" 149 | 150 | }, 151 | "p2": { 152 | 153 | "name":"Pants - Black", 154 | "x":"2", 155 | "y":"2" 156 | 157 | } 158 | 159 | }, 160 | "Bottoms": { 161 | 162 | "s0": { 163 | 164 | "name":"No Skirt", 165 | "x":"0", 166 | "y":"0" 167 | 168 | }, 169 | "s1": { 170 | 171 | "name":"Skirt - Black with Pink Flowers", 172 | "x":"3", 173 | "y":"2" 174 | 175 | }, 176 | "s2": { 177 | 178 | "name":"Pencil Skirt - Grey", 179 | "x":"4", 180 | "y":"2" 181 | 182 | } 183 | 184 | }, 185 | "Tops": { 186 | 187 | "t1": { 188 | 189 | "name":"Hoodie - Grey", 190 | "x":"1", 191 | "y":"4" 192 | 193 | }, 194 | "t2": { 195 | 196 | "name":"Hoodie - Dark", 197 | "x":"2", 198 | "y":"4" 199 | 200 | }, 201 | "t3": { 202 | 203 | "name":"Jacket & T-Shirt - Dark", 204 | "x":"3", 205 | "y":"4" 206 | 207 | }, 208 | "t4": { 209 | 210 | "name":"Singlet - Black", 211 | "x":"4", 212 | "y":"4" 213 | 214 | }, 215 | "t5": { 216 | 217 | "name":"Long Sleeved - Black", 218 | "x":"5", 219 | "y":"4" 220 | 221 | }, 222 | "t6": { 223 | 224 | "name":"T Shirt - White", 225 | "x":"6", 226 | "y":"4" 227 | 228 | } 229 | 230 | }, 231 | "FacialHair": { 232 | 233 | "f0": { 234 | 235 | "name":"No Facial Hair", 236 | "x":"0", 237 | "y":"0" 238 | 239 | }, 240 | "f1": { 241 | 242 | "name":"Brown Beard", 243 | "x":"5", 244 | "y":"1" 245 | 246 | }, 247 | "f2": { 248 | 249 | "name":"Blonde Beard", 250 | "x":"6", 251 | "y":"1" 252 | 253 | }, 254 | "f3": { 255 | 256 | "name":"Black Beard", 257 | "x":"7", 258 | "y":"1" 259 | 260 | }, 261 | "f4": { 262 | 263 | "name":"Red Beard", 264 | "x":"8", 265 | "y":"1" 266 | 267 | } 268 | 269 | }, 270 | "Accessories": { 271 | 272 | "a0": { 273 | 274 | "name":"No Accessories", 275 | "x":"0", 276 | "y":"0" 277 | 278 | }, 279 | "a1": { 280 | 281 | "name":"Glasses", 282 | "x":"4", 283 | "y":"1" 284 | 285 | } 286 | 287 | }, 288 | "Shoes": { 289 | 290 | "s1": { 291 | 292 | "name":"Black Shoes", 293 | "x":"8", 294 | "y":"4" 295 | 296 | }, 297 | "s2": { 298 | 299 | "name":"White Shoes", 300 | "x":"7", 301 | "y":"4" 302 | 303 | }, 304 | "s3": { 305 | 306 | "name":"No Shoes", 307 | "x":"0", 308 | "y":"0" 309 | 310 | } 311 | 312 | } 313 | } -------------------------------------------------------------------------------- /inc/functions.php: -------------------------------------------------------------------------------- 1 | get_json_data_from_file( $datasrc ); 26 | $this->set_data( $data ); 27 | 28 | } 29 | 30 | 31 | 32 | 33 | 34 | /** 35 | * Return a JSON Decoded array from a file 36 | * 37 | * Retrieve the contents of a JSON file and return 38 | * a decoded version as a PHP array 39 | */ 40 | private function get_json_data_from_file( $datasrc ) { 41 | 42 | if ( file_exists( $datasrc ) ) { 43 | 44 | $data = file_get_contents( $datasrc ); 45 | return json_decode( $data, true ); 46 | 47 | } 48 | 49 | return false; 50 | 51 | } 52 | 53 | 54 | 55 | 56 | 57 | /** 58 | * Set the data var in the class 59 | */ 60 | private function set_data( $data ) { 61 | 62 | $this->data = $data; 63 | 64 | } 65 | 66 | 67 | 68 | 69 | 70 | /** 71 | * Return the main maker data 72 | */ 73 | public function get_data() { 74 | 75 | return $this->data; 76 | 77 | } 78 | 79 | 80 | 81 | 82 | 83 | /** 84 | * Render maker form 85 | */ 86 | public function render_form( $data = null ) { 87 | 88 | if ( empty( $data ) ) { 89 | 90 | $data = $this->get_data(); 91 | 92 | } 93 | 94 | echo '
'; 95 | 96 | foreach( $data as $legend => $fieldset ) { 97 | 98 | $this->render_fieldset( $legend, $fieldset ); 99 | 100 | } 101 | 102 | echo ''; 103 | 104 | echo '
'; 105 | 106 | } 107 | 108 | 109 | 110 | 111 | 112 | /** 113 | * Render a fieldset 114 | */ 115 | public function render_fieldset( $legend, $fieldset ) { 116 | 117 | echo '
'; 118 | 119 | echo '' . $legend . ''; 120 | 121 | $counter = 0; 122 | $rand = rand( 0, ( count( $fieldset ) - 1 ) ); 123 | 124 | if ( $legend == 'FacialHair' ) { 125 | 126 | $rand = 0; 127 | 128 | } 129 | 130 | foreach( $fieldset as $itemnum => $item ) { 131 | 132 | $selected = ''; 133 | 134 | if ( $counter == $rand ) { 135 | 136 | $selected = ' checked="checked"'; 137 | 138 | } 139 | 140 | $this->render_item( $item, $itemnum, $legend, $selected ); 141 | 142 | $counter++; 143 | 144 | } 145 | 146 | echo '
'; 147 | 148 | } 149 | 150 | 151 | 152 | 153 | /** 154 | * Shorten a classname to 2 characters 155 | */ 156 | public function shorten_css_class_name( $class ) { 157 | 158 | return substr( strtolower( $class ), 0, 2 ); 159 | 160 | } 161 | 162 | 163 | 164 | 165 | 166 | /** 167 | * Render a fieldset 168 | */ 169 | public function render_item( $item, $itemnum, $legend, $selected ) { 170 | 171 | $type = $this->shorten_css_class_name( $legend ); 172 | 173 | echo ''; 174 | echo ''; 175 | 176 | } 177 | 178 | 179 | 180 | 181 | /** 182 | * Render a fieldset 183 | */ 184 | public function get_item_choices() { 185 | 186 | $data = $this->data; 187 | $items = array(); 188 | 189 | $skintone = $this->verify_item_choice( 'Skintones', $_POST[ 'sk' ], $data ); 190 | if ( $skintone ) { $items[ 'sk' ] = $skintone; } 191 | 192 | $hair = $this->verify_item_choice( 'Hairstyles', $_POST[ 'ha' ], $data ); 193 | if ( $hair ) { $items[ 'ha' ] = $hair; } 194 | 195 | $pants = $this->verify_item_choice( 'Pants', $_POST[ 'pa' ], $data ); 196 | if ( $pants ) { $items[ 'pa' ] = $pants; } 197 | 198 | $bottoms = $this->verify_item_choice( 'Bottoms', $_POST[ 'bo' ], $data ); 199 | if ( $bottoms ) { $items[ 'bo' ] = $bottoms; } 200 | 201 | $tops = $this->verify_item_choice( 'Tops', $_POST[ 'to' ], $data ); 202 | if ( $tops ) { $items[ 'to' ] = $tops; } 203 | 204 | $face = $this->verify_item_choice( 'FacialHair', $_POST[ 'fa' ], $data ); 205 | if ( $face ) { $items[ 'fa' ] = $face; } 206 | 207 | $accessories = $this->verify_item_choice( 'Accessories', $_POST[ 'ac' ], $data ); 208 | if ( $accessories ) { $items[ 'ac' ] = $accessories; } 209 | 210 | $shoes = $this->verify_item_choice( 'Shoes', $_POST[ 'sh' ], $data ); 211 | if ( $shoes ) { $items[ 'sh' ] = $shoes; } 212 | 213 | return $items; 214 | 215 | } 216 | 217 | 218 | 219 | 220 | 221 | /** 222 | * Return the sprite sheet image 223 | */ 224 | public function get_sprite_sheet_image() { 225 | 226 | return 'assets/img/sprite-sheet-01.png'; 227 | 228 | } 229 | 230 | 231 | 232 | 233 | 234 | /** 235 | * Verify the item choice exists 236 | */ 237 | public function verify_item_choice( $type, $choice, $data ) { 238 | 239 | $key = $this->shorten_css_class_name( $type ); 240 | $item = false; 241 | 242 | if ( isset( $_POST[ $key ] ) && isset( $data[ $type ][ $_POST[ $key ] ] ) ) { 243 | 244 | if ( $data[ $type ][ $_POST[ $key ] ][ 'x' ] > 0 ) { 245 | 246 | $item = array( $data[ $type ][ $_POST[ $key ] ][ 'x' ], $data[ $type ][ $_POST[ $key ] ][ 'y' ] ); 247 | 248 | } 249 | 250 | } 251 | 252 | return $item; 253 | 254 | } 255 | 256 | 257 | 258 | 259 | /** 260 | * Create the image 261 | */ 262 | public function create_image( $items ) { 263 | 264 | // Create the base img 265 | $img = imagecreatetruecolor( $this->sprite_width, $this->sprite_height ); 266 | $green = imagecolorallocate( $img, 0, 255, 0 ); 267 | 268 | // Fill w/ obnoxious green, then make transparent 269 | imagefill( $img, 0, 0, $green ); 270 | imagecolortransparent( $img, $green ); 271 | 272 | // Check for items 273 | if ( is_array( $items ) ) { 274 | 275 | // Loop through items 276 | foreach( $items as $key => $item ) { 277 | 278 | // Create image instances 279 | $src = imagecreatefrompng( $this->get_sprite_sheet_image() ); 280 | 281 | // Copy and merge 282 | imagecopyresampled( $img, $src, 0, 0, ( ( $item[ 0 ] - 1 ) * $this->sprite_width ), ( ( $item[ 1 ] - 1 ) * $this->sprite_height ), $this->sprite_width, $this->sprite_height, $this->sprite_width, $this->sprite_height ); 283 | 284 | } 285 | 286 | ob_start(); 287 | 288 | imagepng( $img ); 289 | $imgdata = ob_get_contents(); 290 | 291 | ob_end_clean(); 292 | 293 | imagedestroy( $img ); 294 | imagedestroy( $src ); 295 | 296 | $dataUri = "data:image/png;base64," . base64_encode( $imgdata ); 297 | 298 | return $dataUri; 299 | 300 | } 301 | 302 | return false; 303 | 304 | } 305 | 306 | 307 | } -------------------------------------------------------------------------------- /assets/css/style.css: -------------------------------------------------------------------------------- 1 | body{-webkit-animation:a infinite 1s}@-webkit-keyframes a{0%{padding:0}to{padding:0}}html{box-sizing:border-box;overflow:auto;overflow-x:hidden}*,:after,:before{box-sizing:inherit}body,html,main,section{min-height:100vh}body{background-color:#bae6cd;color:#fff;font-family:Verdana,sans-serif;font-size:.6em;margin:0;padding:0;text-align:center}a{color:currentColor}legend{color:#fff!important;margin-bottom:.25em}fieldset{border:none;display:inline-block;padding:0;margin-bottom:1em}label,label:after,label:before{display:inline-block;-webkit-transition:-webkit-transform .2s ease;transition:transform .2s ease}input+label:after,input+label:before{content:""}input{opacity:0;position:absolute}input:checked+label:after,label:before{background:url(../img/sprite-sheet-01.png) no-repeat 0 0/576px 544px;height:136px;width:64px;-ms-interpolation-mode:nearest-neighbor;image-rendering:-webkit-optimize-contrast;image-rendering:-webkit-crisp-edges;image-rendering:-moz-crisp-edges;image-rendering:-o-crisp-edges;image-rendering:pixelated}label{height:68px;overflow:hidden;width:44px;text-align:center;margin:.25em;background-color:hsla(0,0%,100%,.2)}label:hover{background-color:hsla(0,0%,100%,.4)}input:checked+label{background-color:hsla(0,0%,100%,.6)}input:checked+label:after{left:50%;margin-left:-32px;pointer-events:none;position:absolute;top:0}label:before{-webkit-transform:scale(.5) translate(-50%,-50%);-ms-transform:scale(.5) translate(-50%,-50%);transform:scale(.5) translate(-50%,-50%);margin-left:6px}#sk-li+label:before,#sk-li:checked+label:after{background-position:0 0}#sk-me+label:before,#sk-me:checked+label:after{background-position:-64px 0}#sk-da+label:before,#sk-da:checked+label:after{background-position:-128px 0}#ha-h6+label:before,#ha-h6:checked+label:after{background-position:-256px -136px}#ha-h7+label:before,#ha-h7:checked+label:after{background-position:-320px -136px}#ha-h8+label:before,#ha-h8:checked+label:after{background-position:-384px -136px}#ha-h9+label:before,#ha-h9:checked+label:after{background-position:-448px -136px}#ha-h10+label:before,#ha-h10:checked+label:after{background-position:0 -272px}#ha-h11+label:before,#ha-h11:checked+label:after{background-position:-64px -272px}#ha-h12+label:before,#ha-h12:checked+label:after{background-position:-128px -272px}#ha-h13+label:before,#ha-h13:checked+label:after{background-position:-192px -272px}#ha-h14+label:before,#ha-h14:checked+label:after{background-position:-256px -272px}#ha-h15+label:before,#ha-h15:checked+label:after{background-position:-320px -272px}#ha-h16+label:before,#ha-h16:checked+label:after{background-position:-448px -272px}#ha-h17+label:before,#ha-h17:checked+label:after{background-position:-512px 0}#ha-h18+label:before,#ha-h18:checked+label:after{background-position:-512px -136px}#ha-h19+label:before,#ha-h19:checked+label:after{background-position:-512px -272px}#ha-h20+label:before,#ha-h20:checked+label:after{background-position:-512px -408px}#to-t1+label:before,#to-t1:checked+label:after{background-position:0 -408px}#to-t2+label:before,#to-t2:checked+label:after{background-position:-64px -408px}#to-t3+label:before,#to-t3:checked+label:after{background-position:-128px -408px}#to-t4+label:before,#to-t4:checked+label:after{background-position:-192px -408px}#to-t5+label:before,#to-t5:checked+label:after{background-position:-256px -408px}#to-t6+label:before,#to-t6:checked+label:after{background-position:-320px -408px}#pa-p1+label:before,#pa-p1:checked+label:after{background-position:0 -136px}#pa-p2+label:before,#pa-p2:checked+label:after{background-position:-64px -136px}#bo-s0+label:before,#bo-s0:checked+label:after{background-position:64px 136px}#bo-s1+label:before,#bo-s1:checked+label:after{background-position:-128px -136px}#bo-s2+label:before,#bo-s2:checked+label:after{background-position:-192px -136px}#ac-a0+label:before,#ac-a0:checked+label:after{background-position:64px 136px}#ac-a1+label:before,#ac-a1:checked+label:after{background-position:-192px 0}#fa-f0+label:before,#fa-f0:checked+label:after{background-position:64px 136px}#fa-f1+label:before,#fa-f1:checked+label:after{background-position:-256px 0}#fa-f2+label:before,#fa-f2:checked+label:after{background-position:-320px 0}#fa-f3+label:before,#fa-f3:checked+label:after{background-position:-384px 0}#fa-f4+label:before,#fa-f4:checked+label:after{background-position:-448px 0}#sh-s1+label:before,#sh-s1:checked+label:after{background-position:-448px -408px}#sh-s2+label:before,#sh-s2:checked+label:after{background-position:-384px -408px}#sh-s3+label:before,#sh-s3:checked+label:after{background-position:64px 136px}section{padding:3em 2em}.sc{width:100%}@media (min-width:500px){body{font-size:1em}fieldset{text-align:left}}.t-u{text-transform:uppercase}.t-tn{font-weight:600;letter-spacing:.01em}.btn{background-color:#deac6c;border-radius:5em;border:none;color:#fff;display:inline-block;font-size:1em;outline:none;padding:1em 1.5em;text-decoration:none}.btn:hover{background-color:#d9a057}#btn-s{left:50%;position:absolute;top:151px;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%)}#create{position:relative}#final-img:before,form:before{background-color:#95cecb;border-radius:50%;content:"";display:inline-block;height:10px;left:50%;margin-left:-25.6px;position:absolute;top:126px;width:51.2px;z-index:-1}form{padding-top:216px}.t-s{text-shadow:-.075em .05em 0 #95cecb}h1{color:#fff;font-size:3.5em;margin:0}h1 span{display:block;font-weight:400;font-size:.5em}.wrap{max-width:1170px;position:relative;width:100%}.deco,.wrap{display:inline-block}.deco{border:2px solid #fff;margin-bottom:2em;margin-top:-2.5em;padding:2em 2.75em 0}.deco .o-b{margin-bottom:-1.5em}.gr{background:-webkit-linear-gradient(top,rgba(149,206,203,.65),rgba(149,206,203,0));background:linear-gradient(180deg,rgba(149,206,203,.65) 0,rgba(149,206,203,0));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#a695cecb',endColorstr='#0095cecb',GradientType=0)}section{width:100%}#splash{height:100vh}@media (min-width:600px){#splash:after,#splash:before{background-image:url(../img/hero.png);background-repeat:no-repeat;content:"";display:inline-block;height:571px;margin-top:-235px;position:absolute;top:45%;width:430px}#splash:before{background-position:0;left:50%;margin-left:-40em}#splash:after{background-position:100%;right:50%;margin-right:-40em}}section{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}[name~=fa]+label:after,[name~=ha]+label:after,[name~=to]+label:after{opacity:0;-webkit-transform:translateY(-1%);-ms-transform:translateY(-1%);transform:translateY(-1%)}[name~=fa]:checked+label:after,[name~=ha]:checked+label:after,[name~=to]:checked+label:after{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}[name~=ac]+label:after,[name~=bo]+label:after,[name~=pa]+label:after{opacity:0;-webkit-transform:translateY(1%);-ms-transform:translateY(1%);transform:translateY(1%)}[name~=ac]:checked+label:after,[name~=bo]:checked+label:after,[name~=pa]:checked+label:after{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}#h-save{max-width:12em;margin-left:auto;margin-right:auto}footer{background-color:#95cecb;bottom:0;left:0;padding:1em;position:fixed;width:100%;font-size:.8em}#final-img{display:inline-block;margin:1em;position:relative} -------------------------------------------------------------------------------- /assets/scss/style.scss: -------------------------------------------------------------------------------- 1 | // Vars 2 | @import 'inc/base-maker-data-vars'; 3 | @import 'inc/vars'; 4 | 5 | // Tools 6 | @import 'inc/tools'; 7 | 8 | 9 | // Bugfix for android :| 10 | body { -webkit-animation: bugfix infinite 1s; } 11 | @-webkit-keyframes bugfix { from { padding:0; } to { padding:0; } } 12 | 13 | 14 | html { 15 | box-sizing: border-box; 16 | overflow: auto; 17 | overflow-x: hidden; 18 | } 19 | *, *:before, *:after { 20 | box-sizing: inherit; 21 | } 22 | 23 | 24 | html, 25 | body, 26 | section, 27 | main { 28 | 29 | min-height: 100vh; 30 | 31 | } 32 | 33 | 34 | body { 35 | 36 | background-color: $pm-color--secondary; 37 | color: #fff; 38 | font-family: $pm-typeface--primary; 39 | font-size: .6em; 40 | margin: 0; 41 | padding: 0; 42 | text-align: center; 43 | 44 | } 45 | 46 | 47 | a { 48 | 49 | color: currentColor; 50 | 51 | } 52 | 53 | 54 | legend { 55 | 56 | color: #fff !important; 57 | margin-bottom: .25em; 58 | 59 | } 60 | 61 | 62 | fieldset { 63 | 64 | border: none; 65 | display: inline-block; 66 | padding: 0; 67 | margin-bottom: 1em; 68 | 69 | } 70 | 71 | 72 | label, 73 | label::before, 74 | label::after { 75 | 76 | display: inline-block; 77 | transition: transform .2s ease; 78 | 79 | } 80 | 81 | 82 | input + label::before, 83 | input + label::after { 84 | 85 | content: ""; 86 | 87 | } 88 | 89 | 90 | input { 91 | 92 | opacity: 0; 93 | position: absolute; 94 | 95 | } 96 | 97 | 98 | /* Ensure the image background is set */ 99 | label::before, 100 | input:checked + label::after { 101 | 102 | background: url( '../img/sprite-sheet-01.png' ) no-repeat 0 0/576px 544px; 103 | height: $pm-sprite-item--height; 104 | width: $pm-sprite-item--width; 105 | -ms-interpolation-mode: nearest-neighbor; 106 | image-rendering: -webkit-optimize-contrast; 107 | image-rendering: -webkit-crisp-edges; 108 | image-rendering: -moz-crisp-edges; 109 | image-rendering: -o-crisp-edges; 110 | image-rendering: pixelated; 111 | 112 | } 113 | 114 | 115 | label { 116 | 117 | height: ( $pm-sprite-item--height / 2 ); 118 | overflow: hidden; 119 | width: 44px; 120 | text-align: center; 121 | margin: .25em; 122 | background-color: rgba( 255, 255, 255, .2 ); 123 | 124 | } 125 | 126 | 127 | label:hover { 128 | 129 | background-color: rgba( 255, 255, 255, .4 ); 130 | 131 | } 132 | 133 | 134 | input:checked + label { 135 | 136 | background-color: rgba( 255, 255, 255, .6 ); 137 | 138 | } 139 | 140 | 141 | /* Set the positioning */ 142 | input:checked + label::after { 143 | 144 | left: 50%; 145 | margin-left: -( $pm-sprite-item--width / 2 ); 146 | pointer-events: none; 147 | position: absolute; 148 | top: 0; 149 | 150 | } 151 | 152 | 153 | label::before { 154 | 155 | transform: scale( .5 ) translate( -50%, -50% ); 156 | margin-left: 6px; 157 | 158 | } 159 | 160 | 161 | 162 | /* Skin Tones */ 163 | @each $item, $map in $Skintones { 164 | 165 | $id: #sk-#{ $item }; 166 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 167 | 168 | } 169 | 170 | 171 | 172 | /* Hairstyles */ 173 | @each $item, $map in $Hairstyles { 174 | 175 | $id: #ha-#{ $item }; 176 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 177 | 178 | } 179 | 180 | 181 | 182 | /* Tops */ 183 | @each $item, $map in $Tops { 184 | 185 | $id: #to-#{ $item }; 186 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 187 | 188 | } 189 | 190 | 191 | 192 | /* Pants */ 193 | @each $item, $map in $Pants { 194 | 195 | $id: #pa-#{ $item }; 196 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 197 | 198 | } 199 | 200 | 201 | /* Bottoms */ 202 | @each $item, $map in $Bottoms { 203 | 204 | $id: #bo-#{ $item }; 205 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 206 | 207 | } 208 | 209 | 210 | 211 | /* Accessories */ 212 | @each $item, $map in $Accessories { 213 | 214 | $id: #ac-#{ $item }; 215 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 216 | 217 | } 218 | 219 | 220 | /* FacialHair */ 221 | @each $item, $map in $FacialHair { 222 | 223 | $id: #fa-#{ $item }; 224 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 225 | 226 | } 227 | 228 | 229 | 230 | /* Shoes */ 231 | @each $item, $map in $Shoes { 232 | 233 | $id: #sh-#{ $item }; 234 | @include pm-sprite-map-element( $id, map-get( $map, x ), map-get( $map, y ) ); 235 | 236 | } 237 | 238 | 239 | 240 | section { 241 | 242 | padding: 3em 2em; 243 | 244 | } 245 | 246 | 247 | 248 | // Sections 249 | .sc { 250 | 251 | width: 100%; 252 | 253 | } 254 | 255 | 256 | @media ( min-width: 500px ) { 257 | 258 | body { 259 | 260 | font-size: 1em; 261 | 262 | } 263 | 264 | fieldset { 265 | 266 | text-align: left; 267 | 268 | } 269 | 270 | } 271 | 272 | 273 | .t-u { 274 | 275 | text-transform: uppercase; 276 | 277 | } 278 | 279 | 280 | .t-tn { 281 | 282 | font-weight: 600; 283 | letter-spacing: .01em; 284 | 285 | } 286 | 287 | 288 | .btn { 289 | 290 | background-color: $pm-color--tertiary; 291 | border-radius: 5em; 292 | border: none; 293 | color: #fff; 294 | display: inline-block; 295 | font-size: 1em; 296 | outline: none; 297 | padding: 1em 1.5em; 298 | text-decoration: none; 299 | 300 | &:hover { 301 | 302 | background-color: darken( $pm-color--tertiary, 5 ); 303 | 304 | } 305 | 306 | } 307 | 308 | 309 | #btn-s { 310 | 311 | left: 50%; 312 | position: absolute; 313 | top: ( $pm-sprite-item--height + 15px ); 314 | transform: translateX( -50% ); 315 | 316 | } 317 | 318 | 319 | 320 | #create { 321 | 322 | position: relative; 323 | 324 | } 325 | 326 | 327 | // Decorative shadow 328 | form:before, 329 | #final-img:before { 330 | 331 | background-color: $pm-color--secondary-dark; 332 | border-radius: 50%; 333 | content: ""; 334 | display: inline-block; 335 | height: 10px; 336 | left: 50%; 337 | margin-left: -( ( $pm-sprite-item--width * .4 ) ); 338 | position: absolute; 339 | top: ( $pm-sprite-item--height - 10px ); 340 | width: ( $pm-sprite-item--width * .8 ); 341 | z-index: -1; 342 | 343 | } 344 | 345 | 346 | 347 | 348 | form { 349 | 350 | padding-top: ( $pm-sprite-item--height + 80px ); 351 | 352 | } 353 | 354 | 355 | .t-s { 356 | 357 | text-shadow: -.075em .05em 0px $pm-color--secondary-dark; 358 | 359 | } 360 | 361 | 362 | 363 | h1 { 364 | 365 | color: #fff; 366 | font-size: 3.5em; 367 | margin: 0; 368 | 369 | span { 370 | 371 | display: block; 372 | font-weight: 400; 373 | font-size: .5em; 374 | 375 | } 376 | 377 | } 378 | 379 | 380 | 381 | .wrap { 382 | 383 | display: inline-block; 384 | max-width: 1170px; 385 | position: relative; 386 | width: 100%; 387 | 388 | } 389 | 390 | 391 | 392 | .deco { 393 | 394 | border: 2px solid #fff; 395 | display: inline-block; 396 | margin-bottom: 2em; 397 | margin-top: -2.5em; 398 | padding: 2em 2.75em 0 2.75em; 399 | 400 | .o-b { 401 | 402 | margin-bottom: -1.5em; 403 | 404 | } 405 | 406 | } 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | .gr { 420 | 421 | background: -moz-linear-gradient(top, rgba( $pm-color--secondary-dark, 0.65) 0%, rgba($pm-color--secondary-dark,0) 100%); /* FF3.6-15 */ 422 | background: -webkit-linear-gradient(top, rgba($pm-color--secondary-dark,0.65) 0%,rgba($pm-color--secondary-dark,0) 100%); /* Chrome10-25,Safari5.1-6 */ 423 | background: linear-gradient(to bottom, rgba($pm-color--secondary-dark,0.65) 0%,rgba($pm-color--secondary-dark,0) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ 424 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a695cecb', endColorstr='#0095cecb',GradientType=0 ); /* IE6-9 */ 425 | 426 | } 427 | 428 | 429 | section { 430 | 431 | width: 100%; 432 | 433 | } 434 | 435 | 436 | #splash { 437 | 438 | height: 100vh; 439 | 440 | @media ( min-width: 600px ) { 441 | 442 | &:before, 443 | &:after { 444 | 445 | background-image: url( '../img/hero.png' ); 446 | background-repeat: no-repeat; 447 | content: ""; 448 | display: inline-block; 449 | height: 571px; 450 | margin-top: -235px; 451 | position: absolute; 452 | top: 45%; 453 | width: 430px; 454 | 455 | } 456 | 457 | &:before { 458 | 459 | background-position: left center; 460 | left: 50%; 461 | margin-left: -40em; 462 | 463 | } 464 | 465 | &:after { 466 | 467 | background-position: right center; 468 | right: 50%; 469 | margin-right: -40em; 470 | 471 | } 472 | 473 | } 474 | 475 | } 476 | 477 | 478 | 479 | section { 480 | 481 | display: flex; 482 | align-items: center; 483 | justify-content: center; 484 | 485 | } 486 | 487 | 488 | 489 | [name~="ha"], 490 | [name~="to"], 491 | [name~="fa"] { 492 | 493 | + label::after { 494 | 495 | opacity: 0; 496 | transform: translateY( -1% ); 497 | 498 | } 499 | 500 | &:checked + label::after { 501 | 502 | opacity: 1; 503 | transform: translateY( 0 ); 504 | 505 | } 506 | 507 | } 508 | 509 | 510 | 511 | [name~="pa"], 512 | [name~="bo"], 513 | [name~="ac"] { 514 | 515 | + label::after { 516 | 517 | opacity: 0; 518 | transform: translateY( 1% ); 519 | 520 | } 521 | 522 | &:checked + label::after { 523 | 524 | opacity: 1; 525 | transform: translateY( 0 ); 526 | 527 | } 528 | 529 | } 530 | 531 | 532 | #h-save { 533 | 534 | max-width: 12em; 535 | margin-left: auto; 536 | margin-right: auto; 537 | 538 | } 539 | 540 | 541 | 542 | footer { 543 | 544 | background-color: $pm-color--secondary-dark; 545 | bottom: 0; 546 | left: 0; 547 | padding: 1em; 548 | position: fixed; 549 | width: 100%; 550 | font-size: .8em; 551 | 552 | } 553 | 554 | 555 | 556 | #final-img { 557 | 558 | display: inline-block; 559 | margin: 1em; 560 | position: relative; 561 | 562 | } --------------------------------------------------------------------------------