React.JS calculating img width in virtual DOM - javascript

I'm trying to find the width of an <img> to center it via JavaScript.
Trying to calculate the width of this react.js DOM node returns 0.
var Player = React.createClass({
componentDidMount:function(){
var imgEl = this.refs.imgSize.getDOMNode();
console.log(imgEl.offsetWidth);
},
render: function () {
return (
<img ref="imgSize" src={this.props.imageURL} />
);
}
});

You could use the image's onLoad event to make sure it's loaded before you try this:
<script src="http://fb.me/react-0.12.2.js"></script>
<script src="http://fb.me/JSXTransformer-0.12.2.js"></script>
<script type="text/jsx;harmony=true">void function() { "use strict";
var Player = React.createClass({
_onLoad(e) {
console.log(e.target.offsetWidth)
},
render() {
return <img src={this.props.imageURL} onLoad={this._onLoad}/>
}
})
React.render(<Player imageURL="http://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg"/>, document.body)
}()</script>

I wrote a React library that exposes a size object (with width and height props) to your components.
You can use it like so for your use case:
var SizeMe = require('react-sizeme');
var Player = React.createClass({
componentDidMount:function(){
var imgEl = this.refs.imgSize.getDOMNode();
console.log(imgEl.offsetWidth);
},
render: function () {
// height and width via props!!
var width = this.props.width;
var height = this.props.height;
return (
<img ref="imgSize" src={this.props.imageURL} />
);
}
});
// Wrap your component with the SizeMe HOC!
module.exports = SizeMe()(Player);
Demo: https://react-sizeme-example-esbefmsitg.now.sh/
Github: https://github.com/ctrlplusb/react-sizeme

Related

Polymer Element Error by displaying Image inside FabricJS Canvas

I'm trying to display an Image on the FabricJS Canvas inside my Polymer Element. By doing this, this error appears:
Uncaught TypeError: Cannot read property '_set' of undefined
at klass._onObjectAdded (fabric.js:6964)
at klass.add (fabric.js:260)
at HTMLElement.ready (convert-section.html:97)
at HTMLElement._enableProperties (property-accessors.html:531)
at HTMLElement.connectedCallback (element-mixin.html:630)
at HTMLElement._attachDom (element-mixin.html:690)
at HTMLElement._readyClients (element-mixin.html:663)
at HTMLElement._flushClients (property-effects.html:1518)
at HTMLElement._propertiesChanged (property-effects.html:1644)
at HTMLElement._flushProperties (property-accessors.html:549)
Is it possible to display an Image on a FabricJs canvas inside my Polymer Element? Or did I made an misstake? I'm new to Polymer and I don't have much experience.
I can display shapes like triangles etc.
Here is my Element:
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="my-paper-element-styles.html">
<dom-module id="convert-section">
<template>
<style include="my-paper-element-styles">
</style>
<canvas id="convertCanvas" ></canvas>
</template>
<script>
class ConvertSection extends Polymer.Element {
static get is() {
return 'convert-section';
}
static get properties() {
return {
imageLocationPath: {
type: String,
notify: true
}
};
}
disconnectedCallback() {
super.disconnectedCallback();
this.imageLocationPath = "";
}
ready() {
super.ready();
this.canvas = this.__canvas = new fabric.Canvas(this.$.convertCanvas);
var height = window.innerHeight - 48;
var width = window.innerWidth - 300;
this.canvas.setHeight(height);
this.canvas.setWidth(width);
var image = fabric.Image.fromURL('img/viper-board.png');
this.canvas.add(image);
}
}
window.customElements.define(ConvertSection.is, ConvertSection);
</script>
<script src="../../node_modules/fabric/dist/fabric.js"></script>
</dom-module>
ready() {
super.ready();
var self = this;
self.canvas = self.__canvas = new fabric.Canvas(self.$.convertCanvas);
var height = window.innerHeight - 48;
var width = window.innerWidth - 300;
self.canvas.setHeight(height);
self.canvas.setWidth(width);
fabric.Image.fromURL('img/viper-board.png',function(oImg){
oImg.set({
left:10,
top:10
});
self.canvas.add(oImg);
});
}
As you can see fromURL doesn't return anything. You need to pass source url and a callback function and add that image inside callback function.

