I am using the Telerik RadEditor and am seeing some strange behavior with the Image Manager window, shown below.
The tabs such as SiteCopy, Body Setup, Header Setup, etc. are all from the page that should be behind the window, yet they are somehow showing through. Clicking and dragging the window to another location on the screen fixes that issue, however, the window cannot be closed using either the X or Cancel. This only seems to happen in Chrome when I am zoomed in a bit on the page. Is this a bug with the Image Manager or is there something that can be done to prevent this behavior?
Thanks
Try the ideas from this thread: http://www.telerik.com/community/forums/button-click-fails-(sometimes)
Chrome 39 broke the internet again because it started returning decimal values for properties that used to be integers, which can cause script errors.
Try the following:
use a RadScriptManager on the main page
The script override from the thread abocve could be the solution you are looking for:
if (document.documentElement.getBoundingClientRect) {
$telerik.originalGetLocation = function (element) {
var e = Function._validateParams(arguments, [
{ name: "element", domElement: true }
]);
if (e) throw e;
if (element.self || element.nodeType === 9 ||
(element === document.documentElement) ||
(element.parentNode === element.ownerDocument.documentElement)) {
return new Sys.UI.Point(0, 0);
}
var clientRect = element.getBoundingClientRect();
if (!clientRect) {
return new Sys.UI.Point(0, 0);
}
var documentElement = element.ownerDocument.documentElement,
offsetX = Math.round(clientRect.left) + documentElement.scrollLeft,
offsetY = Math.round(clientRect.top) + documentElement.scrollTop;
if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
try {
var f = element.ownerDocument.parentWindow.frameElement || null;
if (f) {
var offset = (f.frameBorder === "0" || f.frameBorder === "no") ? 2 : 0;
offsetX += offset;
offsetY += offset;
}
}
catch (ex) {
}
if (Sys.Browser.version === 7 && !document.documentMode) {
var body = document.body,
rect = body.getBoundingClientRect(),
zoom = (rect.right - rect.left) / body.clientWidth;
zoom = Math.round(zoom * 100);
zoom = (zoom - zoom % 5) / 100;
if (!isNaN(zoom) && (zoom !== 1)) {
offsetX = Math.round(offsetX / zoom);
offsetY = Math.round(offsetY / zoom);
}
}
if ((document.documentMode || 0) < 8) {
offsetX -= documentElement.clientLeft;
offsetY -= documentElement.clientTop;
}
}
offsetX = Math.round(offsetX);
offsetY = Math.round(offsetY);
return new Sys.UI.Point(offsetX, offsetY);
};
}
Related
I use a script for moving an object both with mouse and touch screen. This works.
I have another script to make the object rotate 90 degrees with each click, this also works.
It just doesn't work together.
When I merge them, the move still works, but with a click the object moves back to the starting position and only rotates there.
I've read that I should merge this but I don't know how. Below both scripts.
Thanks in advance for responses.
var container = document.querySelector("#container");
var activeItem = null;
var active = false;
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if (e.target !== e.currentTarget) {
active = true;
// this is the item we are interacting with
activeItem = e.target;
if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}
if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}
if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
console.log("doing something!");
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}
function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}
active = false;
activeItem = null;
}
function drag(e) {
if (active) {
if (e.type === "touchmove") {
e.preventDefault();
activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}
activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;
setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
// Make blocks rotate 90 deg on each click
var count=0;
function rot(e){
count++;
var deg=count*90;
e.style.transform = "rotate("+deg+"deg)";
}
So I put them in a file but then it only works as described above.
When uploading an image with image2 plugin, the height & width are initially set to the image's dimensions. Some of our users are uploading massive images and click OK to insert it onto the page without first choosing a reasonable size. The image fills the entire editor and they can't see what they're doing.
How can I set the initial size to something like 300px wide?
We're using CKEditor 4.11.1 with image2 plugin.
I was able to achieve this by hacking plugins/image2/dialog/image2.js and adding this to onChangeSrc() around line 148:
// Limit initial size
if (width > editor.config.image_initial_width) {
height = Math.round( editor.config.image_initial_width * ( height / width ) )
width = editor.config.image_initial_width;
}
if (height > editor.config.image_initial_height) {
width = Math.round( editor.config.image_initial_height * ( width / height) );
height = editor.config.image_initial_height;
}
and then defining config.image_initial_height=300 and config.image_initial_width=300.
But how can I achieve this without hacking?
Here's what worked for me.
Replace the image2 onChange event with our own, but keep a reference and call it.
Need to define two variables in config:
config.ckeditor_image2_initial_width = 300;
config.ckeditor_image2_initial_height = 300;
jQuery(document).ready(function() {
if (typeof CKEDITOR !== 'undefined') {
CKEDITOR.on('dialogDefinition', function(e) {
if (e.data.name == 'image2') {
var infoTab = e.data.definition.getContents('info');
var src_field = infoTab.elements[0].children[0].children[0];
var widthfield = infoTab.elements[2].children[0];
var height_field = infoTab.elements[2].children[1];
var src_was_changed = 0;
// Add a change function to the height field.
height_field.onChange = heightChanged;
// We need to add a change event to the src field but it already has
// one from image2 plugin. Replace it with our own but keep a reference
// and call it with CKEditor tools.
// https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_tools.html#method-override
src_field.onChange = CKEDITOR.tools.override(src_field.onChange, function(original) {
return function() {
// Call the original image2 onChangeSrc() function.
original.call(this);
var dialog = this.getDialog();
var widget_image_src = 0;
if (e.editor.widgets.selected.length) {
widget_image_src = e.editor.widgets.selected[0].data.src;
}
// Fire only when image src is set and has actually changed.
if (this.getValue() && (this.getValue() !== widget_image_src)) {
var initial_width = e.editor.config.ckeditor_image2_initial_width;
var initial_height = e.editor.config.ckeditor_image2_initial_height;
if (typeof initial_width !== 'undefined' || typeof initial_height !== 'undefined') {
// Set a flag to be used in heightChanged().
src_was_changed = 1;
}
}
}
});
// Change event for the image height field.
function heightChanged() {
if (src_was_changed) {
src_was_changed = 0;
var dialog = this.getDialog();
var initial_width = e.editor.config.ckeditor_image2_initial_width;
var initial_height = e.editor.config.ckeditor_image2_initial_height;
var width_field = dialog.getContentElement('info', 'width');
var height_field = dialog.getContentElement('info', 'height');
var new_width = orig_width = width_field.getValue();
var new_height = orig_height = height_field.getValue();
if (new_height > initial_height) {
new_height = initial_height;
new_width = Math.round(orig_width * (initial_height / orig_height));
}
if (new_width > initial_width) {
new_width = initial_width;
new_height = Math.round(orig_height * (initial_width / orig_width));
}
width_field.setValue(new_width);
height_field.setValue(new_height);
}
}
}
});
}
});
I read here that it was possible to display a message when the cursor is on a button of a promt. I looked a little on the net but I did not find what part of the botchat.js edit.
Can you teach me?
Thanks you
display a message when the cursor is on a button of a promt.
You could modify the botchat.js file to add title attribute to the button in order to shown it as a tooltip text when the mouse moves over the button, the following code snippet is for your reference.
Add add title attribute to actionButton element within ActionCollection.prototype.render function:
for (var i = 0; i < this.items.length; i++) {
if (isActionAllowed(this.items[i], forbiddenActionTypes)) {
var actionButton = new ActionButton(this.items[i]);
actionButton.element.style.overflow = "hidden";
actionButton.element.style.overflow = "table-cell";
actionButton.element.style.flex = this._owner.hostConfig.actions.actionAlignment === Enums.ActionAlignment.Stretch ? "0 1 100%" : "0 1 auto";
/*add title attribute to button*/
actionButton.element.title = this.items[i].title;
actionButton.text = this.items[i].title;
actionButton.onClick = function (ab) { _this.actionClicked(ab); };
this._actionButtons.push(actionButton);
buttonStrip.appendChild(actionButton.element);
this._renderedActionCount++;
if (this._renderedActionCount >= this._owner.hostConfig.actions.maxActions || i == this.items.length - 1) {
break;
}
else if (this._owner.hostConfig.actions.buttonSpacing > 0) {
var spacer = document.createElement("div");
if (orientation === Enums.Orientation.Horizontal) {
spacer.style.flex = "0 0 auto";
spacer.style.width = this._owner.hostConfig.actions.buttonSpacing + "px";
}
else {
spacer.style.height = this._owner.hostConfig.actions.buttonSpacing + "px";
}
Utils.appendChild(buttonStrip, spacer);
}
}
}
Test result:
I have created a simple function that would "animate" the cell backcolor at a tap, it works perfectly fine:
Color nOldColor = _grid.BackgroundColor;
for (int i = 0; i <= 100; i += 5)
{
double f = (double)i / (double)100;
Color nNewColor = PCLHelper.BlendColors(nOldColor, Color.Red, f);
_grid.BackgroundColor = nNewColor;
_label1.BackgroundColor = nNewColor;
await Task.Delay(5);
}
_grid.BackgroundColor = nOldColor;
_label1.BackgroundColor = nOldColor;
Now I wanted to do the same with an Animation, but the animation doesn't show the steps "in-between" but rather (as it looks to me) switches to the final color:
private async void animateButtonTouched()
{
int repeatCountMax = 100;
Color nOldColor = _grid.BackgroundColor;
var repeatCount = 0;
_grid.Animate("changeBG", new Animation((val) =>
{
double f = (double)repeatCount / (double)100;
Color nNewColor = PCLHelper.BlendColors(nOldColor, Color.Red, f);
_grid.BackgroundColor = nNewColor;
_label1.BackgroundColor = nNewColor;
}),
5, //duration. I've also tried it with 100. Nothing helped
finished: (val, b) =>
{
repeatCount++;
}, repeat: () =>
{
return repeatCount < repeatCountMax;
});
What am I doing wrong?
"You are making it more difficult than it needs to be." Trademark pending 🍣
The Animate callback is providing the stepping value (or keyframe value). This is a double from 0 to 1 that is called ever X milliseconds (i.e. the length of a single animation frame, 16 default) over the course of X milliseconds (250 default).
So in this example the ShiftToColor gets called 125 times (2000 / 16) with a value that is evenly divided from 0 to 1, thus steps of .008.
var orgColor = aFormsElementInstance.BackgroundColor;
aFormsElementInstance.Animate("changeBG", new Animation((val) =>
{
Color ShiftToColor(Color From, Color To, double pct)
{
var r = From.R + ((To.R - From.R) * val);
var g = From.G + ((To.G - From.G) * val);
var b = From.B + ((To.B - From.B) * val);
return new Color(r, g, b);
}
Device.BeginInvokeOnMainThread(() =>
{
aFormsElementInstance.BackgroundColor = ShiftToColor(orgColor, Color.Red, val);
});
}), 16, 2000);
Results in:
I've deliberately provided the version number in the question as this is the kind of question that will go out of date at some point.
Here is a simple animation that will run perfectly smoothly in Chrome and Safari, but will be very jerky in Firefox:
function lerp(a,b,λ) {
return a + λ*(b-a);
}
function random(a,b) {
return lerp( a, b, Math.random() );
}
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
$(document).ready( function()
{
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var balls = new Array(12);
for( var i=0; i<balls.length; i++ )
{
while(true)
{
var density = Math.sqrt( random(1,100) );
var r = random(5, 30);
var x = random( r+1, canvas.width-1 -(r+1) ),
y = random( r+1, canvas.height-1 -(r+1) );
var overlap = false;
for( var j=0; j<i; j++ )
{
var _x = balls[j].x - x,
_y = balls[j].y - y,
d2 = _x*_x + _y*_y,
_r = balls[j].r + r;
if( d2 < _r*_r )
overlap = true;
}
if( overlap )
continue;
balls[i] = {
color : d3.hsl( lerp(0,240,density/10), random(.3,.7), random(.3,.7) ).toString(),
x : x,
y : y,
vx : random(0, 0.2),
vy : random(0, 0.2),
r : r,
advance: function(t) {
this.x += t * this.vx;
this.y += t * this.vy;
}
};
break;
}
};
window.requestAnimationFrame(vsync);
var t_last;
function vsync(t)
{
if( t_last )
render( t - t_last );
t_last = t;
window.requestAnimationFrame(vsync);
}
function render(t_frame)
{
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.fillStyle="gray";
ctx.fillRect(0,0, canvas.width, canvas.height);
function advance_all(t) {
balls.forEach( function(b) {
b.advance(t);
});
}
var t_remaining = t_frame;
while(true) {
var hit = get_next_collision( balls, canvas.width, canvas.height );
if( t_remaining < hit.t )
break;
advance_all( hit.t );
t_remaining -= hit.t;
collide_wall( balls[hit.i], hit.wall );
balls[hit.i].advance(.001);
};
advance_all( t_remaining );
// draw balls
balls.forEach( function(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.r, 0, Math.PI*2, true);
ctx.closePath();
ctx.fillStyle = ball.color;
ctx.fill();
});
}
});
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
function get_next_collision(balls,W,H)
{
var winner;
// ball-wall
balls.forEach( function(ball,i)
{
var t = [];
t['L'] = (ball.r - ball.x) / ball.vx; // s.x + t v.x = r
t['T'] = (ball.r - ball.y) / ball.vy;
t['R'] = (W-1-ball.r - ball.x) / ball.vx; // s.x + t v.x = (W-1)-r
t['B'] = (H-1-ball.r - ball.y) / ball.vy;
// get index of smallest positive t
var LR = t['L'] >= 0 ? 'L' : 'R',
TB = t['T'] >= 0 ? 'T' : 'B',
wall = t[LR] < t[TB] ? LR : TB;
if( ! winner || ( t[wall] <= winner.t ) )
winner = {
t : t[wall],
i : i,
wall: wall
};
});
return winner;
}
function collide_wall( A, wall )
{
if( wall == 'L' || wall == 'R' )
A.vx *= -1;
else
A.vy *= -1;
}
html, body {
width: 100%;
height: 100%;
margin: 0px;
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mathjs/1.5.1/math.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<canvas id="myCanvas">
<!-- Insert fallback content here -->
</canvas>
Why is Firefox performing significantly worse than its competitors?
If I take the number of balls to 500 Chrome is still smooth, Firefox is seriously choppy.
If I take the number of balls down to 1 Firefox is still burring it.
Another experiment I did was applying a fixed velocity increment each frame, so that the smoothness of the animation accurately reflects the evenness of the render callback. This showed Firefox to be all over the place. Chrome on the other hand was smooth.
If there is sufficient interest, I can provide a snippet for that also and maybe tidy up the first one so that it offers a slider to modify the ball count.
As far as I can see, (1) Firefox definitely isn't giving us a genuine VSYNC callback, I suspect it is just using a timer, (2) even correcting for that by manually calculating elapsed time for each frame, it burrs the animation, maybe suggesting that it sometimes the callback fires in time to catch the VSYNC and sometimes it misses the boat, (3) there is an additional compositing hit that is disproportionate compared with Chrome.
Is there anything to be done about this?
EDIT: I found this question from four years ago! Poor performance of html5 canvas under firefox -- please don't mark this question as the duplicate unless it is certain that the answer to that question is still the only relevant answer four years later. I've deliberately included the version number in the question, as the question pertains specifically to the current version.