Using GSAP (TweenMax) on css varabiles - gsap

I'm really into Google's Polymer and I love GSAP - and so far I've been using the two in conjunction without a hitch. Unfortunately I have now hit a problem - how do I use GSAP (TweenMax to be specific) with custom css variables?
For example:
To change someCssProperty of someElement I would
TweenMax.to(someElement, 1, someCssProperty: "value");
but the someCssProperty becomes an issue when I'm trying to animate a css variable, which take on the form --some-custom-css-variable .
I have tried to use
TweenMax.to(someElement, 1, --some-custom-css-Property: "value");
(obviously gives me errors) and I also tried to use TweenMax.to(someElement, 1, "--some-custom-css-Property": "value");
(quotes around the some-custom-Css-property) - however this results in
no change/animation and an invalid tween value error message on the developer console.
So the question is: how would I go about animating custom css variables with TweenMax (GSAP)?
Thanks for any help :)
EDIT:
I have tried using classes through
TweenMax.to("SomeElement", 5, {className:"class2"});
But this changed the element style as if I had declared it in css with a
SomeElement:hover {}
style (as in it does not animate, just changes immediately)

For now, you're going to have to manually update the variable using a generic object.
var docElement = document.documentElement;
var tl = new TimelineMax({ repeat: -1, yoyo: true, onUpdate: updateRoot });
var cs = getComputedStyle(docElement, null);
var blur = {
value: cs.getPropertyValue("--blur")
};
tl.to(blur, 2, { value: "25px" });
function updateRoot() {
docElement.style.setProperty("--blur", blur.value);
}
:root {
--blur: 0px;
}
img {
-webkit-filter: blur(var(--blur));
filter: blur(var(--blur));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.4/TweenMax.min.js"></script>
<img src="http://lorempixel.com/400/400/" />

Related

how to update the height of a textarea in vue.js when updating the value dynamically?

Working with Vue.js, I do use a simple way to set dynamically the height of a text area that resizes when typing. But I am not able to do it when the component mounts or the value updates.
I have already try http://www.jacklmoore.com/autosize/, but it has the same problem.
I have created a sandbox that shows the problem, when typing the box it updates, but not when the value changes dynamically
Live example: https://codesandbox.io/s/53nmll917l
You need a triggerInput() method:
triggerInput() {
this.$nextTick(() => {
this.$refs.resize.$el.dispatchEvent(new Event("input"));
});
}
to use whenever you're changing the value programatically, triggering the resize logic used on <textarea> on "real" input events.
Updated codesandbox.
Note: Without the $nextTick() wrapper, the recently changed value will not have been applied yet and, even though the input is triggered, the element has not yet been updated and the resize happens before value has changed, resulting in the old height and looking like it didn't happen.
Not really feeling the answers posted here. Here is my simple solution:
<textarea
rows="1"
ref="messageInput"
v-model="message"
/>
watch: {
message: function(newItem, oldItem) {
let { messageInput } = this.$refs;
const lineHeightInPixels = 16;
// Reset messageInput Height
messageInput.setAttribute(
`style`,
`height:${lineHeightInPixels}px;overflow-y:hidden;`
);
// Calculate number of lines (soft and hard)
const height = messageInput.style.height;
const scrollHeight = messageInput.scrollHeight;
messageInput.style.height = height;
const count = Math.floor(scrollHeight / lineHeightInPixels);
this.$nextTick(() => {
messageInput.setAttribute(
`style`,
`height:${count*lineHeightInPixels}px;overflow-y:hidden;`
);
});
},
}
<style scoped>
textarea {
height: auto;
line-height: 16px;
}
</style>

ckeditor5 - custom container element - recursion error on paste

I'm trying to create a CKEditor5 custom element plugin - mainly for custom format/styles -- nested divs etc. Managed to be able to inject/format the elements, and I can type in them. But if I try to copy and paste text into a custom element I get a too much recursion error.
MyWidget plugin:
export default class MyWidgetPlugin extends Plugin {
init() {
const editor = this.editor;
editor.model.schema.register('my-widget', {
inheritAllFrom: '$root',
isLimit: true,
});
editor.conversion.elementToElement({ model: 'my-widget', view: 'my-widget' });
editor.commands.add('myWidget', new MyWidgetCommand(editor));
}
}
MyWidget command:
class MyWidgetCommand extends Command {
execute() {
const editor = this.editor;
const block = first(this.editor.model.document.selection.getSelectedBlocks());
this.editor.model.change(writer => {
const myWidget = writer.createElement('my-widget')
writer.insert ( myWidget, block, 'after');
writer.appendElement( 'paragraph', myWidget );
});
}
}
Inserting a widget injects this into the editor:
<my-widget>
<p></p>
</my-widget>
And I can type fine, but I can't paste. I'm guessing I got the schema wrong... have played around with quite a few different options.. but to no avail.
I didn't check it but I think that the issue is here:
editor.model.schema.register('my-widget', {
inheritAllFrom: '$root',
isLimit: true,
});
This schema rule says that <my-widget> will allow e.g. a <paragraph> inside it. But it doesn't say anything about where <my-widget> may be used. That's because $root is not allowed in any other element (cause it's a root :)).
I think that the following should work fine:
editor.model.schema.register('my-widget', {
inheritAllFrom: '$root',
allowIn: '$root',
isLimit: true,
});
Alternatively, a more generic solution should work too:
editor.model.schema.register('my-widget', {
inheritAllFrom: '$root',
allowWhere: '$block',
isLimit: true,
});
Still, the editor should not crash with an infinite loop, so I reported https://github.com/ckeditor/ckeditor5-engine/issues/1441.

Use Dojo boxConstrainedMoveable to constrain movable div to window

I have a div, to which I applied Dojo dojo/dnd/Moveable. But, I'd like to prevent the user from dragging the div offscreen. So, I think I need to implement dojo/dnd/move/boxConstrainedMoveable.
I'm starting with this:
var dnd = new Moveable(this.domNode, {
'handle': this.titleNode
});
There's a similar SO question here:
Constrain a moveable object in Dojo. Applying that answer, I get something like this:
var dnd = new move.boxConstrainedMoveable(
'handle': this.titleNode
constraints: {
l: 0,
t: 20,
w: 500,
h: 500
},
within: true
);
But, I just can't understand how the bounding box works. I simply want the div to stay inside the window. I've tried implementing a few things with the window box, the div's margin box. Nothing's worked, and all I've made is a big mess.
I read the docs here:
http://dojotoolkit.org/api/?qs=1.9/dojo/dnd/move.boxConstrainedMoveable
Has anyone done this with Dojo? I'd be very appreciate of an example.
I looked up some old code I have and I did implement this type of movable once. This was written against Dojo 1.7, so things may have changed in 1.9. Fiddle demonstration: https://jsfiddle.net/4ev1daqr/26/
The main difference between your attempted solution and this is that the constraints property in the moveable needs to be a function rather than a static bounding box. When using the boxConstrainedMoveable module, the static bounding box should be assigned to a box property, rather than the constraints property.
This is actually a nice design, IMHO, because it allows the constraints to react to changes in application state, e.g. hiding a sidebar or moving a splitter, but it does make the simple case a bit more difficult to get working.
define(["dojo/_base/declare",
"dojo/dnd/move",
"dojo/dom",
"dojo/_base/window",
"dojo/dom-style",
"dojo/dom-geometry",
],
function (declare, move, dom, win, domStyle, domGeom) {
return declare( "my/dnd/move/BodyConstrainedMoveable", [move.constrainedMoveable], {
markupFactory: function(params, node){
return new this(node, params);
},
constructor: function(node, params) {
// Constrain the node to be within the body
this.constraints = function() {
var n = win.body(),
s = domStyle.getComputedStyle(n),
mb = domGeom.getMarginBox(n, s);
if ( this.node ) {
var menubox = domGeom.getMarginBox(this.node);
mb.w -= menubox.w;
mb.h -= menubox.h;
}
return mb;
};
}
})});

Grabing Dojo Original Object given Dom Id

I have a DOJO Editor that I add in JS using the method createEditor
require(["dijit/Editor"],
function(Editor){
this.createEditor = function(idToReplace){
var myEditorA = new Editor({
height: '50px',
plugins:['bold','italic']
}, document.getElementById(idToReplace));
myEditorA.startup();
}
});
I need the text inside the Editor after it has been changed.
I hooked up the method getEditorText but it is failing to do as I want it to do.
require(["dijit/Editor"], "dojo/dom",
function(Editor, dom){
this.getEditorText = function(idofEditor){
//Editor myEditor =Editor(null, dom.byId(idofEditor)); does not work either
var myEditor = dom.byId(idofEditor);
var content = myEditor.get("value");
});
The value that I need is stored in the attribute "value" in the Editor.
If I store myEditorA in a global variable I can get the content but I need the correct syntax to avoid working with unnecessary global variables
In Dojo widgets (dijit) and DOM nodes are treated seperately. For DOM nodes you indeed need to use the dojo/dom module and the function byId(). For widgets however, you need the dijit/registry module and then you can get the widget by its DOM node like this:
require(["dijit/registry", "dojo/dom"], function(registry, dom) {
var myEditor = registry.byNode(dom.byId(idofEditor));
});
But because the registry also saves your editor with the same ID as your DOM node, you can also access it directly (without using the DOM node) like this:
require(["dijit/registry"], function(registry) {
var myEditor = registry.byId(idofEditor);
});
I made an example JSFiddle which you can find here.

Dynamically adding html to panel

I am designing an app in sencha touch2. I have a panel object in my JS file. I need to dynamically set the text/html for this component. The store for this component is defined at the application level. Following is the thing I worked out:
Ext.define('class_name',{
....
config : {
pnlObj : null,
...
}
initialize : function() {
this.config.pnlObj = Ext.create('Ext.Panel');
var store = Ext.data.Storemanager.lookup('some_store');
store.on('load',this.loadStore,this);
this.setItems([{
//some items here
{
flex : 2,
// id : 'somepnl',
config : this.config.pnlObj
}
}]);
},
loadStore : function(store, rec) {
var text = rec.get('text');
var panel = this.config.pnlObj;
// var panel = Ext.getCmp('somepanl');
panel.setHtml(text);
}
});
When I inspect the inspect the element using Firebug console, I can find the panel added there. But I am not able to set the html dynamically. no html text is set there. I tried adding it using panel.add() & panel.setItems() method which doesn't work. If I give an id to that panel(somepanel here) and try to access it using Ext.getCmp('smpanel') then in that case it works fine. I have found that using Ext.getCmp() is not a good practice and want to avoid it as it might somewhere break my code in the future.
I guess the way I am instantiating the panel object is creating some issue. Can someone suggest the best way of doing it?
The recommended way to manipulate your components in Sencha Touch 2 is using controller, through refs and control configs. For example, your panel has a config like this: xtype:'myPanel', then in your controller:
refs: {
myPanel: 'myPanel'
}
control:{
myPanel: {
on_an_event: 'set_html_for_my_panel'
}
}
Lastly, define your function:
set_html_for_my_panel: function()
{
this.getMyPanel().setHtml('my_updated_html');
}
P/S: Behind the scene, Sencha Touch 2 uses Ext.ComponentQuery for refs in controllers