├── readme.md ├── gulpfile.js ├── package.json ├── LICENSE ├── js └── app.js ├── index.html └── scss └── app.scss /readme.md: -------------------------------------------------------------------------------- 1 | # Emoji Cursor 2 | 3 | ## Public version 4 | 5 | You can use the public version of this site here: 6 | 7 | https://www.emojicursor.app/ 8 | 9 | ## Installation 10 | 11 | ```bash 12 | git clone https://github.com/kylekelly/emoji-cursor 13 | cd emoji-cursor 14 | npm install 15 | npm run start 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var $ = require('gulp-load-plugins')(); 3 | 4 | var sassPaths = [ 5 | ]; 6 | 7 | gulp.task('sass', function() { 8 | return gulp.src('scss/app.scss') 9 | .pipe($.sass({ 10 | includePaths: sassPaths, 11 | outputStyle: 'compressed' // if css compressed **file size** 12 | }) 13 | .on('error', $.sass.logError)) 14 | .pipe($.autoprefixer({ 15 | browsers: ['> 0.25%', 'ie >= 9'] 16 | })) 17 | .pipe(gulp.dest('css')); 18 | }); 19 | 20 | gulp.task('default', ['sass'], function() { 21 | gulp.watch(['scss/**/*.scss'], ['sass']); 22 | }); 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "emoji-cursor", 3 | "version": "1.0.0", 4 | "description": "Create cursors from emojis", 5 | "main": "gulpfile.js", 6 | "scripts": { 7 | "start": "gulp", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "devDependencies": { 11 | "gulp": "^3.9.0", 12 | "gulp-autoprefixer": "^3.1.0", 13 | "gulp-load-plugins": "^1.1.0", 14 | "gulp-sass": "^2.1.0" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/kylekelly/emoji-cursor.git" 19 | }, 20 | "author": "Kyle Kelly ", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/kylekelly/emoji-cursor/issues" 24 | }, 25 | "homepage": "https://github.com/kylekelly/emoji-cursor" 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 kylekelly 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 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | //Generate png favicon from Emoji - source:https://koddsson.com/posts/emoji-favicon/ 2 | const favicon = document.querySelector("link[rel=icon]"); 3 | 4 | if (favicon) { 5 | const emoji = favicon.getAttribute("data-emoji"); 6 | 7 | if (emoji) { 8 | const canvas = document.createElement("canvas"); 9 | canvas.height = 64; 10 | canvas.width = 64; 11 | 12 | const ctx = canvas.getContext("2d"); 13 | ctx.font = "64px serif"; 14 | ctx.fillText(emoji, 0, 64); 15 | 16 | favicon.href = canvas.toDataURL(); 17 | } 18 | } 19 | 20 | //Vue.JS app controls Emoji Cursor form and output. 21 | var app = new Vue({ 22 | el: '#app', 23 | data: { 24 | message: 'Hello Vue', 25 | selectedEmoji: '😀', 26 | emojis: [ 27 | '😀', 28 | '👍', 29 | '🤔', 30 | '👉', 31 | '🙌', 32 | '‍😱', 33 | '❗', 34 | '❤️', 35 | '💩', 36 | '🤖', 37 | '👨‍💻', 38 | '‍👩🏻‍💻', 39 | '🔥', 40 | '🍀', 41 | '‍🌎', 42 | '🌈', 43 | '💦', 44 | '🍺', 45 | '🥊', 46 | '🌟', 47 | '🎮', 48 | '🏁', 49 | '💵', 50 | '💯', 51 | '🇨🇦', 52 | '🚀' 53 | ], 54 | range: 40 55 | }, 56 | computed: { 57 | css: function() { 58 | let font_size = (this.range * 0.6).toFixed(0); 59 | let width = this.range; 60 | let height = (this.range * 1.2).toFixed(0); 61 | let y = (this.range * 1.1).toFixed(0); 62 | let css_string = `url("data:image/svg+xml;utf8,${this.selectedEmoji}") 16 0,auto`; 63 | return css_string 64 | }, 65 | cssCursor: function() { 66 | return 'cursor:'+this.css+';'; 67 | }, 68 | styleObject: function() { 69 | return { 70 | cursor: this.css 71 | } 72 | } 73 | }, 74 | methods: { 75 | copyCss: function (event) { 76 | var tester = document.querySelector('.preview__tester'); 77 | tester.focus(); 78 | tester.select(); 79 | try { 80 | var success = document.execCommand('copy'); 81 | var message = success ? 'yes' : 'no'; 82 | console.log('CSS copied to clipboard: ' + message); 83 | } catch (err) { 84 | console.log('Unable to copy', err); 85 | } 86 | } 87 | } 88 | }); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Emoji Cursor 8 | 9 | 10 | 11 | 12 | 13 |
14 |