Use Onload on image tag in ember

I have a template in which photos are being displayed in a frame ( each frame is different for different images) .I have written a function which uses the images original height and width and gives me customized width and height for that particular frame inorder to restore the aspect ratio.Now I have called that function through onload as images loads on that particular moment.
My feed.hbs( template)
<img src = "{{photo.0.photo_url}}" onload = "OnImageLoad(event);" {{action "imgOverlay0" photo}}/>
Function
function OnImageLoad(evt) {
var img = evt.currentTarget;
// what's the size of this image and it's parent
var w = $(img).width();
var h = $(img).height();
var tw = $(img).parent().width();
var th = $(img).parent().height();
// compute the new size and offsets
var result = scaling(w, h, tw, th,false);
// adjust the image coordinates and size
img.width = result.width;
img.height = result.height;
$(img).css("margin-left", result.targetleft);
$(img).css("margin-top", result.targettop);
// console.log("result",result)
return result;
}
function scaling (w, h, tw, th,false){
//manipulation with data
}
But it will not be included in the build of ember as I have kept the function file in bower_compontent.How do I include it in my ember app ?
Instead of creating a bower component, I'd create a few ember components: one that triggers an action when the image is loaded, and another that handles scaling.
app/components/x-image/component.js
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'img',
didInsertElement() {
this._super(...arguments);
this.$()[0].onload = () => {
this.sendAction('imageLoaded');
};
},
});
app/components/scaled-image/component.js
import Ember from 'ember';
export default Ember.Component.extend({
setImageDimensions() {
const img = this.$('img');
// what's the size of this image and it's parent
const w = img.width();
const h = img.height();
const tw = img.parent().width();
const th = img.parent().height();
// compute the new size and offsets
const result = this.scaling(w, h, tw, th, false);
// adjust the image coordinates and size
img.width = result.width;
img.height = result.height;
img.css("margin-left", result.targetleft);
img.css("margin-top", result.targettop);
// console.log("result",result)
},
scaling(w, h, tw, th,false) {
//manipulation with data
},
actions: {
imageLoaded() {
this.setImageDimensions();
}
}
});
app/components/scaled-image/template.hbs
{{x-image
src=src
imageLoaded=(action 'imageLoaded')
}}
In-use in a template
{{scaled-image
src=photo.0.photo_url
action=(action "imgOverlay0" photo)
}}
It will be better to put this javascript file in vendor directory because normally bower_components is included in .gitignore.
Say you put this code in vendor/file-onload.js.
Then do a import in ember-cli-build.js
app.import('vendor/file-onload.js');
It will be even easier if you put these functions in corresponding feed controller.

How can overwrite this calculation?JQuery

