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
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.
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.
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.
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.
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.