WIP: Add initial meme generator! #748

Merged
skhameneh merged 16 commits from featureTesting into master 2018-11-30 03:54:55 +01:00
3 changed files with 92 additions and 58 deletions
Showing only changes of commit 63d1de3147 - Show all commits

View file

@ -68,4 +68,5 @@ export const PRESETS = {
'Retro Rainbow': require('../FontFaces/RetroRainbow'),
'Green Machine': require('../FontFaces/GreenMachine'),
'vapor wave': require('../FontFaces/VaporWave'),
'The Special': require('../FontFaces/TheSpecial'),
}

File diff suppressed because one or more lines are too long

View file

@ -4,35 +4,30 @@ import Select from 'react-select'
import RichDraggable from './RichDraggable';
import EditableFontface, { PRESETS as FontPresets } from './EditableFontface';
// TODO: Remove `rasterizehtml` from SSR
let rasterizeHTML = () => {};
try {
if(window) {
rasterizeHTML = require('rasterizehtml')
}
} catch(e) {}
const getRasterizedCanvas = (contents, width, height) => {
return new Promise((resolve) => {
// Parse to xHTML for SVG/foreignObject rendering
contents = new XMLSerializer().serializeToString(
new DOMParser().parseFromString(contents, 'text/html')
);
// Resolves a bug in Chrome where it renders correctly, but
// replaces the inline styles with an invalid `background-clip`.
if(/Chrome/.test(navigator.userAgent)) {
contents = contents.replace(/background\-clip:(.*)[;$]/g,
(match, group) => (`-webkit-background-clip:${group};${match}`)
contents = contents.replace(/background\-clip:(\s*text\s*)[;$]/g,
(match, group) => (`-webkit-background-clip:text;${match}`)
);
}
// Attempt to match font kerning with the DOM.
contents = '<style>svg{font-kerning:normal}</style>' + contents;
const svgContents = `<svg xmlns="http://www.w3.org/2000/svg" width="${width * 2}" height="${height * 2}">
<foreignObject x="0" y="0" width="${width * 2}" height="${height * 2}" externalResourcesRequired="true">
<html xmlns="http://www.w3.org/1999/xhtml"><body>${contents}</body></html>
</foreignObject></svg>`;
rasterizeHTML.drawHTML(contents, document.createElement('canvas'), {
width,
height,
}).then((renderResult) => {
const pixelRatio = 2;
// Why do this? Because Firefox doesn't always give us what we expect
// `background-clip: text` is very broken and does not always render in time.
let img = document.createElement('img');
let canvas = document.createElement('canvas');
@ -50,14 +45,14 @@ const getRasterizedCanvas = (contents, width, height) => {
document.body.appendChild(shadowNode);
shadowNode.appendChild(img);
//document.body.appendChild(canvas);
var svg64 = btoa(unescape(encodeURIComponent(renderResult.svg)));
var svg64 = btoa(unescape(encodeURIComponent(svgContents)));
var b64Start = 'data:image/svg+xml;base64,';
var image64 = b64Start + svg64;
img.addEventListener('load', () => {
window.requestAnimationFrame(() => {
// We still can't trust Firefox's %$%&* engine, add another 5ms timeout
// `background-clip: text` is very broken and does not always render in time.
setTimeout(() => {
let context = canvas.getContext('2d', { alpha: false });
context.clearRect(0, 0, canvas.width, canvas.height);
@ -75,7 +70,6 @@ const getRasterizedCanvas = (contents, width, height) => {
});
img.src = image64;
});
});
};
export default class Creatify extends Component {
@ -120,12 +114,10 @@ export default class Creatify extends Component {
let contents = me.contents.current.outerHTML;
console.log(contents)
// Cheap border/handles removal
contents = `<style>.creatifyDecor{border-color:transparent!important;background-color:transparent!important}</style>` + contents;
getRasterizedCanvas(contents, 600, 500).then((element) => {
console.log(element);
document.body.appendChild(element);
});
}