I have this site:
link
I have two pages that contain the same divs... on a page I want to be a calculation (to div) on another page another calculation..,
CODE JS:(NEW)
jQuery(document).ready(function ($) {
var windowsizecontact = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
console.log("ecran contact:",windowsizecontact);
var stanga= jQuery('.contact-stanga').outerWidth();
console.log("latime-stanga:",stanga);
var dreapta= jQuery('.contact-dreapta').outerWidth();
console.log("latime-dreapta:",dreapta);
var contentcontactwh=windowsizecontact-stanga-dreapta;
console.log("rezultat",contentcontactwh);
$('.contact-container #primary').css{('cssText', contentcontactwh'!important')}; //here I want to overide this div
});
This is old code (which must remain and apply only on certain pages)
jQuery(document).ready(function ($) {
var latime= Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var _stanga= jQuery('#secondary').outerWidth();
var selectat= jQuery('.selectat').outerWidth();
var calcul=latime-_stanga-selectat;
$('#primary').css('width', calcul);
});
My problem is that the new code (from above) does not apply to div on the contact page because old code ... and I need to do to be unique. (Old code should remain as )
It can override somehow?
EDIT:
jQuery(document).ready(function ($) {
var windowsizecontact = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
console.log("ecran contact:",windowsizecontact);
var stanga= jQuery('.contact-stanga').outerWidth();
console.log("latime-stanga:",stanga);
var dreapta= jQuery('.contact-dreapta').outerWidth();
console.log("latime-dreapta:",dreapta);
var contentcontactwh=windowsizecontact-stanga-dreapta;
console.log("rezultat",contentcontactwh);
console.log("------------------");
if ($("#primary").hasClass("content-contact")) {
alert("ggg");
$('.content-contact').css("width:",contentcontactwh); //here now is problem
}else
{
var latime= Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
var _stanga= jQuery('#secondary').outerWidth();
console.log("latime-stanga:",_stanga);
var selectat= jQuery('.selectat').outerWidth();
console.log("latime-stanga:",_stanga);
var calcul=latime-_stanga-selectat;
$('#primary').css('width', calcul);
}
});
I tried the first option suggested ... but now not only apply div width of my.
I've done wrong syntax?
var app = app || {};
app.readyFunction = function () {
// normal
};
// on website you want to overwrite
app.readyFunction = function () {
// altCode
};
// and in document ready just call
$(function () {
app.readyFunction();
});
If al the rest works and if the problem is only in this line then lets change this line a bit.
this
$('.content-contact').css("width:",contentcontactwh); //try removing the : after width
to
$('.content-contact').css("width",contentcontactwh);
Also please provide the console error message if this does not work.

Working with ReactJS and HTML5 Canvas

I have a root component that renders <Particle /> components and <Particle /> component render function is:
render: function(){
var data = this.props.data,
canvas = document.createElement('canvas'),
context;
canvas.style.position = 'absolute';
canvas.style.top = data.y + 'px';
canvas.style.left = data.x + 'px';
context = canvas.getContext('2d');
context.drawImage(data.img, data.x, data.y, data.tileSize, data.tileSize, 0, 0, data.tileSize, data.tileSize);
return canvas;
}
And this returns the following error:
Uncaught Error: Invariant Violation: Particle.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
I had a look at Flipboard's react-canvas but I couldn't find any good examples similar to my situation.
So any help would be much appreciated.
You should just return a single canvas element with a reference to it. This element is not the same as a DOM node; React transforms it into a React Component using JSX:
render: function() {
return <canvas ref="canvas" />
}
Then modify it inside a lifecycle method:
componentWillReceiveProps: function() {
var canvas = React.findDOMNode(this.refs.canvas);
canvas.style.position = 'absolute';
// etc ...
}
You could also set some inline style attributes inside the render:
render: function() {
var styles = {
position: 'absolute',
top: this.props.data.y,
left: this.props.data.x
}
return <canvas ref="canvas" style={styles} />
}
...but the context/drawimage would be best to put in a lifecycle method since you need access to the dom node.

Autoscaling an svg on window resize

I have this code:
function myClient() {
if (!(this instanceof arguments.callee)) {
return new arguments.callee(arguments);
}
var self = this;
this.init = function() {
self.viewResized();
self.drawSvg();
};
this.viewResized = function () {
var width = $('body').width(),
windowHeight = $(window).height(),
svgCanvasHeight = width * (369.0 / 567.0);
$('#svg').css({
'margin-top': 10
});
}
this.drawSvg = function() {
// ...
}
var myClient;
jQuery(function() {
myClient = new myClient();
$(window).resize(function() {
console.log("window resized");
myClient.viewResized();
});
});
How do I get the svgCanvasHeight in drawSvg dynamically so that when the window is resized, so does the svg's viewBox and svg?
Answered here: Get the real size of a SVG/G element
With regards to viewBox:
I have had a lot of problems with SVG and jQuery.
While html attributes are case-insensitive the svg ones (like viewBox) aren't. I'd try using the element.setAttribute(name, value) native JS function. This worked for me, and make sure you're using viewBox with the capital B.

Categories

Resources