Emoji Cursor

15 |
16 |

Steps:

17 |
    18 |
  1. Choose your preferred emoji from the list below or provide your own.
  2. 19 |
  3. Adjust the size.
  4. 20 |
  5. Hover over the preview box to see the result.
  6. 21 |
  7. Copy the CSS and place it in your website stylesheet.
  8. 22 |
23 |
24 |
25 |
26 |

Options

27 |
28 | 29 | 30 | {{ range }} 31 |
Above 50 can cause blurriness and browser glitches.
32 |
33 |
    34 |
  • 35 | 36 | 37 |
  • 38 |
  • 39 | 40 | 41 |
  • 42 |
43 |
44 |
45 |

Hover to Preview

46 | 47 | 48 |
49 |
50 |
51 | 52 |
53 |

Notes:

54 | 63 |
64 |
65 |

Made by Kyle (, ).

66 |

Source on github.

67 |

Feel free to buy me a coffee.

68 |
69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /scss/app.scss: -------------------------------------------------------------------------------- 1 | @charset 'utf-8'; 2 | 3 | body { 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 5 | padding:0rem 3rem 3rem 3rem; 6 | } 7 | 8 | h1 { 9 | cursor:url("data:image/svg+xml;utf8,🚀") 16 0,auto; 10 | } 11 | 12 | h1, h2, h3, h4 { 13 | color: #000000; 14 | } 15 | 16 | a { 17 | &:hover { 18 | text-decoration: none; 19 | } 20 | } 21 | 22 | ol, ul { 23 | line-height: 1.5; 24 | margin: 0; 25 | padding:0 ; 26 | list-style-position: inside; 27 | } 28 | 29 | 30 | 31 | .form { 32 | margin:2rem 0; 33 | display:flex; 34 | flex-wrap:wrap; 35 | //background: #fdfdfd; 36 | //background: #e6e6e6; 37 | @media screen and (min-width:900px) { 38 | display:grid; 39 | //padding: 2rem; 40 | grid-template-columns: 300px 1fr; 41 | } 42 | } 43 | 44 | .controls { 45 | display:flex; 46 | flex-direction: column; 47 | margin-right:2rem; 48 | max-height: 600px; 49 | overflow-y: scroll; 50 | &__range-warning { 51 | color:orangered; 52 | visibility: hidden; 53 | font-size:0.8rem; 54 | padding:0.5rem 0; 55 | &.show { 56 | visibility: visible; 57 | } 58 | } 59 | } 60 | 61 | .list { 62 | list-style-type: none; 63 | margin:0; 64 | padding:0; 65 | display:flex; 66 | display:grid; 67 | grid-template-columns: repeat(2, 1fr); 68 | font-size:1.3rem; 69 | &__custom { 70 | input { 71 | font-size:1.3rem; 72 | width:25px; 73 | } 74 | } 75 | &__label_custom { 76 | font-size:1rem; 77 | } 78 | } 79 | 80 | .preview { 81 | max-width:calc(100% - 5rem); 82 | position: relative; 83 | &__tester { 84 | background-color:#eeeeee; 85 | padding:2rem; 86 | width:400px; 87 | max-width:100%; 88 | height:400px; 89 | font-size:0.85rem; 90 | border:0; 91 | } 92 | &__copy { 93 | padding:1rem; 94 | background:white; 95 | border:0; 96 | position: absolute; 97 | left: 0; 98 | width: 100px; 99 | bottom: 0; 100 | @media screen and (min-width:900px) { 101 | bottom: 36px; 102 | } 103 | &:hover { 104 | text-decoration: underline; 105 | cursor: pointer; 106 | } 107 | } 108 | } 109 | 110 | .icon { 111 | &__twitter { 112 | //cursor:url("data:image/svg+xml;utf8,🐦") 16 0,auto; 113 | cursor:url("data:image/svg+xml;utf8,🐦") 16 0,auto; 114 | } 115 | &__email { 116 | cursor:url("data:image/svg+xml;utf8,📧") 16 0,auto; 117 | } 118 | &__coffee { 119 | cursor:url("data:image/svg+xml;utf8,") 16 0,auto; 120 | } 121 | &__pi { 122 | cursor:url("data:image/svg+xml;utf8,π") 16 0,auto; 123 | } 124 | &__github { 125 | cursor:url("data:image/svg+xml;utf8,🔧") 16 0,auto; 126 | } 127 | &__fox { 128 | cursor:url("data:image/svg+xml;utf8,🔥🦊") 30 0,auto; 129 | } 130 | } 131 | --------------------------------------------------------------------------------