├── LICENSE
├── README.md
├── app.html
├── assets
├── css
│ ├── landing.css
│ └── style.css
├── imgs
│ ├── browser.png
│ ├── demos
│ │ ├── craftworks.gif
│ │ ├── craftworks.png
│ │ ├── dribbble.gif
│ │ ├── dribbble.png
│ │ ├── notion.gif
│ │ ├── notion.png
│ │ ├── slack.gif
│ │ └── slack.png
│ ├── easy.png
│ ├── editor.png
│ └── xsullo.webp
└── js
│ └── main.js
├── demo.gif
├── index.html
└── robots.txt
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flashy
2 |
3 |
4 | Flashy is a web-based tool that can help you cycle through images while adding text to them.
5 |
6 |
7 |
8 |
9 | ## Features
10 | 🖼️ No file uploads everything runs in your browser
11 | 🪄 Add and edit text on each frame with drag to adjust it's position
12 | ⏱ Set framerate for each image
13 | ...more coming soon
14 |
15 | Feel free to reach out on [Twitter](https://twitter.com/alemalohe) if you have any questions or feedback
16 |
--------------------------------------------------------------------------------
/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | App
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
49 |
50 |
51 |
52 |
53 |
54 |
57 |
58 |
61 | @xsullo
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | FlashyVersion 2.0
91 |
92 |
93 |
94 |
116 |
117 |
118 |
119 | Add image from URL
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | Add images
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
Images
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
166 |
Made with ❤️ by Alohe
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
179 |
180 | Content
181 |
182 |
183 |
184 |
185 |
186 |
187 | Font size
188 |
189 |
190 |
191 |
192 | Font Weight
193 |
194 | 100
195 | 200
196 | 300
197 | 400
198 | 500
199 | 600
200 | 700
201 | 800
202 | 900
203 |
204 |
205 |
206 |
207 | Color
208 |
209 |
210 |
211 |
212 | Shadow
213 |
214 |
215 |
216 |
217 |
218 |
219 |
Align
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 | Shadow Value
229 |
231 |
232 |
233 |
234 |
235 |
236 |
Delay
237 |
238 |
ms
239 |
240 |
241 |
248 |
249 |
250 |
Delete Image
251 |
252 |
253 |
254 |
255 |
256 |
259 |
260 |
261 |
262 |
--------------------------------------------------------------------------------
/assets/css/landing.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --green: #00bc87;
3 | --light-green: #bdffe9;
4 | --blue: #00c2ee;
5 | --light-blue: #c0f6ff;
6 | --yellow: #ffa800;
7 | --light-yellow: #ffe7bd;
8 | --red: #d00090;
9 | --light-red: #ffbdee;
10 | --orange: #e74c3c;
11 | --light-orange: #ffc0bd;
12 | --purple: #5849b5;
13 | --purple-light: #dfdaff;
14 | --primary: #282828;
15 | --secondary: #333333;
16 | --light-0: #fafafa;
17 | --light-1: #f3f3f4;
18 | --light-2: #e6e6e6;
19 | --light-3: #585858;
20 | --light-4: #b9b9b9;
21 | --pink: #ea4c89;
22 | --pink-light: #ffe6ef;
23 | }
24 | button:focus {
25 | outline: 0;
26 | }
27 | body,
28 | html {
29 | font-family: Inter;
30 | overflow-x: hidden;
31 | }
32 | a {
33 | color: var(--dark);
34 | text-decoration: none;
35 | }
36 | a:hover {
37 | color: var(--light-3);
38 | text-decoration: none;
39 | }
40 | p {
41 | margin: 0;
42 | }
43 | .t-purple {
44 | color: var(--purple);
45 | }
46 | .t-pink {
47 | color: var(--pink);
48 | }
49 | .badge {
50 | font-size: 11px;
51 | font-weight: 500;
52 | background: var(--pink);
53 | color: #fff;
54 | }
55 | .logo {
56 | font-family: Poppins;
57 | font-size: 30px;
58 | padding-top: 20px;
59 | font-weight: 800;
60 | }
61 | .main-mt {
62 | margin-top: 15vh;
63 | }
64 | .logo img {
65 | margin-top: -5px;
66 | margin-left: 0;
67 | }
68 | .main {
69 | margin-top: 150px;
70 | }
71 | .main .title {
72 | font-weight: 900;
73 | font-family: "Inter";
74 | font-size: 50px;
75 | line-height: 50px;
76 | text-transform: capitalize;
77 | }
78 | .main .desc {
79 | font-family: "Inter";
80 | font-size: 19px;
81 | margin-bottom: 20px;
82 | color: var(--light-3);
83 | }
84 | .pop {
85 | margin-left: -10px;
86 | margin-top: 0;
87 | width: 60px;
88 | position: absolute;
89 | z-index: -1;
90 | }
91 | .pulse {
92 | animation: pulse 3s infinite cubic-bezier(0.66, 0.66, 0.66, 1);
93 | }
94 | @keyframes pulse {
95 | 0% {
96 | color: var(--yellow);
97 | }
98 | 20% {
99 | color: var(--red);
100 | }
101 | 40% {
102 | color: var(--green);
103 | }
104 | 60% {
105 | color: var(--blue);
106 | }
107 | 80% {
108 | color: var(--orange);
109 | }
110 | 100% {
111 | color: var(--yellow);
112 | }
113 | }
114 | .main {
115 | position: relative;
116 | }
117 | .demos img {
118 | border-radius: 10px;
119 | cursor: none;
120 | }
121 | .demos .img1 {
122 | position: absolute;
123 | left: -230px;
124 | top: -80px;
125 | width: 150px;
126 | height: 150px;
127 | }
128 | .demos .img2 {
129 | position: absolute;
130 | right: -230px;
131 | top: -80px;
132 | width: 150px;
133 | height: 150px;
134 | }
135 | .demos .img3 {
136 | position: absolute;
137 | left: -50px;
138 | bottom: -100px;
139 | width: 100px;
140 | height: 100px;
141 | }
142 | .demos .img4 {
143 | position: absolute;
144 | right: -50px;
145 | bottom: -100px;
146 | width: 100px;
147 | height: 100px;
148 | }
149 | .video {
150 | margin-top: 70px;
151 | margin-bottom: 200px;
152 | margin-left: 35px;
153 | margin-right: 35px;
154 | border: solid 5px var(--light-0);
155 | }
156 | .video iframe {
157 | border: solid 5px var(--light);
158 | border-radius: 10px;
159 | width: 100%;
160 | height: 404px;
161 | }
162 | .features .title {
163 | font-weight: 900;
164 | font-family: Poppins;
165 | font-size: 50px;
166 | font-weight: 700;
167 | text-transform: capitalize;
168 | }
169 | .features .desc {
170 | font-family: Inter;
171 | font-size: 19px;
172 | margin-bottom: 20px;
173 | color: var(--light-3);
174 | }
175 | .features .inner {
176 | margin-top: 60px;
177 | margin-bottom: 60px;
178 | }
179 | .features .inner .text {
180 | margin-top: 70px;
181 | }
182 | .features .inner .text-2 {
183 | margin-top: 180px;
184 | }
185 | .examples {
186 | margin-top: 250px;
187 | font-family: Poppins;
188 | font-weight: 700;
189 | color: var(--light-3);
190 | }
191 | .examples img {
192 | width: 80px;
193 | height: 80px;
194 | border-radius: 7px;
195 | }
196 | .compare {
197 | margin-left: auto;
198 | margin-right: auto;
199 | }
200 | .before {
201 | margin-right: 20px;
202 | }
203 | .footer {
204 | padding-top: 100px;
205 | padding-bottom: 100px;
206 | color: var(--dark);
207 | font-size: 17px;
208 | font-weight: 400;
209 | }
210 | .footer .img {
211 | border-radius: 50px;
212 | width: 25px;
213 | margin-top: -3px;
214 | }
215 | .ver {
216 | display: flex;
217 | justify-content: space-between;
218 | align-items: center;
219 | }
220 | .btn {
221 | height: 60px;
222 | padding-left: 40px;
223 | padding-right: 40px;
224 | font-size: 16px;
225 | border: none;
226 | border-radius: 20px;
227 | font-weight: 700;
228 | letter-spacing: 0.2px;
229 | font-family: Inter;
230 | }
231 | .btn-ph {
232 | background: #da552f;
233 | color: #fff;
234 | }
235 | .btn-ph:hover {
236 | background: #ffe4dc;
237 | color: #da552f;
238 | }
239 | .btn-tw {
240 | background: #1d9bf0;
241 | color: #fff;
242 | }
243 | .btn-tw:hover {
244 | background: #dcf1ff;
245 | color: #1d9bf0;
246 | }
247 | .btn-gh {
248 | background: #24292e;
249 | color: #fff;
250 | }
251 | .btn-gh:hover {
252 | background: #dcf1ff;
253 | color: #24292e;
254 | }
255 | .btn-purple {
256 | background: var(--purple);
257 | color: #fff;
258 | }
259 | .btn-purple:hover {
260 | background: var(--purple-light);
261 | color: var(--purple);
262 | }
263 | .btn-pink {
264 | background: var(--pink);
265 | color: #fff;
266 | border: none;
267 | border-radius: 10px;
268 | height: 50px;
269 | padding-left: 25px;
270 | padding-right: 25px;
271 | font-weight: 600;
272 | font-family: Inter;
273 | letter-spacing: 0.2px;
274 | }
275 | .follow-me {
276 | margin-top: 50px;
277 | }
278 | .follow-me button {
279 | font-size: 20px;
280 | width: 60px;
281 | height: 60px;
282 | padding: 0;
283 | }
284 | .follow-me h3 {
285 | font-family: Inter;
286 | font-weight: 400;
287 | margin-top: 100px;
288 | margin-bottom: 15px;
289 | }
290 | .support {
291 | margin-top: 80px;
292 | }
293 | .bold {
294 | font-weight: 700;
295 | }
296 | @media (min-width: 700px) {
297 | .mobile {
298 | display: none;
299 | }
300 | }
301 | @media (max-width: 700px) {
302 | .pc {
303 | display: none;
304 | }
305 | .title {
306 | font-weight: 900;
307 | font-family: Poppins;
308 | font-size: 50px;
309 | font-weight: 700;
310 | text-transform: capitalize;
311 | line-height: 50px;
312 | }
313 | .desc {
314 | font-family: Inter;
315 | font-size: 18px;
316 | margin-bottom: 20px;
317 | }
318 | .main {
319 | position: relative;
320 | }
321 | .demos img {
322 | border-radius: 10px;
323 | cursor: none;
324 | }
325 | .demos .img1 {
326 | position: absolute;
327 | left: 30px;
328 | top: -120px;
329 | width: 70px;
330 | height: 70px;
331 | transform: rotate(-20deg);
332 | }
333 | .demos .img2 {
334 | position: absolute;
335 | right: 30px;
336 | top: -100px;
337 | width: 80px;
338 | height: 80px;
339 | transform: rotate(20deg);
340 | }
341 | .demos .img3 {
342 | position: absolute;
343 | left: 20px;
344 | bottom: -120px;
345 | width: 60px;
346 | height: 60px;
347 | transform: rotate(-20deg);
348 | }
349 | .demos .img4 {
350 | position: absolute;
351 | right: 30px;
352 | bottom: -120px;
353 | width: 100px;
354 | height: 100px;
355 | width: 60px;
356 | height: 60px;
357 | transform: rotate(20deg);
358 | }
359 | .examples {
360 | padding: 30px;
361 | margin-top: 250px;
362 | font-family: Inter;
363 | font-weight: 300;
364 | color: var(--light-3);
365 | }
366 | .examples h3 {
367 | font-size: 40px;
368 | color: var(--light-2);
369 | }
370 | .examples p {
371 | font-size: 20px;
372 | margin-bottom: 20px;
373 | }
374 | .examples img {
375 | width: 120px;
376 | height: 120px;
377 | border-radius: 7px;
378 | }
379 | .compare {
380 | margin-left: auto;
381 | margin-right: auto;
382 | margin-bottom: 40px;
383 | }
384 | .before {
385 | margin-right: 20px;
386 | }
387 | .video {
388 | margin-top: 0;
389 | margin-bottom: 0;
390 | }
391 |
392 | .video iframe {
393 | border: solid 5px var(--light);
394 | border-radius: 20px;
395 | width: 100%;
396 | height: 150px;
397 | }
398 | .features {
399 | padding: 30px;
400 | }
401 | .features .inner {
402 | margin-top: 50px;
403 | }
404 | .features .inner .text {
405 | margin-top: 20px;
406 | }
407 | .features .inner .text-2 {
408 | margin-top: 0;
409 | margin-bottom: 150px;
410 | }
411 | .footer {
412 | padding: 30px;
413 | color: var(--primary);
414 | font-size: 17px;
415 | font-weight: 400;
416 | }
417 | .footer .img {
418 | border-radius: 50px;
419 | width: 25px;
420 | margin-top: -3px;
421 | }
422 | .follow-me {
423 | margin-top: -100px;
424 | }
425 | .follow-me h3 {
426 | font-family: Inter;
427 | font-weight: 400;
428 | margin-top: 100px;
429 | margin-bottom: 15px;
430 | }
431 | .support {
432 | margin-top: 80px;
433 | }
434 | }
435 | .img-shadow {
436 | border-radius: 20px;
437 | box-shadow: 0 0 40px 0 var(--light-2);
438 | }
439 |
--------------------------------------------------------------------------------
/assets/css/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --green: #00bc87;
3 | --light-green: #bdffe9;
4 | --blue: #05f;
5 | --light-blue: rgb(202, 219, 255);
6 | --yellow: #ffa800;
7 | --light-yellow: #ffe7bd;
8 | --red: #d00090;
9 | --light-red: #ffbdee;
10 | --orange: #e74c3c;
11 | --light-orange: #ffc0bd;
12 | --purple: #5849b5;
13 | --purple-light: #dfdaff;
14 | --pink: #ea4c89;
15 | --pink-light: #ffe6ef;
16 | --primary: #282828;
17 | --secondary: #333333;
18 | --light-0: #fafafa;
19 | --light-1: #f3f3f4;
20 | --light-2: #e6e6e6;
21 | --light-3: #585858;
22 | --light-4: #b9b9b9;
23 | }
24 | a {
25 | color: var(--primary);
26 | }
27 | a:hover {
28 | color: var(--light-3);
29 | text-decoration: none;
30 | }
31 | button:focus {
32 | outline: 0;
33 | }
34 | input,
35 | select {
36 | outline: 0;
37 | }
38 | body,
39 | html {
40 | font-family: "Space Grotesk";
41 | overflow-x: hidden;
42 | background: var(--light);
43 | }
44 | p {
45 | margin: 0;
46 | }
47 | .header {
48 | padding: 30px;
49 | padding-top: 10px;
50 | padding-bottom: 0;
51 | }
52 | .small {
53 | font-size: 0.8rem;
54 | line-height: 18px;
55 | margin-top: 20px;
56 | }
57 | .h1 {
58 | font-family: Poppins;
59 | font-size: 40px;
60 | padding-top: 20px;
61 | font-weight: 700;
62 | animation: 3s changecolors infinite;
63 | }
64 | .h1 i {
65 | display: none;
66 | }
67 | .main-container {
68 | position: fixed;
69 | top: 0;
70 | bottom: 0;
71 | right: 0;
72 | display: flex;
73 | align-items: center;
74 | justify-content: center;
75 | z-index: 1;
76 | transition: 1s;
77 | }
78 | .main-container.edit {
79 | left: 25%;
80 | }
81 | .main-container.full {
82 | left: 0;
83 | }
84 | .image-container {
85 | width: 400px;
86 | height: 400px;
87 | display: flex;
88 | background-size: cover;
89 | background-repeat: no-repeat;
90 | background-position: center;
91 | justify-content: center;
92 | align-items: center;
93 | position: relative;
94 | }
95 | .image-container .image {
96 | width: 100%;
97 | height: 100%;
98 | background-size: cover;
99 | background-repeat: no-repeat;
100 | background-position: center;
101 | display: flex;
102 | justify-content: center;
103 | align-items: center;
104 | position: relative;
105 | }
106 | .image-container .image-text {
107 | position: absolute;
108 | font-family: Inter;
109 | font-size: 120px;
110 | font-weight: 400;
111 | line-height: auto;
112 | cursor: grab;
113 | }
114 | .controls {
115 | position: fixed;
116 | top: 0;
117 | bottom: 0;
118 | right: 100%;
119 | width: 25%;
120 | background: #fff;
121 | padding-top: 20px;
122 | padding-left: 25px;
123 | padding-right: 25px;
124 | overflow-x: hidden;
125 | overflow-y: auto;
126 | z-index: 3;
127 | border-top-right-radius: 25px;
128 | border-bottom-right-radius: 25px;
129 | box-shadow: 0 0 20px 0 var(--light-2);
130 | transition: 0.2s;
131 | }
132 | .controls.show {
133 | right: 75%;
134 | }
135 | .controls.hide {
136 | right: 150%;
137 | }
138 | @keyframes hide {
139 | 0% {
140 | opacity: 100;
141 | }
142 | 100% {
143 | opacity: 0;
144 | }
145 | }
146 | .controls::-webkit-scrollbar {
147 | width: 0;
148 | background: 0 0;
149 | }
150 | .controls::-webkit-scrollbar-thumb {
151 | background-color: var(--blue);
152 | border-radius: 100px;
153 | border: solid 3px red;
154 | }
155 | .controls::-webkit-scrollbar-corner {
156 | background-color: transparent;
157 | }
158 | .controls .h2 {
159 | font-weight: 800;
160 | font-family: "Inter";
161 | margin-bottom: 0;
162 | font-size: 30px;
163 | }
164 | .badge {
165 | font-size: 11px;
166 | font-weight: 500;
167 | background: var(--pink);
168 | color: #fff;
169 | }
170 | .controls .desc {
171 | font-weight: 400;
172 | font-family: Inter;
173 | margin-bottom: 0;
174 | font-size: 12px;
175 | margin-top: 5px;
176 | }
177 | .title {
178 | font-size: 13px;
179 | font-weight: 700;
180 | }
181 | .label {
182 | font-size: 12px;
183 | font-weight: 700;
184 | font-family: Inter;
185 | color: var(--light-3);
186 | }
187 | input[type="number"] {
188 | background: var(--light-1);
189 | color: var(--primary);
190 | font-family: Inter;
191 | border: solid 1px var(--light-2);
192 | font-weight: 600;
193 | border-radius: 10px;
194 | font-size: 15px;
195 | padding: 10px;
196 | padding-left: 15px;
197 | font-size: 12.5px;
198 | height: 35px;
199 | width: calc(100% - 0px);
200 | margin-top: 2px;
201 | }
202 | input::-webkit-inner-spin-button,
203 | input::-webkit-outer-spin-button {
204 | -webkit-appearance: none;
205 | margin: 0;
206 | }
207 | input[type="number"] {
208 | -moz-appearance: textfield;
209 | }
210 | .number-label {
211 | position: relative;
212 | }
213 | .number-label input {
214 | appearance: none;
215 | padding-right: 35px;
216 | }
217 | .number-label .inner-label {
218 | position: absolute;
219 | right: 10px;
220 | bottom: 7px;
221 | font-weight: 700;
222 | background: var(--light-1);
223 | }
224 | .number-label-long {
225 | position: relative;
226 | }
227 | .number-label-long input[type="number"] {
228 | max-width: 60px;
229 | }
230 | input[type="text"] {
231 | font-family: Inter;
232 | border: solid 1px var(--light-2);
233 | font-weight: 600;
234 | border-radius: 10px;
235 | font-size: 15px;
236 | padding: 10px;
237 | padding-left: 15px;
238 | font-size: 12.5px;
239 | height: 35px;
240 | width: calc(100% - 0px);
241 | margin-top: 2px;
242 | background: var(--light-1);
243 | color: var(--primary);
244 | width: 100%;
245 | }
246 | input[type="color"] {
247 | padding: 0;
248 | color: var(--primary);
249 | width: 50px;
250 | border-radius: 20px;
251 | border: none;
252 | -webkit-appearance: none;
253 | border: none;
254 | width: 40px;
255 | height: 40px;
256 | }
257 | input[type="color"]::-webkit-color-swatch-wrapper {
258 | padding: 0;
259 | }
260 | input[type="color"]::-webkit-color-swatch {
261 | border-radius: 20px;
262 | border: solid 2px var(--light-0);
263 | box-shadow: 0 0 5px 0 var(--light-2);
264 | }
265 | select {
266 | font-family: Inter;
267 | border: solid 1px var(--light-2);
268 | font-weight: 600;
269 | border-radius: 10px;
270 | font-size: 15px;
271 | padding: 10px;
272 | padding-top: 8px;
273 | padding-left: 10px;
274 | padding-bottom: 10px;
275 | font-size: 12.5px;
276 | height: 35px;
277 | margin-top: 2px;
278 | background: var(--light-1);
279 | color: var(--primary);
280 | min-width: 80px;
281 | -webkit-appearance: none;
282 | appearance: none;
283 | }
284 | input[type="range"] {
285 | -webkit-appearance: none;
286 | width: 100%;
287 | background: var(--pink-light);
288 | height: 5px;
289 | padding-right: 5px;
290 | border-radius: 50px;
291 | margin-bottom: 26px;
292 | }
293 | input[type="range"]:active {
294 | cursor: grabbing;
295 | }
296 | input[type="range"]::-webkit-slider-thumb {
297 | -webkit-appearance: none;
298 | width: 16px;
299 | height: 16px;
300 | border-radius: 50px;
301 | background: var(--pink);
302 | cursor: pointer;
303 | margin-top: 2px;
304 | margin-left: 2px;
305 | margin-right: 10px;
306 | }
307 | .ver-select {
308 | display: flex;
309 | align-items: center;
310 | column-gap: 1;
311 | }
312 | .ver-select .options {
313 | background: var(--light-1);
314 | border-radius: 10px;
315 | width: 120px;
316 | font-family: Inter;
317 | border: solid 1px var(--light-2);
318 | font-weight: 600;
319 | border-radius: 5px;
320 | font-size: 12.5px;
321 | height: 35px;
322 | margin-top: 2px;
323 | background: var(--light-1);
324 | color: var(--primary);
325 | }
326 | .select-btn {
327 | border: none;
328 | height: 33px;
329 | width: 100%;
330 | padding: 2px;
331 | font-size: 12px;
332 | background-color: var(--light-1);
333 | color: var(--primary);
334 | border-radius: 5px;
335 | }
336 | .select-btn.active {
337 | background-color: #fff;
338 | border: solid 3px var(--light-1);
339 | border-radius: 5px;
340 | }
341 | .image-select-btn {
342 | color: #fff;
343 | background: #3178ff;
344 | text-align: center;
345 | cursor: pointer;
346 | font-family: Heebo;
347 | letter-spacing: 0.5px;
348 | border: none;
349 | font-weight: 600;
350 | border-radius: 10px;
351 | font-size: 13px;
352 | padding: 10px;
353 | height: 40px;
354 | width: calc(100% - 10px);
355 | margin-top: 5px;
356 | margin-left: 5px;
357 | transition: 1s;
358 | }
359 | .image-select-btn:hover {
360 | background: #4071cc;
361 | color: #fff;
362 | }
363 | .image-select-btn:hover > i {
364 | animation: 0.8s bounce 1;
365 | }
366 | @keyframes bounce {
367 | 0% {
368 | transform: translateY(7px);
369 | }
370 | 25% {
371 | transform: translateY(-7px);
372 | }
373 | 100% {
374 | transform: translateY(0);
375 | }
376 | }
377 | .ver {
378 | display: flex;
379 | justify-content: space-between;
380 | align-items: center;
381 | }
382 | .ver-left {
383 | display: flex;
384 | justify-content: left;
385 | align-items: center;
386 | column-gap: 10px;
387 | }
388 | .ver-top {
389 | display: flex;
390 | justify-content: space-between;
391 | }
392 | .ver-top > div {
393 | flex: auto auto auto;
394 | align-items: top;
395 | border: 5px transparent solid;
396 | }
397 | @keyframes changecolors {
398 | 0% {
399 | color: var(--yellow);
400 | }
401 | 20% {
402 | color: var(--red);
403 | translate-x: -20px;
404 | }
405 | 40% {
406 | color: var(--green);
407 | }
408 | 60% {
409 | color: var(--blue);
410 | }
411 | 80% {
412 | color: var(--orange);
413 | }
414 | 100% {
415 | color: var(--yellow);
416 | }
417 | }
418 | .images {
419 | padding-left: 6px;
420 | padding-right: 6px;
421 | margin-top: 5px;
422 | border-radius: 10px;
423 | font-family: Inter;
424 | }
425 | .images-container {
426 | margin-top: 5px;
427 | padding: 10px;
428 | border-radius: 10px;
429 | font-family: Inter;
430 | display: grid;
431 | grid-template-columns: auto auto auto;
432 | grid-column-gap: 10px;
433 | grid-row-gap: 10px;
434 | background: 0 0;
435 | border: solid 3px var(--light-4);
436 | border-style: dashed;
437 | }
438 | .images .title {
439 | font-size: 20px;
440 | }
441 | .images .image-components {
442 | margin-top: 10px;
443 | padding: 10px;
444 | padding-bottom: 0;
445 | border-radius: 20px;
446 | font-family: Inter;
447 | background: 0 0;
448 | }
449 | .images .image-components .img-component {
450 | padding: 0;
451 | padding-top: 5px;
452 | padding-bottom: 5px;
453 | margin-bottom: 5px;
454 | border-radius: 10px;
455 | display: grid;
456 | align-items: center;
457 | justify-content: center;
458 | cursor: pointer;
459 | }
460 | .images .image-components .img-component.active {
461 | background: #fff;
462 | padding: 10px;
463 | box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.048);
464 | }
465 | .images .image-components .img-component.active .img {
466 | height: 80px;
467 | }
468 | .images .image-components .img-component .img {
469 | width: 70px;
470 | height: 70px;
471 | background-size: cover;
472 | background-position: center;
473 | border-radius: 13px;
474 | transition: 0.1s;
475 | }
476 | .images .image-components .img-component:hover .img {
477 | transform: scale(1.1);
478 | }
479 | .editor {
480 | position: fixed;
481 | left: 26%;
482 | bottom: 20px;
483 | z-index: 5;
484 | background: #fff;
485 | width: 300px;
486 | padding: 10px;
487 | padding-bottom: 15px;
488 | border-radius: 20px;
489 | border: solid 0.8px var(--light-2);
490 | box-shadow: 0 0 10px 2px var(--light-1);
491 | }
492 | .background {
493 | position: fixed;
494 | top: 0;
495 | right: 0;
496 | bottom: 0;
497 | left: 25%;
498 | background: #fff;
499 | opacity: 0;
500 | z-index: 5;
501 | }
502 | .editor .img {
503 | width: 70px;
504 | height: 70px;
505 | background-size: cover;
506 | background-position: center;
507 | border-radius: 13px;
508 | }
509 | .hidden {
510 | display: none;
511 | }
512 | .images .text {
513 | font-size: 13px;
514 | padding-left: 10px;
515 | border-radius: 5px;
516 | font-weight: 700;
517 | background: var(--light);
518 | height: 25px;
519 | font-size: 13px;
520 | width: 100%;
521 | margin-bottom: 5px;
522 | border: solid 1.5px var(--light-4);
523 | }
524 | .close-btn {
525 | border: none;
526 | width: 30px;
527 | height: 30px;
528 | background: 0 0;
529 | font-size: 13px;
530 | }
531 | .play-btn {
532 | height: 40px;
533 | width: 40px;
534 | border: none;
535 | border-radius: 50px;
536 | font-family: Inter;
537 | font-size: 12px;
538 | background: var(--light-2);
539 | color: var(--light-3);
540 | font-weight: 700;
541 | transition: 0.3s;
542 | padding: 0;
543 | margin: 0;
544 | }
545 | .play-btn:hover {
546 | color: var(--primary);
547 | }
548 | .clear-btn {
549 | height: 35px;
550 | width: 35px;
551 | border: none;
552 | border-radius: 50px;
553 | font-family: Inter;
554 | font-size: 12px;
555 | background: var(--pink);
556 | color: #fff;
557 | font-weight: 700;
558 | transition: 0.3s;
559 | }
560 | .clear-btn:hover {
561 | background: var(--pink-light);
562 | color: var(--pink);
563 | }
564 | .remove-btn {
565 | height: 30px;
566 | width: 100%;
567 | border: none;
568 | border-radius: 10px;
569 | font-family: Inter;
570 | background: var(--pink);
571 | color: #fff;
572 | font-weight: 600;
573 | transition: 0.3s;
574 | font-size: 11px;
575 | margin-top: 15px;
576 | }
577 | .remove-btn:hover {
578 | background: var(--pink-light);
579 | color: var(--pink);
580 | }
581 | @media (max-width: 700px) {
582 | .pc {
583 | display: none;
584 | }
585 | .main-container {
586 | display: none;
587 | }
588 | .controls {
589 | display: none;
590 | }
591 |
592 | .showControls{
593 | display: none;
594 | }
595 | }
596 | @media (min-width: 700px) {
597 | .mobile {
598 | display: none;
599 | padding-left: 20px;
600 | padding-right: 20px;
601 | }
602 | }
603 |
604 | .showControls {
605 | position: fixed;
606 | top: 20px;
607 | left: 20%;
608 | z-index: 1;
609 | background: var(--light-2);
610 | color: var(--secondary);
611 | height: 40px;
612 | width: 40px;
613 | border: none;
614 | border-radius: 50px;
615 | font-family: Poppins;
616 | font-size: 13.5px;
617 | font-weight: 900;
618 | transition: 0.3s;
619 | }
620 | .showControls.show {
621 | background: var(--pink);
622 | color: #fff;
623 | left: 2%;
624 | }
625 | .showControls:hover {
626 | color: var(--dark);
627 | background: var(--light);
628 | box-shadow: 0 0 15px 0 #fff;
629 | }
630 | .fixed-btn {
631 | position: fixed;
632 | top: 70px;
633 | left: 2%;
634 | z-index: 1;
635 | background: var(--blue);
636 | color: #fff;
637 | transition: 0.5s;
638 | }
639 | .fixed-btn:hover {
640 | color: var(--blue);
641 | background: var(--purple-light);
642 | box-shadow: 0 0 15px 0 #fff;
643 | }
644 | .canvas {
645 | background: #00bc87;
646 | }
647 | .canvas-container {
648 | position: relative;
649 | }
650 | .url-input-container {
651 | position: relative;
652 | }
653 | .url-input-container .add-btn {
654 | position: absolute;
655 | border: none;
656 | background: #3178ff;
657 | color: #fff;
658 | height: 35px;
659 | width: 35px;
660 | border-radius: 10px;
661 | margin-top: 5px;
662 | right: 0;
663 | bottom: 0;
664 | }
665 | .primary-btn {
666 | background: #3178ff;
667 | color: #fff;
668 | border-radius: 10px;
669 | border: none;
670 | margin-top: 5px;
671 | font-size: 13px;
672 | padding: 10px;
673 | height: 40px;
674 | width: 45px;
675 | }
676 |
677 | .primary-btn:hover {
678 | background: #4071cc;
679 | }
680 |
681 | .credits {
682 | margin-top: 50px;
683 | margin-bottom: 50px;
684 | padding-left: 20px;
685 | padding-right: 20px;
686 | }
687 |
688 | .made-by {
689 | font-family: Inter;
690 | font-size: 13px;
691 | color: var(--light-3);
692 | text-decoration: none;
693 | text-align: center;
694 | margin-left: auto;
695 | margin-right: auto;
696 | filter: blur(20px);
697 | transition: 0.1s;
698 | font-weight: 600;
699 | }
700 |
701 | .made-by:hover {
702 | filter: blur(0px);
703 | color: #000;
704 | cursor: pointer;
705 | transform: translateX(40px);
706 | }
707 |
708 | .socials a{
709 | text-decoration: none;
710 | }
711 |
712 | .socials button{
713 | border: none;
714 | border-radius: 10px;
715 | font-size: 20px;
716 | width: 40px;
717 | height: 40px;
718 | background-color: rgb(255, 255, 255);
719 | color: var(--light-5);
720 | transition: 0.3s;
721 | }
722 |
723 | .socials button:hover{
724 | color: var(--light-4);
725 | }
726 |
--------------------------------------------------------------------------------
/assets/imgs/browser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/browser.png
--------------------------------------------------------------------------------
/assets/imgs/demos/craftworks.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/craftworks.gif
--------------------------------------------------------------------------------
/assets/imgs/demos/craftworks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/craftworks.png
--------------------------------------------------------------------------------
/assets/imgs/demos/dribbble.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/dribbble.gif
--------------------------------------------------------------------------------
/assets/imgs/demos/dribbble.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/dribbble.png
--------------------------------------------------------------------------------
/assets/imgs/demos/notion.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/notion.gif
--------------------------------------------------------------------------------
/assets/imgs/demos/notion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/notion.png
--------------------------------------------------------------------------------
/assets/imgs/demos/slack.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/slack.gif
--------------------------------------------------------------------------------
/assets/imgs/demos/slack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/demos/slack.png
--------------------------------------------------------------------------------
/assets/imgs/easy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/easy.png
--------------------------------------------------------------------------------
/assets/imgs/editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/editor.png
--------------------------------------------------------------------------------
/assets/imgs/xsullo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/assets/imgs/xsullo.webp
--------------------------------------------------------------------------------
/assets/js/main.js:
--------------------------------------------------------------------------------
1 | /* main */
2 | let mainWidth = document.querySelector("#mainWidth");
3 | let mainHeight = document.querySelector("#mainHeight");
4 | let overRideDelay = document.querySelector("#overRideDelay");
5 | let overRideFontSize = document.querySelector("#overRideFontSize");
6 |
7 | /* User Added images */
8 | let images = [];
9 | /* images preview container */
10 | let mainImagesContainer = document.querySelector("#mainImagesContainer");
11 | /* preview thumbnail container */
12 | let imagesContainer = document.querySelector("#images");
13 |
14 | /* reset and play/stop buttons */
15 | let clearBtn = document.querySelector("#clearBtn");
16 | let ppBtn = document.querySelectorAll(".play-btn");
17 |
18 | /* main view window */
19 | let mainImgContainer = document.querySelector("#mainImgContainer");
20 | let animeImg = document.querySelector("#animeImg");
21 | let animeText = document.querySelector("#animeText");
22 |
23 | /* current image */
24 | let currentId = "";
25 | let currentEditImage = document.querySelector("#currentEditImage");
26 | let currentText = document.querySelector("#currentText");
27 | let currentColor = document.querySelector("#currentColor");
28 | let currentFontSize = document.querySelector("#currentFontSize");
29 | let currentFontWeight = document.querySelector("#currentFontWeight");
30 | let currentShadowValue = document.querySelector("#currentShadowValue");
31 | let currentShadowColor = document.querySelector("#currentShadowColor");
32 | let currentDelay = document.querySelector("#currentDelay");
33 | let currentRotation = document.querySelector("#currentRotation");
34 | let currentRotationInput = document.querySelector("#currentRotationInput");
35 |
36 | let currentTop = 136;
37 | let currentLeft = 21;
38 | let currentAlignment = "center";
39 |
40 | let editorBackground = document.querySelector("#editorBackground");
41 | let editor = document.querySelector(".editor");
42 |
43 | /* remove current image beig edited */
44 | let removeCurrentImage = document.querySelector("#removeCurrentImage");
45 |
46 | let width = 400;
47 | let height = 400;
48 |
49 |
50 | $(".url-input-container").hide();
51 |
52 | function addUrlImageBtn() {
53 | if ($(".url-input-container").is(":visible")) {
54 | $(".url-input-container").fadeOut(500);
55 | $("#linkBtn").removeClass("btn-secondary");
56 | $("#linkBtn").html(' ');
57 | } else {
58 | $(".url-input-container").fadeIn(500);
59 | $("#linkBtn").addClass("btn-secondary");
60 | $("#linkBtn").html(' ');
61 | }
62 | }
63 |
64 | function toggleControls() {
65 | if ($("#controls").hasClass("show")) {
66 | $("#controls").removeClass("show");
67 | $("#controls").addClass("hide");
68 | $(".showControls").addClass("show");
69 | $("#hideBtn").hide();
70 | $("#showBtn").show();
71 | $(".main-container").removeClass("edit");
72 | $(".main-container").addClass("full");
73 | } else {
74 | $(".showControls").removeClass("show");
75 | $("#controls").addClass("show");
76 | $("#controls").removeClass("hide");
77 | $("#hideBtn").fadeIn();
78 | $("#showBtn").hide();
79 | $(".main-container").addClass("edit");
80 | $(".main-container").removeClass("full");
81 | }
82 | }
83 |
84 | /* image upload */
85 | function handleImage(files) {
86 | mainImagesContainer.hidden = false;
87 | clearBtn.hidden = false;
88 | mainImgContainer.hidden = false;
89 |
90 | if (files.length > 0) {
91 | [...files].forEach((each) => {
92 | let newImg = URL.createObjectURL(each);
93 | images.push({
94 | id: images.length,
95 | img: newImg,
96 | text: "",
97 | color: "#ffffff",
98 | fontsize: "120",
99 | fontweight: "700",
100 | shadow: "100",
101 | shadowcolor: "#000000",
102 | delay: 500,
103 | top: '50%',
104 | left: '50%',
105 | align: "center",
106 | rotation: 0,
107 | });
108 |
109 | imagesContainer.innerHTML += `
110 |
115 | `;
116 | });
117 | }
118 |
119 | ppBtn.forEach((each) => {
120 | if (images.length > 0) {
121 | each.hidden = false;
122 | }
123 | });
124 | }
125 |
126 | function urlImageUpload() {
127 | let urlInput = document.querySelector("#urlInput");
128 | if (urlInput.value.length > 3) {
129 | imagesContainer.hidden = false;
130 | clearBtn.hidden = false;
131 |
132 | let newImg = urlInput.value;
133 | let id = images.length;
134 | images.push({
135 | id: id,
136 | img: newImg,
137 | text: "",
138 | color: "#ffffff",
139 | fontsize: "120",
140 | fontweight: "700",
141 | shadow: "100",
142 | shadowcolor: "#000000",
143 | delay: 500,
144 | top: 136,
145 | left: 21,
146 | align: "center",
147 | rotation: 0,
148 | });
149 |
150 | imagesContainer.innerHTML += `
151 |
154 | `;
155 |
156 | ppBtn.forEach((each) => {
157 | if (images.length > 0) {
158 | each.hidden = false;
159 | }
160 | });
161 |
162 | mainImagesContainer.hidden = false;
163 | clearBtn.hidden = false;
164 | mainImgContainer.hidden = false;
165 | }
166 | urlInput.value = "";
167 | }
168 |
169 | function clearImages() {
170 | if (confirm("Are you sure all data will be lost if you continue!") == true) {
171 | location.reload();
172 | }
173 | }
174 |
175 | function editTextClick() {
176 | editImage(currentId);
177 | }
178 |
179 | function editImage(id) {
180 | console.log(id);
181 | currentId = id;
182 | currentEditImage.style.cssText = `background-image: url('${images[id].img}')`;
183 |
184 | currentText.value = images[id].text;
185 | currentColor.value = images[id].color;
186 | currentFontSize.value = images[id].fontsize;
187 | currentFontWeight = images[id].fontweight;
188 | currentShadowValue.value = images[id].shadow;
189 | currentShadowColor.value = images[id].shadowcolor;
190 | currentDelay.value = images[id].delay;
191 | currentTop = images[id].top;
192 | currentLeft = images[id].left;
193 | currentAlignment = images[id].align;
194 | currentRotation.style.transform = images[id].rotation;
195 |
196 | animeImg.style.cssText = `background-image: url('${images[id].img}')`;
197 | animeText.innerHTML = images[id].text;
198 | animeText.style.cssText = `color: ${images[id].color}; text-shadow: 0 0 ${images[id].shadow}px ${images[id].shadowcolor}; font-weight: ${images[id].fontweight}; font-size: ${images[id].fontsize}px;`;
199 |
200 | animeText.style.top = images[id].top + "px";
201 | animeText.style.left = images[id].left + "px";
202 |
203 | animeText.style.textAlign = images[id].align;
204 |
205 | animeText.style.transform = `rotate(${images[id].rotation}deg)`;
206 | currentRotationInput.value = images[id].rotation;
207 |
208 | editor.hidden = false;
209 | editorBackground.hidden = false;
210 |
211 | currentText.focus();
212 | }
213 |
214 | function textAlignment(el) {
215 | currentAlignment = el.value;
216 | animeText.style.textAlign = el.value;
217 | images[currentId].align = el.value;
218 | document.querySelectorAll(".text-alignment-btn").forEach((each) => {
219 | if (each.value == el.value) {
220 | each.classList.add("active");
221 | } else {
222 | each.classList.remove("active");
223 | }
224 | });
225 | }
226 |
227 | dragElement(animeText);
228 |
229 | function dragElement(elmnt) {
230 | var pos1 = 0,
231 | pos2 = 0,
232 | pos3 = 0,
233 | pos4 = 0;
234 | if (document.getElementById(elmnt.id + "header")) {
235 | // if present, the header is where you move the DIV from:
236 | document.getElementById(elmnt.id + "header").onmousedown = dragMouseDown;
237 | } else {
238 | // otherwise, move the DIV from anywhere inside the DIV:
239 | elmnt.onmousedown = dragMouseDown;
240 | }
241 |
242 | function dragMouseDown(e) {
243 | e = e || window.event;
244 | e.preventDefault();
245 | // get the mouse cursor position at startup:
246 | pos3 = e.clientX;
247 | pos4 = e.clientY;
248 | document.onmouseup = closeDragElement;
249 | // call a function whenever the cursor moves:
250 | document.onmousemove = elementDrag;
251 | }
252 |
253 | function elementDrag(e) {
254 | e = e || window.event;
255 | e.preventDefault();
256 | // calculate the new cursor position:
257 | pos1 = pos3 - e.clientX;
258 | pos2 = pos4 - e.clientY;
259 | pos3 = e.clientX;
260 | pos4 = e.clientY;
261 | // set the element's new position:
262 | elmnt.style.top = elmnt.offsetTop - pos2 + "px";
263 | elmnt.style.left = elmnt.offsetLeft - pos1 + "px";
264 |
265 | images[currentId].top = elmnt.offsetTop - pos2;
266 | images[currentId].left = elmnt.offsetLeft - pos1;
267 |
268 | console.log(elmnt.offsetTop - pos2);
269 | console.log(elmnt.offsetLeft - pos1);
270 | }
271 |
272 | function closeDragElement() {
273 | // stop moving when mouse button is released:
274 | document.onmouseup = null;
275 | document.onmousemove = null;
276 | }
277 | }
278 |
279 | currentText.addEventListener("keyup", (el) => {
280 | let val = el.target.value;
281 | images[currentId].text = val;
282 | animeText.innerHTML = val;
283 | });
284 |
285 | currentColor.addEventListener("change", (el) => {
286 | let val = el.target.value;
287 | images[currentId].color = val;
288 | animeText.style.color = val;
289 | });
290 |
291 | /* current image edit font update */
292 | currentFontSize.addEventListener("change", (el) => {
293 | let val = el.target.value;
294 | images[currentId].fontsize = val;
295 | animeText.style.fontSize = `${val}px`;
296 | });
297 |
298 | currentFontSize.addEventListener("keyup", (el) => {
299 | let val = el.target.value;
300 | images[currentId].fontsize = val;
301 | animeText.style.fontSize = `${val}px`;
302 | });
303 |
304 | /* current image edit Font Weight */
305 | currentFontWeight.addEventListener("change", (el) => {
306 | let val = el.target.value;
307 | images[currentId].fontweight = val;
308 | animeText.style.fontWeight = val;
309 | });
310 |
311 | /* current image edit shadow */
312 | currentShadowValue.addEventListener("change", (el) => {
313 | let val = el.target.value;
314 | images[currentId].shadow = val;
315 | animeText.style.textShadow = ` 0 0 ${val}px ${images[currentId].shadowcolor}`;
316 | });
317 |
318 | /* current image edit shadow color */
319 | currentShadowColor.addEventListener("change", (el) => {
320 | let val = el.target.value;
321 | images[currentId].shadowcolor = val;
322 | animeText.style.textShadow = ` 0 0 ${images[currentId].shadow}px ${val}`;
323 | });
324 |
325 | /* current image edit image delay */
326 | currentDelay.addEventListener("change", (el) => {
327 | let val = el.target.value;
328 | images[currentId].delay = val;
329 | });
330 |
331 | currentRotation.addEventListener("mousemove", (el) => {
332 | let val = el.target.value;
333 | images[currentId].rotation = val;
334 | animeText.style.textShadow = `0 0 10px 0 red;`;
335 | animeText.style.transform = `rotate(${val}deg)`;
336 | currentRotationInput.value = val;
337 | });
338 |
339 | currentRotationInput.addEventListener("keyup", (el) => {
340 | if (el.target.value.length >= 0) {
341 | let val = el.target.value;
342 | images[currentId].rotation = val;
343 | animeText.style.textShadow = `0 0 10px 0 red;`;
344 | animeText.style.transform = `rotate(${val}deg)`;
345 | currentRotation.value = val;
346 | } else {
347 | images[currentId].rotation = 0;
348 | animeText.style.textShadow = `0 0 10px 0 red;`;
349 | animeText.style.transform = `rotate(${0}deg)`;
350 | currentRotation.value = 0;
351 | }
352 | });
353 |
354 | removeCurrentImage.addEventListener("click", (el) => {
355 | let arr = [...images];
356 | console.log(arr)
357 | arr = images.filter((each) => {
358 | return each.id !== currentId;
359 | });
360 | images = arr;
361 | console.log(images)
362 | console.log(arr);
363 | console.log(images);
364 | editor.hidden = true;
365 |
366 | imagesContainer.innerHTML = "";
367 | images.forEach((image, id) => {
368 | image.id = id;
369 | imagesContainer.innerHTML += `
370 |
373 | `;
374 | });
375 | });
376 |
377 |
378 | /* main width and height */
379 | mainWidth.addEventListener("keyup", (el) => {
380 | let val = el.target.value;
381 | width = val;
382 | mainImgContainer.style.cssText = `width: ${val}px; height: ${height}px;`;
383 | });
384 |
385 | mainHeight.addEventListener("keyup", (el) => {
386 | let val = el.target.value;
387 | height = val;
388 | mainImgContainer.style.cssText = `width: ${width}px; height: ${val}px;`;
389 | });
390 |
391 | /* closeeditor */
392 | function hideEditor() {
393 | editorBackground.hidden = true;
394 | editor.hidden = true;
395 | }
396 |
397 | let animeCounter = 0;
398 | let animeDelay = 1;
399 | let animating = false;
400 | let intervalID;
401 | let initial = true;
402 |
403 | overRideDelay.addEventListener("change", (el) => {
404 | let val = el.target.value;
405 | images.forEach((each) => {
406 | each.delay = val;
407 | });
408 | animeCounter = 0;
409 | clearInterval(intervalID);
410 | animeDelay = 0;
411 | initial = true;
412 | if (animating) {
413 | animating = false;
414 | start();
415 | }
416 | });
417 |
418 | overRideFontSize.addEventListener("change", (el) => {
419 | let val = el.target.value;
420 | images.forEach((each) => {
421 | each.fontsize = val;
422 | });
423 | animeCounter = 0;
424 | });
425 |
426 | function start() {
427 | if (animating == false) {
428 | animating = true;
429 | ppBtn.forEach((each) => {
430 | each.disabled = false;
431 | each.innerHTML = ` `;
432 | });
433 |
434 | let looper = () => {
435 | /* to avoid default delay value run through before applying custom delay for each image */
436 | intervalID = setTimeout(() => {
437 | currentId = animeCounter;
438 | currentEditImage.style.cssText = `background-image: url('${images[animeCounter].img}')`;
439 |
440 | currentText.value = images[animeCounter].text;
441 | currentColor.value = images[animeCounter].color;
442 | currentFontSize.value = images[animeCounter].fontsize;
443 | currentFontWeight = images[animeCounter].fontweight;
444 | currentShadowValue.value = images[animeCounter].shadow;
445 | currentShadowColor.value = images[animeCounter].shadowcolor;
446 | currentDelay.value = images[animeCounter].delay;
447 |
448 | animeDelay = images[animeCounter].delay;
449 |
450 | animeImg.style.cssText = `background-image: url('${images[animeCounter].img}')`;
451 | animeText.innerHTML = images[animeCounter].text;
452 | animeText.style.cssText = `color: ${images[animeCounter].color}; text-shadow: 0 0 ${images[animeCounter].shadow}px ${images[animeCounter].shadowcolor}; font-weight: ${images[animeCounter].fontweight}; font-size: ${images[animeCounter].fontsize}px;`;
453 |
454 | animeText.style.top = images[animeCounter].top + "px";
455 | animeText.style.left = images[animeCounter].left + "px";
456 |
457 | animeText.style.textAlign = images[animeCounter].align;
458 |
459 | animeText.style.transform = `rotate(${images[animeCounter].rotation}deg)`;
460 | currentRotationInput.value = images[animeCounter].rotation;
461 |
462 | editor.hidden = true;
463 | editorBackground.hidden = true;
464 | console.log(animeDelay);
465 |
466 | if (animeCounter < images.length - 1) {
467 | animeCounter += 1;
468 | if (animating) {
469 | looper();
470 | }
471 | } else {
472 | animeCounter = 0;
473 | initial = false;
474 | if (animating) {
475 | looper();
476 | }
477 | }
478 | }, animeDelay);
479 | };
480 |
481 | looper();
482 | } else {
483 | animating = false;
484 | animeCounter = 0;
485 | initial = false;
486 | animating = false;
487 | clearInterval(intervalID);
488 | ppBtn.forEach((each) => {
489 | each.disabled = false;
490 | each.innerHTML = ` `;
491 | });
492 | }
493 | }
494 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alohe/flashy/18c72c968e932076866324bb6678fb238f2382ac/demo.gif
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 | Flashy 2.0
14 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
32 |
36 |
37 |
38 |
39 |
40 |
46 |
50 |
54 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 | Flashy Version 2.0
93 |
94 |
95 | Turn your images into a
96 | frame by frame animation
97 |
103 |
104 |
105 | Start Creating
106 |
107 |
108 |
109 |
115 |
121 |
127 |
133 |
134 |
135 |
136 |
137 |
138 |
Some Examples
139 |
140 |
141 |
142 |
143 |
Before
144 |
148 |
149 |
150 |
After
151 |
155 |
156 |
157 |
158 |
159 |
160 |
Before
161 |
165 |
166 |
167 |
After
168 |
172 |
173 |
174 |
175 |
176 |
177 |
Before
178 |
182 |
183 |
184 |
After
185 |
189 |
190 |
191 |
192 |
193 |
194 | VIDEO
201 |
202 |
203 |
204 |
205 |
206 |
207 |
213 |
214 |
215 |
Fast & Easy
216 |
Just add your images and press play thats it
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
230 |
231 |
232 |
233 | Total control
234 |
235 |
236 | Add text, change its size, weight, alignment, shadow, color,
237 | duration, rotation and position by dragging the text
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 | Working on adding more features to this project such as Export to
246 | video, so stay in touch. If you have feature requests feel free to let me know on one of these 👇
247 |
248 |
249 |
250 |
267 |
268 |
269 |
270 |
286 |
287 |
291 |
292 |
293 |
--------------------------------------------------------------------------------
/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
--------------------------------------------------------------------------------