I've been searching for this script all day.
does anyone know any such script that I can use to rotate an image using mouse drag event. using javascript.
thanks in advance.
I have an implmentation idea, as I'm going to need to write this one also, unless you already have a solution so I'd like to have it :)
anyway, do this:
/** edit: removed my pseudo-code in favor for the real one ahead **/
anyway... I'll implement this and let you know.
unless of course, during the next few hours some one will send his implementation :-)
/** edit: thanks for those who did **/
UPDATE:
here it is, anyway (rotating one image over another:)
it's working great, jsut do a little clean up if you're importing this.
it's cross browser.
html:
<div id="centered" style=" /* margin-left:400px; computed in javacript*/ ">
<img id="static" src="" style="position:absolute; z-index:-1">
<img id="rotating" src="" >
</div>
include:
// jquery.min.js, jQueryRotate.js (discussed above)
javascript:
var alpha=0
var dragOrig = null
var mouseInPic = new Point(0,0)
var diff
var imageNo = 0
function swapImage_or_something(i /* or get src from somewhere else*/) {
$("#static").attr("src", arrCfgImages[i].src)
$("#rotating").attr("src", arrCfgImages[i].src)
$("#static").height(450);
$("#rotating").height(450);
$("#centered").css ({
"margin-left": ($(document).width()-$("#static").width())/2
})
$("#rotating").rotate(0)
}
function doEventBinding() {
$(document).bind("mousedown", function (e) {
dragOrig = new Point (mouseInPic.x, mouseInPic.y)
e.preventDefault()
return
});
$(document).bind("mouseup", function (e) {
if (dragOrig) {
dragOrig = null
alpha+=diff
diff=0
}
});
$(document).bind("mousemove", function (e) {
var x = -1*(Math.round($("#rotating").width()/2+0.01) - (e.pageX - $("#rotating").offset().left - (isIE ? 2 : 0)))
var y = Math.round($("#rotating").height()/2+0.01) - (e.pageY - $("#rotating").offset().top - (isIE ? 2 : 0))
mouseInPic = new Point(x,y)
if (dragOrig) {
var cp = new Point(0,0)
var deg1 = getAngleBetweenPoints(dragOrig, cp)
var deg2 = getAngleBetweenPoints(mouseInPic, cp)
diff = (deg1-deg2)
diff = diff<0 ? diff+360 : diff>360 ? diff-360 : diff
diff = diff>180 ? diff-360 : diff
//my$("debug").innerHTML = diff
$('#rotating').rotate(alpha+diff);
e.preventDefault()
}
});
}
also:
var toRAD = 1/180*Math.PI;
var toDEG = 180/Math.PI;
function getAngle(dx,dy) {
var ang
if (dx!=0) {
var rad = Math.atan(dy/dx) + (dx<0?Math.PI:0)
ang = rad*toDEG
if (ang<0) ang+=360;
} else {
ang = dy>0 ? 90 : 270;
}
return ang;
}
function getAngleBetweenPoints (p1, p2) {
var dx = p1.x-p2.x
var dy = p1.y-p2.y
return getAngle (dx, dy)
}
Greensock has a bery fancy spin functionality. Have a look at:
https://www.greensock.com/draggable/
Scroll down to spin.
Unfortunately it's not completelt free.
There you go. here is my solution it works only with IE for FF version you find out what is equivalent to vml objects in FF and other browsers:
<META HTTP-EQUIV="MSThemeCompatible" CONTENT="yes">
<HEAD>
<script>
var dragok = false;
var gotElementSelected = false;
var currentElement = null;
function move()
{
if (dragok)
{
tempX = event.clientX + document.body.scrollLeft;
tempY = event.clientY + document.body.scrollTop;
//rotating
document.getElementById(currentElement).style.rotation=tempX+tempY;
return false;
}
}
function down(){
dragok = true;
if(gotElementSelected && currentElement !=null)
{
document.onmousemove = move;
return false;
}
}
function up()
{
if(gotElementSelected && currentElement !=null)
{
gotElementSelected = false;
dragok = false;
document.onmousemove = null;
currentElement = null;
}
}
</script>
<STYLE>.rvml {
BEHAVIOR: url(#default#VML)
}
</STYLE>
</HEAD>
<BODY bgcolor=DDDDDD>
<?xml:namespace prefix = rvml ns = "urn:schemas-microsoft-com:vml" />
<rvml:image style="POSITION: absolute; WIDTH: 100px; DISPLAY: none; HEIGHT: 100px; TOP: 100px; LEFT:100px; rotation: 0" id=myimage class=rvml
onmousedown="gotElementSelected=true; currentElement=this.attributes.getNamedItem('id').value; selectedElement=currentElement;"
onclick="select_element(this.attributes.getNamedItem('id').value); selectedElement=this.attributes.getNamedItem('id').value;"
src = "path/to/your/image" coordsize = "21600,21600"></rvml:image>
Related
I have been trying to add some html and javascript to my website so users can draw some shapes. I found a really good sample to work from on JS Fiddle. When I run the code on JSFiddle, it works perfectly, but when I ran it myself on my browser (I tried Edge, Firefox, and Chrome) it did not work.
When I ran it myself, I included all the scripts and css into one html file because thats the only way to add it to my Wix website. The scripts (local javascript, and external cdn libraries) where together in the body section of html. All the tutorials I found make it seem like it's OK to use the CDN libraries. I'm positive my issue has something to do with the connection to the CDN libraries, so how would I fix it?
Here is code:
var roof = null;
var roofPoints = [];
var lines = [];
var lineCounter = 0;
var drawingObject = {};
drawingObject.type = "";
drawingObject.background = "";
drawingObject.border = "";
function Point(x, y) {
this.x = x;
this.y = y;
}
$("#poly").click(function () {
if (drawingObject.type == "roof") {
drawingObject.type = "";
lines.forEach(function(value, index, ar){
canvas.remove(value);
});
//canvas.remove(lines[lineCounter - 1]);
roof = makeRoof(roofPoints);
canvas.add(roof);
canvas.renderAll();
} else {
drawingObject.type = "roof"; // roof type
}
});
// canvas Drawing
var canvas = new fabric.Canvas('canvas-tools');
var x = 0;
var y = 0;
fabric.util.addListener(window,'dblclick', function(){
drawingObject.type = "";
lines.forEach(function(value, index, ar){
canvas.remove(value);
});
//canvas.remove(lines[lineCounter - 1]);
roof = makeRoof(roofPoints);
canvas.add(roof);
canvas.renderAll();
console.log("double click");
//clear arrays
roofPoints = [];
lines = [];
lineCounter = 0;
});
canvas.on('mouse:down', function (options) {
if (drawingObject.type == "roof") {
canvas.selection = false;
setStartingPoint(options); // set x,y
roofPoints.push(new Point(x, y));
var points = [x, y, x, y];
lines.push(new fabric.Line(points, {
strokeWidth: 3,
selectable: false,
stroke: 'red'
}).setOriginX(x).setOriginY(y));
canvas.add(lines[lineCounter]);
lineCounter++;
canvas.on('mouse:up', function (options) {
canvas.selection = true;
});
}
});
canvas.on('mouse:move', function (options) {
if (lines[0] !== null && lines[0] !== undefined && drawingObject.type == "roof") {
setStartingPoint(options);
lines[lineCounter - 1].set({
x2: x,
y2: y
});
canvas.renderAll();
}
});
function setStartingPoint(options) {
var offset = $('#canvas-tools').offset();
x = options.e.pageX - offset.left;
y = options.e.pageY - offset.top;
}
function makeRoof(roofPoints) {
var left = findLeftPaddingForRoof(roofPoints);
var top = findTopPaddingForRoof(roofPoints);
roofPoints.push(new Point(roofPoints[0].x,roofPoints[0].y))
var roof = new fabric.Polyline(roofPoints, {
fill: 'rgba(0,0,0,0)',
stroke:'#58c'
});
roof.set({
left: left,
top: top,
});
return roof;
}
function findTopPaddingForRoof(roofPoints) {
var result = 999999;
for (var f = 0; f < lineCounter; f++) {
if (roofPoints[f].y < result) {
result = roofPoints[f].y;
}
}
return Math.abs(result);
}
function findLeftPaddingForRoof(roofPoints) {
var result = 999999;
for (var i = 0; i < lineCounter; i++) {
if (roofPoints[i].x < result) {
result = roofPoints[i].x;
}
}
return Math.abs(result);
}
.canvas {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<button id="poly" title="Draw Polygon" ">Draw Polygon </button>
<label style="color:blue"><b>Press double click to close shape and stop</b></label>
<canvas id="canvas-tools" class="canvas" width="500" height="500"></canvas>
EDIT
So, in the html file I put everything inside the body tag. The libraries are also included before the javascript. I get the error "Unable to get property 'x' of undefined or null reference" when I double-click to close the shape. I'm positive its because no points are added when I click in the canvas
Wix does not allow using Cloudflare. The following link has more detail.
https://support.wix.com/en/article/request-cloudflare-support
Wix has some limited API to work with HTML elements
https://support.wix.com/en/article/corvid-working-with-the-html-element
if you want to run it on a separate page (not on wix) and scripts are loaded try to wrap your javascript code in :
<script>
$(function() {
//your code here
var roof = null;
var roofPoints = [];
var lines = [];
var lineCounter = 0;
var drawingObject = {};
...
...
});
</script>
I have been trying to put a text particle effect on my website. I have tested it on Codepen and works great but does not work on my website.
The text shows but the effect does not work as required. The text stays in a static position on the screen but the hover effect is below the word.
taking the mose through the text does nothing, if I move the mouse to the bottom of the screen the effect works on the text above.
The text stays static, however, when I move scroll down, the position of the text effect stays at the bottom of the screen until it ends up below the div and stops working all together.
I was wondering if someone could help me centre this behind the text.
Also I am keen to change the colour of the text, to a linear gradient from #125eaa to #d52027
The link to the page on my site - https://www.supplementgenie.co.uk/testpage
link to my codepen - https://codepen.io/Paulmcf87/pen/gjpgOB
However, when I run this code on JS Fiddle it gives me a 404 error?
You will see, running code below it works great as on Codepen. It doesnt seem to translate properly to a full screen
Any help would be great
The code I am using
var pixels=new Array();
var canv=$('canv');
var ctx=canv.getContext('2d');
var wordCanv=$('wordCanv');
var wordCtx=wordCanv.getContext('2d');
var mx=-1;
var my=-1;
var words="";
var txt=new Array();
var cw=0;
var ch=0;
var resolution=1;
var n=0;
var timerRunning=false;
var resHalfFloor=0;
var resHalfCeil=0;
function canv_mousemove(evt)
{
mx=evt.clientX-canv.offsetLeft;
my=evt.clientY-canv.offsetTop;
}
function Pixel(homeX,homeY)
{
this.homeX=homeX;
this.homeY=homeY;
this.x=Math.random()*cw;
this.y=Math.random()*ch;
//tmp
this.xVelocity=Math.random()*10-5;
this.yVelocity=Math.random()*10-5;
}
Pixel.prototype.move=function()
{
var homeDX=this.homeX-this.x;
var homeDY=this.homeY-this.y;
var homeDistance=Math.sqrt(Math.pow(homeDX,2) + Math.pow(homeDY,2));
var homeForce=homeDistance*0.01;
var homeAngle=Math.atan2(homeDY,homeDX);
var cursorForce=0;
var cursorAngle=0;
if(mx >= 0)
{
var cursorDX=this.x-mx;
var cursorDY=this.y-my;
var cursorDistanceSquared=Math.pow(cursorDX,2) + Math.pow(cursorDY,2);
cursorForce=Math.min(10000/cursorDistanceSquared,10000);
cursorAngle=Math.atan2(cursorDY,cursorDX);
}
else
{
cursorForce=0;
cursorAngle=0;
}
this.xVelocity+=homeForce*Math.cos(homeAngle) + cursorForce*Math.cos(cursorAngle);
this.yVelocity+=homeForce*Math.sin(homeAngle) + cursorForce*Math.sin(cursorAngle);
this.xVelocity*=0.92;
this.yVelocity*=0.92;
this.x+=this.xVelocity;
this.y+=this.yVelocity;
}
function $(id)
{
return document.getElementById(id);
}
function timer()
{
if(!timerRunning)
{
timerRunning=true;
setTimeout(timer,33);
for(var i=0;i<pixels.length;i++)
{
pixels[i].move();
}
drawPixels();
wordsTxt.focus();
n++;
if(n%10==0 && (cw!=document.body.clientWidth || ch!=document.body.clientHeight)) body_resize();
timerRunning=false;
}
else
{
setTimeout(timer,10);
}
}
function getRandomColor(min, max) {
return Math.random() * (max - min) + min;
}
function drawPixels()
{
var imageData=ctx.createImageData(cw,ch);
var actualData=imageData.data;
var index;
var goodX;
var goodY;
var realX;
var realY;
for(var i=0;i<pixels.length;i++)
{
goodX=Math.floor(pixels[i].x);
goodY=Math.floor(pixels[i].y);
for(realX=goodX-resHalfFloor; realX<=goodX+resHalfCeil && realX>=0 && realX<cw;realX++)
{
for(realY=goodY-resHalfFloor; realY<=goodY+resHalfCeil && realY>=0 && realY<ch;realY++)
{
index=(realY*imageData.width + realX)*4;
actualData[index+3]=realX;
actualData[index+2]=realX;
actualData[index+1]=realY;
}
}
}
imageData.data=actualData;
ctx.putImageData(imageData,0,0);
}
function readWords()
{
words=$('wordsTxt').value;
txt=words.split('\n');
}
function init()
{
readWords();
var fontSize=200;
var wordWidth=0;
do
{
wordWidth=0;
fontSize-=5;
wordCtx.font=fontSize+"px Avenir, sans-serif";
for(var i=0;i<txt.length;i++)
{
var w=wordCtx.measureText(txt[i]).width;
if(w>wordWidth) wordWidth=w;
}
} while(wordWidth>cw-50 || fontSize*txt.length > ch-50)
wordCtx.clearRect(0,0,cw,ch);
wordCtx.textAlign="center";
wordCtx.textBaseline="middle";
for(var i=0;i<txt.length;i++)
{
wordCtx.fillText(txt[i],cw/2,ch/2 - fontSize*(txt.length/2-(i+0.5)));
}
var index=0;
var imageData=wordCtx.getImageData(0,0,cw,ch);
for(var x=0;x<imageData.width;x+=resolution) //var i=0;i<imageData.data.length;i+=4)
{
for(var y=0;y<imageData.height;y+=resolution)
{
i=(y*imageData.width + x)*4;
if(imageData.data[i+3]>128)
{
if(index >= pixels.length)
{
pixels[index]=new Pixel(x,y);
}
else
{
pixels[index].homeX=x;
pixels[index].homeY=y;
}
index++;
}
}
}
pixels.splice(index,pixels.length-index);
}
function body_resize()
{
cw=document.body.clientWidth;
ch=document.body.clientHeight;
canv.width=cw;
canv.height=ch;
wordCanv.width=cw;
wordCanv.height=ch;
init();
}
wordsTxt.focus();
wordsTxt.value="Supplement Genie";
resolution=1;
resHalfFloor=Math.floor(resolution/2);
resHalfCeil=Math.ceil(resolution/2);
body_resize();
timer();
#wordsTxt{
display:none
}
div.pixeltext canvas{
width:98vw;
height:100vh;
}
div.pixeltext{
background-color: #d52027;
<div class="pixeltext">
<canvas id="canv" onmousemove="canv_mousemove(event);" onmouseout="mx=-1;my=-1;">
you need a canvas-enabled browser, such as Google Chrome
</canvas>
<canvas id="wordCanv" width="500px" height="500px" style="border:1px solid black;display:none;">
</canvas>
<textarea id="wordsTxt" style="position:absolute;left:-100;top:-100;" onblur="init();" onkeyup="init();" onclick="init();"></textarea>
<div>
You should define the cw,ch variables based on the canvas dimensions and not on the document.body.clientWidth etc.
Also you should avoid using canv.offsetLeft and canv.offsetTop since your element is inside other positioned elements and the offset properties return the position relative to the closest positioned ancestor.
Using canv.getBoundingClientRect which returns the width/height and top/left/right/bottom properties relative to the viewport will solve the problem.
(your codepen was also using wrong names of the methods you had created)
See https://codepen.io/gpetrioli/pen/rreagp which basically modifies the following methods
function canvMousemove(evt) {
var rect = canv.getBoundingClientRect();
mx = evt.clientX - rect.left;
my = evt.clientY - rect.top;
}
function body_resize() {
var rect = canv.getBoundingClientRect()
cw = rect.width;
ch = rect.height;
console.log(ch);
canv.width = cw;
canv.height = ch;
wordCanv.width = cw;
wordCanv.height = ch;
init();
}
In your site i noticed a timer method which should also be modified to
function timer() {
var rect;
if (!timerRunning) {
timerRunning = true;
setTimeout(timer, 33);
for (var i = 0; i < pixels.length; i++) {
pixels[i].move();
}
drawPixels();
wordsTxt.focus();
n++;
rect = canv.getBoundingClientRect();
if (n % 10 == 0 && (cw != rect.width || ch != rect.height)) body_resize();
timerRunning = false;
} else {
setTimeout(timer, 10);
}
}
This is not a duplicate of the other question.
I found this talking about rotation about the center using XML, tried to implement the same using vanilla JavaScript like rotate(45, 60, 60) but did not work with me.
The approach worked with me is the one in the snippet below, but found the rect not rotating exactly around its center, and it is moving little bit, the rect should start rotating upon the first click, and should stop at the second click, which is going fine with me.
Any idea, why the item is moving, and how can I fix it.
var NS="http://www.w3.org/2000/svg";
var SVG=function(el){
return document.createElementNS(NS,el);
}
var svg = SVG("svg");
svg.width='100%';
svg.height='100%';
document.body.appendChild(svg);
class myRect {
constructor(x,y,h,w,fill) {
this.SVGObj= SVG('rect'); // document.createElementNS(NS,"rect");
self = this.SVGObj;
self.x.baseVal.value=x;
self.y.baseVal.value=y;
self.width.baseVal.value=w;
self.height.baseVal.value=h;
self.style.fill=fill;
self.onclick="click(evt)";
self.addEventListener("click",this,false);
}
}
Object.defineProperty(myRect.prototype, "node", {
get: function(){ return this.SVGObj;}
});
Object.defineProperty(myRect.prototype, "CenterPoint", {
get: function(){
var self = this.SVGObj;
self.bbox = self.getBoundingClientRect(); // returned only after the item is drawn
self.Pc = {
x: self.bbox.left + self.bbox.width/2,
y: self.bbox.top + self.bbox.height/2
};
return self.Pc;
}
});
myRect.prototype.handleEvent= function(evt){
self = evt.target; // this returns the `rect` element
this.cntr = this.CenterPoint; // backup the origional center point Pc
this.r =5;
switch (evt.type){
case "click":
if (typeof self.moving == 'undefined' || self.moving == false) self.moving = true;
else self.moving = false;
if(self.moving == true){
self.move = setInterval(()=>this.animate(),100);
}
else{
clearInterval(self.move);
}
break;
default:
break;
}
}
myRect.prototype.step = function(x,y) {
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().translate(x,y));
}
myRect.prototype.rotate = function(r) {
return svg.createSVGTransformFromMatrix(svg.createSVGMatrix().rotate(r));
}
myRect.prototype.animate = function() {
self = this.SVGObj;
self.transform.baseVal.appendItem(this.step(this.cntr.x,this.cntr.y));
self.transform.baseVal.appendItem(this.rotate(this.r));
self.transform.baseVal.appendItem(this.step(-this.cntr.x,-this.cntr.y));
};
for (var i = 0; i < 10; i++) {
var x = Math.random() * 100,
y = Math.random() * 300;
var r= new myRect(x,y,10,10,'#'+Math.round(0xffffff * Math.random()).toString(16));
svg.appendChild(r.node);
}
UPDATE
I found the issue to be calculating the center point of the rect using the self.getBoundingClientRect() there is always 4px extra in each side, which means 8px extra in the width and 8px extra in the height, as well as both x and y are shifted by 4 px, I found this talking about the same, but neither setting self.setAttribute("display", "block"); or self.style.display = "block"; worked with me.
So, now I've one of 2 options, either:
Find a solution of the extra 4px in each side (i.e. 4px shifting of both x and y, and total 8px extra in both width and height),
or calculating the mid-point using:
self.Pc = {
x: self.x.baseVal.value + self.width.baseVal.value/2,
y: self.y.baseVal.value + self.height.baseVal.value/2
};
The second option (the other way of calculating the mid-point worked fine with me, as it is rect but if other shape is used, it is not the same way, I'll look for universal way to find the mid-point whatever the object is, i.e. looking for the first option, which is solving the self.getBoundingClientRect() issue.
Here we go…
FIDDLE
Some code for documentation here:
let SVG = ((root) => {
let ns = root.getAttribute('xmlns');
return {
e (tag) {
return document.createElementNS(ns, tag);
},
add (e) {
return root.appendChild(e)
},
matrix () {
return root.createSVGMatrix();
},
transform () {
return root.createSVGTransformFromMatrix(this.matrix());
}
}
})(document.querySelector('svg.stage'));
class Rectangle {
constructor (x,y,w,h) {
this.node = SVG.add(SVG.e('rect'));
this.node.x.baseVal.value = x;
this.node.y.baseVal.value = y;
this.node.width.baseVal.value = w;
this.node.height.baseVal.value = h;
this.node.transform.baseVal.initialize(SVG.transform());
}
rotate (gamma, x, y) {
let t = this.node.transform.baseVal.getItem(0),
m1 = SVG.matrix().translate(-x, -y),
m2 = SVG.matrix().rotate(gamma),
m3 = SVG.matrix().translate(x, y),
mtr = t.matrix.multiply(m3).multiply(m2).multiply(m1);
this.node.transform.baseVal.getItem(0).setMatrix(mtr);
}
}
Thanks #Philipp,
Solving catching the SVG center can be done, by either of the following ways:
Using .getBoundingClientRect() and adjusting the dimentions considering 4px are extra in each side, so the resulted numbers to be adjusted as:
BoxC = self.getBoundingClientRect();
Pc = {
x: (BoxC.left - 4) + (BoxC.width - 8)/2,
y: (BoxC.top - 4) + (BoxC.height - 8)/2
};
or by:
Catching the .(x/y).baseVal.value as:
Pc = {
x: self.x.baseVal.value + self.width.baseVal.value/2,
y: self.y.baseVal.value + self.height.baseVal.value/2
};
Below a full running code:
let ns="http://www.w3.org/2000/svg";
var root = document.createElementNS(ns, "svg");
root.style.width='100%';
root.style.height='100%';
root.style.backgroundColor = 'green';
document.body.appendChild(root);
//let SVG = function() {}; // let SVG = new Object(); //let SVG = {};
class SVG {};
SVG.matrix = (()=> { return root.createSVGMatrix(); });
SVG.transform = (()=> { return root.createSVGTransformFromMatrix(SVG.matrix()); });
SVG.translate = ((x,y)=> { return SVG.matrix().translate(x,y) });
SVG.rotate = ((r)=> { return SVG.matrix().rotate(r); });
class Rectangle {
constructor (x,y,w,h,fill) {
this.node = document.createElementNS(ns, 'rect');
self = this.node;
self.x.baseVal.value = x;
self.y.baseVal.value = y;
self.width.baseVal.value = w;
self.height.baseVal.value = h;
self.style.fill=fill;
self.transform.baseVal.initialize(SVG.transform()); // to generate transform list
this.transform = self.transform.baseVal.getItem(0), // to be able to read the matrix
this.node.addEventListener("click",this,false);
}
}
Object.defineProperty(Rectangle.prototype, "draw", {
get: function(){ return this.node;}
});
Object.defineProperty(Rectangle.prototype, "CenterPoint", {
get: function(){
var self = this.node;
self.bbox = self.getBoundingClientRect(); // There is 4px shift in each side
self.bboxC = {
x: (self.bbox.left - 4) + (self.bbox.width - 8)/2,
y: (self.bbox.top - 4) + (self.bbox.height - 8)/2
};
// another option is:
self.Pc = {
x: self.x.baseVal.value + self.width.baseVal.value/2,
y: self.y.baseVal.value + self.height.baseVal.value/2
};
return self.bboxC;
// return self.Pc; // will give same output of bboxC
}
});
Rectangle.prototype.animate = function () {
let move01 = SVG.translate(this.CenterPoint.x,this.CenterPoint.y),
move02 = SVG.rotate(10),
move03 = SVG.translate(-this.CenterPoint.x,-this.CenterPoint.y);
movement = this.transform.matrix.multiply(move01).multiply(move02).multiply(move03);
this.transform.setMatrix(movement);
}
Rectangle.prototype.handleEvent= function(evt){
self = evt.target; // this returns the `rect` element
switch (evt.type){
case "click":
if (typeof self.moving == 'undefined' || self.moving == false) self.moving = true;
else self.moving = false;
if(self.moving == true){
self.move = setInterval(()=>this.animate(),100);
}
else{
clearInterval(self.move);
}
break;
default:
break;
}
}
for (var i = 0; i < 10; i++) {
var x = Math.random() * 100,
y = Math.random() * 300;
var r= new Rectangle(x,y,10,10,'#'+Math.round(0xffffff * Math.random()).toString(16));
root.appendChild(r.draw);
}
I'm trying to make this code work with more than one id and i can't make it work.
I have tried with querySelectorAll, but with not succes.
I also read this article, but none of the options worked for me
Can anyone help me?
This is the code:
<script>
function Scroller(options) {
this.svg = options.el;
//Animation will end when the end is at which point of othe page. .9 is at about 90% down the page/
// .1 is 10% from the top of the page. Default is middle of the page.
this.animationBounds = {};
this.animationBounds.top = options.startPoint || .5;
this.animationBounds.bottom = options.endPoint || .5;
this.animationBounds.containerBounds = this.svg.getBoundingClientRect();
this.start = this.getPagePosition('top');
this.end = this.getPagePosition('bottom');
this.svgLength = this.svg.getTotalLength();
this.svg.style.strokeDasharray = this.svgLength;
this.animateLine();
window.addEventListener('scroll', this.animateLine.bind(this));
}
Scroller.prototype.getPagePosition = function (position) {
//These positions are all relative to the current window. So they top of the page will be negative and thus need to be
//subtracted to get a positive number
var distanceFromPageTop = document.body.getBoundingClientRect().top;
var divPosition = this.animationBounds.containerBounds[position];
var startPointInCurrentWindow = window.innerHeight * this.animationBounds[position];
return divPosition - distanceFromPageTop - startPointInCurrentWindow;
};
Scroller.prototype.animateLine = function () {
this.currentVisiblePosition = window.pageYOffset;
if (this.currentVisiblePosition < this.start) {
this.svg.style.strokeDashoffset = this.svgLength;
}
if (this.currentVisiblePosition > this.end) {
this.svg.style.strokeDashoffset = '0px';
}
if (this.currentVisiblePosition > this.start && this.currentVisiblePosition < this.end) {
this.svg.style.strokeDashoffset = this.distanceRemaining() * this.pixelsPerVerticalScroll() + 'px';
}
};
Scroller.prototype.distanceRemaining = function () {
return this.end - this.currentVisiblePosition;
};
Scroller.prototype.pixelsPerVerticalScroll = function () {
this.verticalDistance = this.end - this.start;
return this.svgLength / this.verticalDistance;
};
new Scroller({
'el': **document.getElementById('line')**,
'startPoint': .8,
'endPoint': .5
});
</script>
Loop over all the elements matching the selector.
var lines = document.querySelectorAll("#line, #line1, #line2");
for (var i = 0; i < lines.length; i++) {
new Scroller({
el: lines[i],
startPoint: .8,
endPoint: .5
});
}
I have this function but there are two issues I can't solve, first one is that the mouse action is set on all the screen and I want it to be when hover over the dive "ehab" only, not when I move mouse over screen,
the other issue is that when I have more than one div , the function works only on the first one ...
kindly advise me
/*
By : Ofelquis
Twitter: #felquis
Blog : tutsmais.com.br
Simples implementação ;)
*/
!(function ($doc, $win) {
var screenWidth = $win.screen.width / 2,
screenHeight = $win.screen.height / 2,
$ehab = $doc.querySelectorAll('#ehab')[0],
validPropertyPrefix = '',
otherProperty = 'perspective(600px)';
if(typeof $ehab.style.webkitTransform == 'string') {
validPropertyPrefix = 'webkitTransform';
} else {
if (typeof $ehab.style.MozTransform == 'string') {
validPropertyPrefix = 'MozTransform';
}
}
$doc.addEventListener('mousemove', function (e) {
// vars
var centroX = e.clientX - screenWidth,
centroY = screenHeight - (e.clientY + 13),
degX = centroX * 0.1,
degY = centroY * 0.1
// Seta o rotate do elemento
$ehab.style[validPropertyPrefix] = otherProperty + 'rotateY('+ degX +'deg) rotateX('+ degY +'deg)';
});
})(document, window);
The first problem, (I want it to be when hover the div "#ehab"), you need the attach the mousemove event to your div:
$ehab.addEventListener('mousemove', function (e) {
//You code here.
});
The second problem, (when I have more than one div , the function works only on the first one), you can't have duplicated IDs on your DOM tree, change the selector to a class, for example, .ehab then you have to loop through the matched elements, please try this code:
/*
By : Ofelquis
Twitter: #felquis
Blog : tutsmais.com.br
Simples implementação ;)
*/
!(function($doc, $win) {
var $ehabDIVs = $doc.querySelectorAll('.ehab'),
otherProperty = 'perspective(600px)';
for (var i = 0; i < $ehabDIVs.length; ++i) {
var $ehab = $ehabDIVs[i];
$ehab.addEventListener('mousemove', function(e) {
// vars
var centroX = (e.pageX - this.offsetLeft) - this.offsetWidth/2,
centroY = this.offsetHeight/2 - (e.pageY-this.offsetTop),
degX = centroX * 0.1,
degY = centroY * 0.1
if(this._leave) clearInterval(this._leave);
// Seta o rotate do elemento
this.style.transform = otherProperty + 'rotateY(' + degX + 'deg) rotateX(' + degY + 'deg)';
});
$ehab.addEventListener('mouseleave', function(e) {
var self = this;
this._leave = setTimeout(function() {
self.style.transform = 'rotateY(0deg) rotateX(0deg)';
}, 250);
});
}
})(document, window);
.ehab {
width:300px;
height:300px;
background-color:red;
margin:15px;
float:left;
transition: transform 0.15s ease;
}
<div class="ehab">First Div</div><div class="ehab">Second Div</div>
Good Luck Ismaiel.