Fabricjs Impact font not loading on mobile devices - javascript

I have a demo here: https://codepen.io/Jsbbvk/pen/KKXNPYO
var canvas = new fabric.Canvas("canvas");
const text = new fabric.IText("sample text")
text.set({
fontFamily: "Impact",
left: (this.canvas.width - text.width) / 2,
top: (this.canvas.height - text.height) / 2,
})
canvas.add(text)
canvas.requestRenderAll()
If you visit this codepen on a mobile device, you'll see that the Impact font doesn't load. However, visiting this codepen on a desktop will work. Is there a fix to this?

Impact is not preinstalled on android devices
Actually, the term "web safe fonts" is just plain wrong! (see also: "Impact" font not working on mobile Chrome
Workaround use a async font loader to check the availability
Check if fonts are available via document.fonts.check()
If necessary: load the font via asynchronous helper function loadFonts(fontsToLoad) (based on FontFace.load() method)
You also need to init fabric.js after fonts are loaded:
JS:
async function initFabric() {
var canvas = new fabric.Canvas("canvas");
const text = new fabric.IText("sample text");
let canvasContainer = document.querySelector(".canvas-container");
//load fonts if necessary
let fontsToLoad = checkFontAvailability(fonts);
await loadFonts(fontsToLoad);
text.set({
fontFamily: "Impact",
left: (this.canvas.width - text.width) / 2,
top: (this.canvas.height - text.height) / 2
});
canvas.add(text);
canvas.requestRenderAll();
}
Working example
/**
* fonts to check
*/
let fonts = [{
'font-family': 'Arial',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2'
},
{
'font-family': 'Times New Roman',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2'
},
{
// Inter as replacement
'font-family': 'Helvetica',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/inter/v12/UcC73FwrK3iLTeHuS_fvQtMwCp50KnMa1ZL7.woff2'
},
{
// Anton as replacement
'font-family': 'Impact',
'font-style': 'normal',
'font-weight': 400,
'src': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2'
},
]
/**
* init fabric after font check
*/
initFabric();
async function initFabric() {
var canvas = new fabric.Canvas("canvas");
const text = new fabric.IText("sample text");
let canvasContainer = document.querySelector('.canvas-container');
//load fonts if necessary
let fontsToLoad = checkFontAvailability(fonts);
await loadFonts(fontsToLoad);
text.set({
fontFamily: "Impact",
left: (this.canvas.width - text.width) / 2,
top: (this.canvas.height - text.height) / 2,
})
canvas.add(text)
canvas.requestRenderAll()
//add buttons
fonts.forEach(function(font) {
let fontFamily = font['font-family']
let btn = document.createElement('button')
btn.setAttribute('type', 'button')
btn.classList.add('btn-font');
btn.textContent = fontFamily
canvasContainer.parentNode.insertBefore(btn, canvasContainer);
btn.addEventListener("click", () => {
text.fontFamily = fontFamily
canvas.renderAll()
})
})
}
function checkFontAvailability(fonts) {
let info = [];
let fontsToLoad = [];
if (fonts.length) {
fonts.forEach(function(font) {
let fontFamily = font['font-family'];
let fontApplied = document.fonts.check(`12px ${fontFamily}`);
if (!fontApplied) {
fontsToLoad.push(font)
}
})
}
return fontsToLoad;
}
async function loadFonts(fontsToLoad) {
if (fontsToLoad.length) {
for (let i = 0; i < fontsToLoad.length; i++) {
let fontProps = fontsToLoad[i];
let fontFamily = fontProps['font-family'];
let fontWeight = fontProps['font-weight'];
let fontStyle = fontProps['font-style'];
let fontUrl = Array.isArray(fontProps['src']) ? fontProps['src'][0][0] : fontProps[
'src'];
if (fontUrl.indexOf('url(') === -1) {
fontUrl = 'url(' + fontUrl + ')';
}
let fontFormat = fontProps['src'][0][1] ? fontProps['src'][1] : '';
const font = new FontFace(fontFamily, fontUrl);
font.weight = fontWeight;
font.style = fontStyle;
await font.load();
document.fonts.add(font);
console.log(fontFamily, 'loaded')
// apply font styles to invisible elements
let fontDOMEl = document.createElement('div');
fontDOMEl.textContent = '';
document.body.appendChild(fontDOMEl);
fontDOMEl.setAttribute(
"style",
`position:fixed; height:0; width:0; overflow:hidden; font-family:${fontFamily}; font-weight:${fontWeight}; font-style:${fontStyle}`
);
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.0/fabric.min.js"></script>
<canvas width="300" height="300" id="canvas"></canvas>
loadFonts() will append invisible elements to your DOM with the desired font-families applied.
This will ensure the loaded fonts are also available for canvas elements.

Related

Image in Canvas get cropped only on chrome

I am using PIXIjs to draw and modify large size Image! for large size image the image get cropped as following:
but on firefox is totally okay:
I saw something as following on DEVtool-chrome that I think it might be reason for this and tried to override this but does not work:
I would like to have the full image as firefox on chrome as well!
here is js:
private drawImage(): void {
PIXI.Loader.shared.reset();
const frame = document.querySelector('#frame');
const url = this.urlInputImage;
this.removeAllChildNodes(frame);
const app = new PIXI.Application({
backgroundColor: 0xffffff,
});
const container = new PIXI.Container();
app.stage.interactive = true;
app.stage.on('rightclick', e =>{
this.contextmenuClick.emit(e);
this.rightClick(e);
});
const graphics = new PIXI.Graphics();
this.detectedPositions.forEach((detectedInfo) => {
const boundingBox = detectedInfo['boundingBox'];
graphics.lineStyle(/*border width*/5,/*border color*/ PIXI.utils.string2hex(detectedInfo['detectionBoxesHexColor']), 1);
const points = Object.keys(boundingBox).map(function(boundingBoxIndex){
return boundingBox[boundingBoxIndex];
});
const pointsFiltered = points.filter((point) => {
return point !== null;
});
graphics.drawPolygon(pointsFiltered);
graphics.endFill();
});
PIXI.Loader.shared
.add('layout',url)
.load(setup);
function setup() {
const pic = new PIXI.Sprite(PIXI.Loader.shared.resources.layout.texture);
const border = new PIXI.Graphics();
const borderWidth = 5;
const borderColor = 1261722;
border.lineStyle(borderWidth, borderColor);
border.drawRect(app.stage.x , app.stage.y , pic.width , pic.height );
container.addChild(pic);
container.addChild(border);
container.addChild(graphics);
app.stage.addChild(container);
const w = pic.width;
const h = pic.height;
app.renderer.view.style.width = w + "px";
app.renderer.view.style.height = h + "px";
//this part adjusts the ratio:
app.renderer.resize(w, h);
}
frame.appendChild(app.view);
PIXI.BaseTexture.removeFromCache('layout');
}
here is the css:
:host {
display: block;
}
canvas {
background-color: white;
}
#frame {
overflow: auto;
background-color: white;
height: 450px;
width: auto;
}`
here is html
<div id="frame"></div>

Downloading QRCode in SVG

I'm using the EasyQRCodeJS plugin but I am finding it hard to download/save the QR Code to my device in an SVG format.
Here's the code I am using. It's creating and displaying the QR Code fine displaying but the file will not open so I am doing someone incorrectly.
// Options
var options = {
text: "https://github.com/ushelp/EasyQRCodeJS",
width: 200,
height: 200,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H, // L, M, Q, H
logo: "https://assets.website-files.com/6130bd1fcd31de20d9599493/627b6e7e75f1c5ef5f36ff22_customjava.svg",
logoWidth: 50, // fixed logo width. default is width/3.5
logoHeight: 50, // fixed logo height. default is heigth/3.5,
crossOrigin : 'anonymous',
quietZone: 0,
quietZoneColor: "rgba(0,0,0,0)",
drawer: 'svg',
logoBackgroundColor: '#fffff', // Logo backgroud color, Invalid when logBgTransparent is true; default is '#ffffff'
logoBackgroundTransparent: false, // Whether use transparent image, default is false
};
// Create QRCode Object
new QRCode(document.getElementById("qrcode"), options);
function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
document.getElementById("button").addEventListener("click", function(){
/* alert(QRCode); */
var text = QRCode;
var filename = "qrcode.svg";
download(filename, text);
}, false);
<script src="https://cdn.jsdelivr.net/npm/easyqrcodejs#4.4.12/dist/easy.qrcode.min.js"></script>
<div id="qrcode"></div>
<input type="button" id="button" value="Download" />
var text = QRCode; won't return your svg code but the QRCode object.
Add a element variable and fetch it's innerHTML like so:
var text = qrcodeEl.innerHTML;
Example
// Options
var options = {
text: "https://github.com/ushelp/EasyQRCodeJS",
width: 200,
height: 200,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H, // L, M, Q, H
logo: "https://assets.website-files.com/6130bd1fcd31de20d9599493/627b6e7e75f1c5ef5f36ff22_customjava.svg",
logoWidth: 50, // fixed logo width. default is width/3.5
logoHeight: 50, // fixed logo height. default is heigth/3.5,
crossOrigin: "anonymous",
quietZone: 0,
quietZoneColor: "rgba(0,0,0,0)",
drawer: "svg",
logoBackgroundColor: "#fffff", // Logo backgroud color, Invalid when logBgTransparent is true; default is '#ffffff'
logoBackgroundTransparent: false // Whether use transparent image, default is false
};
const qrcodeEl = document.getElementById("qrcode");
const QR = new QRCode(qrcodeEl, options);
function download(filename, text) {
var element = document.createElement("a");
console.log(text);
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
document.getElementById("button").addEventListener(
"click",
function() {
/* alert(QRCode); */
var text = qrcodeEl.innerHTML;
console.log(text)
var filename = "qrcode.svg";
download(filename, text);
},
false
);
<script src="https://cdn.jsdelivr.net/npm/easyqrcodejs#4.4.12/dist/easy.qrcode.min.js"></script>
<div id="qrcode"></div>
<input type="button" id="button" value="Download" />
Download won't work in SO snippet due to security settings.
Embed logo svg
This will only work if you're using a data URL for your logo.
External logo svgs will most likely not work due to CORS policies.
If logos are on the same domain you might use an ajax fetch() to retrieve all data.
I've converted the logo with Yoksel's URL-encoder for svg.
// getTransformToElement polyfill
SVGElement.prototype.getTransformToElement =
SVGElement.prototype.getTransformToElement ||
function (toElement) {
return toElement.getScreenCTM().inverse().multiply(this.getScreenCTM());
};
// Options
var options = {
text: "https://github.com/ushelp/EasyQRCodeJS",
width: 200,
height: 200,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H, // L, M, Q, H
logo:
"data:image/svg+xml,%3Csvg width='441' height='352' viewBox='0 0 441 352' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M26.0869 35.7268V26.0865H35.8516V7.65674H7.65723V35.7268H26.0869ZM26.0869 58.8637H7.65723V78.1444H26.0869V58.8637ZM26.0869 101.281H7.65723V120.562H26.0869V101.281ZM26.0869 143.699H7.65723V162.98H26.0869V143.699ZM26.0869 186.117H7.65723V205.397H26.0869V186.117ZM26.0869 228.534H7.65723V247.815H26.0869V228.534ZM26.0869 270.952H7.65723V290.232H26.0869V270.952ZM26.0869 313.369H7.65723V341.439H35.8516V323.01H26.0869V313.369ZM59.2869 323.01V341.439H78.8162V323.01H59.2869ZM102.251 323.01V341.439H121.781V323.01H102.251ZM145.216 323.01V341.439H164.745V323.01H145.216ZM188.181 323.01V341.439H207.71V323.01H188.181ZM231.145 323.01V341.439H250.675V323.01H231.145ZM274.11 323.01V341.439H293.639V323.01H274.11ZM317.074 323.01V341.439H336.604V323.01H317.074ZM360.039 323.01V341.439H379.568V323.01H360.039ZM403.004 323.01V341.439H431.198V313.369H412.768V323.01H403.004ZM412.768 290.232H431.198V270.952H412.768V290.232ZM412.768 247.815H431.198V228.534H412.768V247.815ZM412.768 205.397H431.198V186.117H412.768V205.397ZM412.768 162.98H431.198V143.699H412.768V162.98ZM412.768 120.562H431.198V101.281H412.768V120.562ZM412.768 78.1445H431.198V58.8638H412.768V78.1445ZM412.768 35.7269V26.0865H403.004V7.65674H431.198V35.7269H412.768ZM379.568 26.0865V7.65674H360.039V26.0865H379.568ZM336.604 26.0865V7.65674H317.074V26.0865H336.604ZM293.639 26.0865V7.65674H274.11V26.0865H293.639ZM250.675 26.0865V7.65674H231.145V26.0865H250.675ZM207.71 26.0865V7.65674H188.181V26.0865H207.71ZM164.745 26.0865V7.65674H145.216V26.0865H164.745ZM121.781 26.0865V7.65674H102.251V26.0865H121.781ZM78.8162 26.0865V7.65674H59.2869V26.0865H78.8162Z' fill='%235836F5'/%3E%3Crect x='80.377' y='76.5498' width='274.398' height='196.547' fill='%235836F5'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M167.67 122.48L177.04 133.328L133.073 171.309L176.976 208.345L167.734 219.301L110.996 171.438L167.67 122.48Z' fill='white'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M268.656 122.48L259.286 133.328L303.253 171.309L259.35 208.345L268.593 219.301L325.33 171.438L268.656 122.48Z' fill='white'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M187.544 234.91L237.714 103.343L251.107 108.45L200.937 240.018L187.544 234.91Z' fill='%23C9BFFC'/%3E%3Ccircle cx='419.042' cy='20.9894' r='20.9894' fill='%235836F5'/%3E%3Ccircle cx='20.9894' cy='20.9894' r='20.9894' fill='%235836F5'/%3E%3Ccircle cx='419.042' cy='331.011' r='20.9894' fill='%235836F5'/%3E%3Ccircle cx='20.9894' cy='331.011' r='20.9894' fill='%235836F5'/%3E%3C/svg%3E%0A",
logoWidth: 50, // fixed logo width. default is width/3.5
logoHeight: 50, // fixed logo height. default is heigth/3.5,
crossOrigin: "anonymous",
quietZone: 0,
quietZoneColor: "rgba(0,0,0,0)",
drawer: "svg",
logoBackgroundColor: "#fffff", // Logo backgroud color, Invalid when logBgTransparent is true; default is '#ffffff'
logoBackgroundTransparent: false // Whether use transparent image, default is false
};
const qrcodeEl = document.getElementById("qrcode");
new QRCode(qrcodeEl, options);
function download(filename, text) {
var element = document.createElement("a");
console.log(text);
element.setAttribute(
"href",
"data:text/plain;charset=utf-8," + encodeURIComponent(text)
);
element.setAttribute("download", filename);
element.style.display = "none";
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
document.getElementById("button").addEventListener(
"click",
function () {
//embed logo
embedLogo();
var text = qrcodeEl.innerHTML;
console.log(text);
var filename = "qrcode.svg";
download(filename, text);
},
false
);
function embedLogo() {
let qrSVG = document.querySelector("svg");
let logo = qrSVG.querySelector("image");
let imgTrans = logo.getAttribute("transform");
let imgWidth = logo.getAttribute("width");
let imgHeight = logo.getAttribute("height");
//convert data url to svg
let logoSrc = logo
.getAttribute("xlink:href")
.replaceAll("data:image/svg+xml,", "")
.replaceAll("%3C", "<")
.replaceAll("%3E", ">")
.replaceAll("%3C/", "/")
.replaceAll("%0A", "\n")
.replaceAll("%23", "#");
// append logo svg
let logogroup = document.createElementNS("http://www.w3.org/2000/svg", "g");
qrSVG.appendChild(logogroup);
logogroup.innerHTML = logoSrc;
let logoEmbedded = logogroup.querySelector("svg");
logoEmbedded.setAttribute("width", imgWidth);
logoEmbedded.setAttribute("height", imgHeight);
logogroup.setAttribute("transform", imgTrans);
//convert nesest logo svg to group
nestedSvgToGroup(logoEmbedded);
logogroup.removeAttribute("transform");
logo.remove();
}
/**
* convert nested svg to embedded g
*/
function nestedSvgToGroup(svg, groupMatrix = 0) {
let svgSub = svg;
if (svg.parentNode) {
let parent = svg.parentNode.closest("svg");
let svgSubChildren = [...svgSub.children];
groupMatrix = groupMatrix ? groupMatrix : transFormToMatrix(svgSub);
//replace nested svg with group - apply matrix
let group = document.createElementNS("http://www.w3.org/2000/svg", "g");
group.classList.add("svgNest");
group.setAttribute("transform", `matrix( ${groupMatrix} )`);
//copy children to group
svgSubChildren.forEach(function (child, i) {
group.appendChild(child);
});
//remove nested svg
svgSub.replaceWith(group);
}
}
function transFormToMatrix(el) {
let type = el.nodeName.toLowerCase();
let matrixString = "";
let types = [
"path",
"polygon",
"polyline",
"rect",
"ellipse",
"circle",
"line",
"text",
"g",
"svg"
];
if (types.indexOf(type) !== -1) {
// get el matrix
let matrix = el.getTransformToElement(el.parentNode.closest("svg"));
let [a, b, c, d, e, f] = [
matrix.a,
matrix.b,
matrix.c,
matrix.d,
matrix.e,
matrix.f
];
matrixString = [a, b, c, d, e, f].join(" ");
//exclude non transformed elements
if (matrixString != "1 0 0 1 0 0") {
el.setAttribute("transform", `matrix(${matrixString})`);
el.removeAttribute("transform-origin");
}
}
return matrixString;
}
<script src="https://cdn.jsdelivr.net/npm/easyqrcodejs#4.4.12/dist/easy.qrcode.min.js"></script>
<div id="qrcode"></div>
<p><input type="button" id="button" value="Download" /></p>
How it works
convert your logo to a data url and add it to your option
embedLogo() helper will add a nested svg to the parent QRcode svg
nestedSvgToGroup() will translate transformations to a matrix()
<image> is removed
Codepen Example
See also: Issues with conversion of svg element to .svg

BLOTTER.JS why does the first loading of my index.html default to serif font instead of my custom font 'auth'?

when I first load index.html the blotter text defaults to serif. when I refresh it once it switches to my custom 'auth' font and stays as that font with each subsequent refresh
<div id="title"></div>
my css
#font-face{
font-family: 'helvetica';
src: url(helvetica.ttf);
font-family: 'auth';
src: url(auth.otf);
}
javascript
var text = new Blotter.Text("~DAISY CHAIN~", {
family : "auth",
size : 150,
fill : "#000000",
paddingLeft : 120,
paddingRight :120
});
text.needsUpdate = true;
var material = new Blotter.LiquidDistortMaterial();
material.uniforms.uSpeed.value = 0.3;
material.uniforms.uVolatility.value = .1;
material.uniforms.uSeed.value = .10;
var blotter = new Blotter(material, {
texts : text
});
var elem = document.getElementById("title");
var scope = blotter.forText(text);
scope.appendTo(elem);
document.onmousemove = function distort(){
material.uniforms.uVolatility.value = (event.clientY * .0006);;
}

How to add click event to each surface with specific effects, unable to add modifier

How to add click event to each surface with specific effects, I am not able to add modifier.
I tried below code but its not working. I am unable to add StateModifier to each surface.
Please help me to solve this problem as soon as possible.
var Engine = require("famous/core/Engine");
var Surface = require("famous/core/Surface");
var View = require("famous/core/View");
var Scrollview = require("famous/views/Scrollview");
var ContainerSurface = require("famous/surfaces/ContainerSurface");
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var context = Engine.createContext();
var myModifier = new StateModifier({
Transform: Transform.translate(0, 100, 1)
});
var surfaces1 = [];
var scrollers = [];
var scroll_h1_cont = new ContainerSurface({
size: [window.innerWidth, 100],
properties: {
overflow: 'hidden'
}
});
var scroll_h1 = new Scrollview({
direction: 0
});
scroll_h1.sequenceFrom(surfaces1);
scroll_h1_cont.add(scroll_h1);
scrollers.push(scroll_h1_cont);
for (var i = 0; i < 9; i++) {
var surface1 = new Surface({
content: "Surface: " + (i + 1),
size: [window.innerWidth / 3, 100],
properties: {
backgroundColor: "hsl(" + (i * 360 / 8) + ", 100%, 50%)",
lineHeight: "100px",
textAlign: "center"
}
});
surface1.pipe(scroll_h1);
surfaces1.push(surface1);
surface1.pipe(myModifier);
};
context.add(scroll_h1_cont);
Any suggestions?
This should at least get your scrollview working.
/* globals define */
define(function(require, exports, module) {
'use strict';
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Scrollview = require('famous/views/Scrollview');
var context = Engine.createContext();
var surfaces = [];
// create ScrollView
var scrollview = new Scrollview({
direction: 0
});
// create 100 surfaces and add them into array
for (var i = 0; i < 9; i++) {
var temp = new Surface({
content: 'Surface: ' + (i + 1),
size: [undefined, 100],
properties: {
backgroundColor: 'hsl(' + (i * 360 / 40) + ', 100%, 50%)',
lineHeight: '100px',
textAlign: 'center'
}
});
temp.pipe(scrollview);
surfaces.push(temp);
}
// add array of surfaces into ScrollView
scrollview.sequenceFrom(surfaces);
// add ScrollView into context
context.add(scrollview);
});

using canvas kinetic in html5 to draw many text and edit them

When I click the text on a card, I want to be able to edit the text like this website:
http://www.vistaprint.com/vp/ns/studio3.aspx?pf_id=064&combo_id=120585&free_studio_gallery=true&referer=http%3a%2f%2fwww.vistaprint.com%2fvp%2fns%2fdefault.aspx%3fdr%3d1%26rd%3d1%26GNF%3d0%26GP%3d5%252f19%252f2012%2b12%253a36%253a37%2bAM%26GPS%3d2448654652%26GNF%3d1%26GPLSID%3d&rd=1
Here is my code:
$(document).ready(function () {
var Total_layers = 0;
var Text = {};
/*set up stage for drawing image*/
var stage = new Kinetic.Stage({
container: "container",
width: 600,
height: 400
});
// var Layer = {};
/*create a layer object for placing text image over it and place it over the stage*/
var layer = new Kinetic.Layer();
//Layer[Total_layers]
/*Text Property*/
var New_Text = "Company Name";
var Text_Font = "Arial";
var Text_Color = "Black";
var Text_Size = "30";
var Text_Pos_X = 200;
var Text_Pos_y = 100;
var Selected_Text = new Kinetic.Text({});
var current_layer = 0;
// var text_selected = 1;
/*Add event for them*/
//var formElement = document.getElementById("New Text");
// formElement.addEventListener('change', Text_Changed, false);
var formElement = document.getElementById("selectFontSize");
formElement.addEventListener('change', Text_Size_Changed, false);
/*This Function will be Executed when the Size of the Text in consideration is changed*/
function Text_Size_Changed(e) {
var target = e.target;
Text_Size = target.value;
Text_Pos_X = 200; //Text[Total_layers].x;
Text_Pos_Y = 100; //Text[Total_layers].y;
//DeleteLayer(Total_layers);
layer.remove(Selected_Text);
Draw_text(Total_layers);
}
/*Function to swap the Kinetic Text object and get the selected Text object to The Top*/
function swap_layers(Selected_text) {
var temp = new Kinetic.Text({});
for (var i = 1; i <= Total_layers; i++) {
if (Text[i] == Selected_text) {
temp = Text[i];
Text[i] = Text[Total_layers];
Text[Total_layers] = temp;
break;
}
}
}
/*Add different Events to the Text objects once They are instantiated*/
function add_events(dest_Text) {
dest_Text.on("mouseover", function () {
document.body.style.cursor = "pointer";
});
dest_Text.on("mouseout", function () {
document.body.style.cursor = "default";
});
dest_Text.on("click", function () {
$("#selectFontSize").change(function () {
dest_Text.setFontSize($("#selectFontSize").val());
layer.draw(); // vì gọi layer.draw nên tất cả text trong layer đó đều dc vẽ lại
});
$("#selectFontFamily").change(function () {
swap_layers(dest_Text);
//dest_Text.setFontFamily($("#selectFontFamily").val());
//layer.draw();
});
});
}
/*Draw the Text over the layer depening upon the Text_object_Number*/
function Draw_text(Text_object_Number) {
/*Set the Properties of the Topmost object that is been modified and which will be added to the layer*/
Text[Text_object_Number] = new Kinetic.Text({
x: Text_Pos_X,
y: Text_Pos_Y,
text: New_Text,
fontSize: Text_Size,
fontFamily: Text_Font,
textFill: Text_Color,
align: "center",
verticalAlign: "middle",
draggable: "true"
});
/*Adds all the Text objects onto the layer and adds the events to every Text object */
//for (var i = 1; i <= Text_object_Number; i++) {
layer.add(Text[Text_object_Number]);
add_events(Text[Text_object_Number]);
//}
stage.add(layer);
}
$("#add_text").click(function () {
Total_layers++;
Text[Total_layers] = new Kinetic.Text({
x: Text_Pos_X,
y: Text_Pos_y,
text: New_Text,
fontSize: 30,
fontFamily: Text_Font,
textFill: Text_Color,
align: "center",
verticalAlign: "middle",
draggable: "true"
});
add_events(Text[Total_layers]);
layer.add(Text[Total_layers]);
stage.add(layer);
});
/*Adding an image to the present Context*/
var imageObj = new Image();
//alert("abc");
imageObj.onload = function () {
var T_shirt = new Kinetic.Image({
x: 60,
y: 0,
image: imageObj,
width: 550,
height: 400,
name: "image"
});
layer.add(T_shirt);
stage.add(layer);
}
imageObj.src = "../../Content/Image/imagepreview1.jpg";
});
I have tried many ways, but I still can't resolve this problem.
How can I do this by using canvas kineticjs in html5?
The very best solution imho is to use a simple JavaScript prompt:
myText.on('click', function(evt) {
this.setText(prompt('New Text:'));
layer.draw(); //redraw the layer containing the textfield
});
See my answer in this thread: editable Text option in kinetic js
You can't edit the text directly on the canvas, but what you can do is change it with events. So what you need is an input form that is created next to the canvas, and you can read from the form using javascript.
<input type=text id=changeText/>
this way when you click on some text a new input tag will appear and you can type in it and the text inside of the canvas will change as you type.
mytext.on('click', function(){ ... create new input element at the side ... });
//add some jQuery
$('#changeText').onchange( mytext.setText($('$changeText').val()));

Categories