Flash Actionscript 2.0 localToGlobal co-ordinate issues - actionscript

I don't know if anyone here is old enough to remember ActionScript 2.0 but unfortunately I find myself stuck with it as the game I am writing a mod for (Skyrim) still uses AS2 for UI.
I am using Greensock TweenLite/TimeLineLite for my animations/tweens, but I am having difficulty with what should be some simple co-ordinate calculations.
I am trying to animate icon A from it's starting position, scaling it up and moving in x and y, and finishing in exactly the same position and size as icon B.
Icon A and icon B are within different movieclips two levels up from a common parent clip, so I am trying to use localToGlobal to get stage x/y for each icon, and then moving in x/y by the differences between the two sets of stage co-ordinates.
So for example:
Icon A Global x = 95
Icon B Global x = 150
Difference = 55
Icon A Local x + 55 should put it in the same x position on stage as Icon B right? Well that's nowhere near the result I'm getting on screen, not even close.
To help visualise better this is how the widget looks in game:
Example screenshot
And this is how it looks in CS6:
Flash workspace
So for example I am attempting to move/scale leftPreselectIcon (Dragonbone War Axe in the example screenshot) into exactly the position of leftIcon (Staff of Firebolts).
Here are the relevant functions:
public function prepareForPreselectAnimation(): Void
{
//This function checks if the preselect icons are to the left or right of their main icon and sets the animate out direction to the opposite side. It also stores current main icon x/y as the target values for the preselect icons to animate to. Finally it gets and stores all necessary current scale and alpha values to ensure everything returns to the exact state it was in prior to starting the animation
var leftIconLTG:Object = {x:(leftIcon._height * 0.5), y:(leftIcon._width * 0.5)};
var leftPreselectIconLTG:Object = {x:(leftPreselectIcon._height * 0.5), y:(leftPreselectIcon._width * 0.5)};
var rightIconLTG:Object = {x:(rightIcon._height * 0.5), y:(rightIcon._width * 0.5)};
var rightPreselectIconLTG:Object = {x:(rightPreselectIcon._height * 0.5), y:(rightPreselectIcon._width * 0.5)};
var shoutIconLTG:Object = {x:(shoutIcon._height * 0.5), y:(shoutIcon._width * 0.5)};
var shoutPreselectIconLTG:Object = {x:(shoutPreselectIcon._height * 0.5), y:(shoutPreselectIcon._width * 0.5)};
leftIcon.localToGlobal(leftIconLTG);
leftPreselectIcon.localToGlobal(leftPreselectIconLTG);
rightIcon.localToGlobal(rightIconLTG);
rightPreselectIcon.localToGlobal(rightPreselectIconLTG);
shoutIcon.localToGlobal(shoutIconLTG);
shoutPreselectIcon.localToGlobal(shoutPreselectIconLTG);
skyui.util.Debug.log("leftIconLTG - x: " + leftIconLTG.x + ", y: " + leftIconLTG.y)
skyui.util.Debug.log("leftPreselectIconLTG - x: " + leftPreselectIconLTG.x + ", y: " + leftPreselectIconLTG.y)
if (leftIconLTG.x > leftPreselectIconLTG.x){
leftTargetX = (leftIcon_mc._width) //If preselect icon is to the left of the main widget animate main widget out to right
//leftPTargetX = (leftIconLTG.x - leftPreselectIconLTG.x) + (leftIcon._width / 2)
} else {
leftTargetX = -(leftIcon_mc._width) //If preselect icon is to the right of the main widget animate main widget out to left
//leftPTargetX = (leftIconLTG.x - leftPreselectIconLTG.x) - (leftIcon._width)
}
leftPTargetX = (leftIconLTG.x - leftPreselectIconLTG.x)
skyui.util.Debug.log("leftTargetX: " + leftTargetX + ", leftPTargetX: " + leftPTargetX)
if (rightIconLTG.x > rightPreselectIconLTG.x){
rightTargetX = (rightIcon_mc._width)
//rightPTargetX = (rightIconLTG.x - rightPreselectIconLTG.x) + (rightIcon._width / 2)
} else {
rightTargetX = -(rightIcon_mc._width)
//rightPTargetX = (rightIconLTG.x - rightPreselectIconLTG.x) - (rightIcon._width)
}
rightPTargetX = (rightIconLTG.x - rightPreselectIconLTG.x)
if (shoutIconLTG.x > shoutPreselectIconLTG.x){
shoutTargetX = (shoutIcon_mc._width)
//shoutPTargetX = (shoutIconLTG.x - shoutPreselectIconLTG.x) + (shoutIcon._width / 2)
} else {
shoutTargetX = -(shoutIcon_mc._width)
//shoutPTargetX = (shoutIconLTG.x - shoutPreselectIconLTG.x) - (shoutIcon._width)
}
shoutPTargetX = (shoutIconLTG.x - shoutPreselectIconLTG.x)
leftPTargetY = leftIconLTG.y - leftPreselectIconLTG.y;
skyui.util.Debug.log("leftPTargetY: " + leftPTargetY)
rightPTargetY = rightIconLTG.y - rightPreselectIconLTG.y;
shoutPTargetY = shoutIconLTG.y - shoutPreselectIconLTG.y;
//Store current alpha and scale values ready to reapply
leftIconAlpha = leftIcon_mc._alpha;
leftTargetScale = ((leftIcon_mc._xscale / leftPreselectIcon_mc._xscale) * 100);
//leftPTargetX = ((leftIconLTG.x - leftPreselectIconLTG.x) * (leftIcon_mc._xscale / leftPreselectIcon_mc._xscale));
leftPIconAlpha = leftPreselectIcon_mc._alpha;
leftPIconScale = leftPreselectIcon._xscale;
rightIconAlpha = rightIcon_mc._alpha;
rightTargetScale = ((rightIcon_mc._xscale / rightPreselectIcon_mc._xscale) * 100);
rightPIconAlpha = rightPreselectIcon_mc._alpha;
rightPIconScale = rightPreselectIcon._xscale;
shoutIconAlpha = shoutIcon_mc._alpha;
shoutTargetScale = ((shoutIcon_mc._xscale / shoutPreselectIcon_mc._xscale) * 100);
shoutPIconAlpha = shoutPreselectIcon_mc._alpha;
shoutPIconScale = shoutPreselectIcon._xscale;
leftNameAlpha = leftName_mc._alpha;
leftPNameAlpha = leftPreselectName_mc._alpha;
rightNameAlpha = rightName_mc._alpha;
rightPNameAlpha = rightPreselectName_mc._alpha;
shoutNameAlpha = shoutName_mc._alpha;
shoutPNameAlpha = shoutPreselectName_mc._alpha;
skse.SendModEvent("iEquip_ReadyForPreselectAnimation", null);
}
public function equipPreselectedItem(iSlot: Number, currIcon: String, newIcon: String, newName: String, currPIcon: String, newPIcon: String, newPName: String): Void
{
var iconClip: MovieClip;
var iconClip_mc: MovieClip;
var currIcon: String;
var pIconClip: MovieClip;
var pIconClip_mc: MovieClip;
var currPIcon: String;
var itemName_mc: MovieClip;
var preselectName_mc: MovieClip;
var targetX: Number;
var pTargetX: Number;
var pTargetY: Number;
var pIconAlpha: Number;
var pIconScale: Number;
var pIconTargetScale: Number
var iconAlpha: Number;
var itemNameAlpha: Number;
var preselectNameAlpha: Number;
switch(iSlot) {
case 0:
iconClip = leftIcon;
iconClip_mc = leftIcon_mc;
pIconClip = leftPreselectIcon;
pIconClip_mc = leftPreselectIcon_mc;
itemName_mc = leftName_mc;
preselectName_mc = leftPreselectName_mc;
targetX = leftTargetX;
pTargetX = leftPTargetX;
pTargetY = leftPTargetY;
pIconAlpha = leftPIconAlpha;
pIconScale = leftPIconScale;
iconAlpha = leftIconAlpha;
pIconTargetScale = leftTargetScale;
itemNameAlpha = leftNameAlpha;
preselectNameAlpha = leftPNameAlpha;
break
case 1:
iconClip = rightIcon;
iconClip_mc = rightIcon_mc;
pIconClip = rightPreselectIcon;
pIconClip_mc = rightPreselectIcon_mc;
itemName_mc = rightName_mc;
preselectName_mc = rightPreselectName_mc;
targetX = rightTargetX;
pTargetX = rightPTargetX;
pTargetY = rightPTargetY;
pIconAlpha = rightPIconAlpha;
pIconScale = rightPIconScale;
iconAlpha = rightIconAlpha;
pIconTargetScale = rightTargetScale;
itemNameAlpha = rightNameAlpha;
preselectNameAlpha = rightPNameAlpha;
break
case 2:
iconClip = shoutIcon;
iconClip_mc = shoutIcon_mc;
pIconClip = shoutPreselectIcon;
pIconClip_mc = shoutPreselectIcon_mc;
itemName_mc = shoutName_mc;
preselectName_mc = shoutPreselectName_mc;
targetX = shoutTargetX;
pTargetX = shoutPTargetX;
pTargetY = shoutPTargetY;
pIconAlpha = shoutPIconAlpha;
pIconScale = shoutPIconScale;
iconAlpha = shoutIconAlpha;
pIconTargetScale = shoutTargetScale;
itemNameAlpha = shoutNameAlpha;
preselectNameAlpha = shoutPNameAlpha;
break
}
var tempIcon: MovieClip = iconClip.duplicateMovieClip("tempIcon", this.getNextHighestDepth());
tempIcon.gotoAndStop(currIcon);
iconClip._alpha = 0;
iconClip.gotoAndStop(newIcon);
var tempPIcon: MovieClip = pIconClip.duplicateMovieClip("tempPIcon", this.getNextHighestDepth());
//var iconLTG: Object = {x:(iconClip._width * 0.5), y:(iconClip._height * 0.5)}
//iconClip.localToGlobal(iconLTG);
//var tempPIconLTG: Object = {x:(tempPIcon._width * 0.5), y:(tempPIcon._height * 0.5)}
//tempPIcon.localToGlobal(tempPIconLTG);
//pTargetX = ((iconLTG.x - tempPIconLTG.x) * (iconClip_mc._xscale / pIconClip_mc._xscale));
//skyui.util.Debug.log("iconLTG.x: " + iconLTG.x + ", iconLTG.y: " + iconLTG.y + "tempPIconLTG.x: " + tempPIconLTG.x + ", tempPIconLTG.y: " + tempPIconLTG.y + ", pTargetX: " + pTargetX)
tempPIcon._xscale = pIconClip_mc._xscale;
tempPIcon._yscale = pIconClip_mc._yscale;
tempPIcon.gotoAndStop(currPIcon);
pIconClip._alpha = 0;
pIconClip._xscale = 25;
pIconClip._yscale = 25;
pIconClip.gotoAndStop(newPIcon);
var tl = new TimelineLite({paused:true, autoRemoveChildren:true, onComplete:equipPreselectedItemComplete});
tl.to(itemName_mc, 0.3, {_alpha:0, ease:Quad.easeOut}, 0)
.to(preselectName_mc, 0.3, {_alpha:0, ease:Quad.easeOut}, 0)
.call(updateNamesForEquipPreselect, [iSlot, newName, newPName, this])
.to(tempIcon, 0.6, {_x:targetX, _y:((tempIcon._height) / 2), _rotation:"+=90", _alpha:0, _xscale:25, _yscale:25, ease:Quad.easeOut}, 0);
.to(tempPIcon, 0.6, {_x:pTargetX, _y:pTargetY, _alpha:iconAlpha, _xscale:pIconTargetScale, _yscale:pIconTargetScale, ease:Quad.easeOut}, 0)
.to(iconClip, 0, {_alpha:iconAlpha, ease:Linear.easeNone})
.to(tempPIcon, 0, {_alpha:0, ease:Linear.easeNone})
.to(pIconClip, 0.4, {_alpha:pIconAlpha, _xscale:pIconScale, _yscale:pIconScale, ease:Elastic.easeOut}, 0.5)
.to(itemName_mc, 0.3, {_alpha:itemNameAlpha, ease:Quad.easeOut}, 0.6)
.to(preselectName_mc, 0.3, {_alpha:preselectNameAlpha, ease:Quad.easeOut}, 0.6)
tl.play();
}
I have also uploaded it to Pastebin HERE
The straightforward Icon A X value + Global X value difference which should work results in this:
Screenshot 2
And the issue is worse the greater the distance between the two icons is to start with. If I edit the starting position of Icon A to be much further away this is the result:
Screenshot 3
From those two examples the logged values and calculations are:
[20:12:47.970] leftIconLTG - x: 149.49916992187, y: 581.28598632812
[20:12:47.970] leftPreselectIconLTG - x: 94.587438964844, y: 577.68461914063
[20:12:47.970] leftTargetX: 39.15, leftPTargetX: 54.911730957031
[20:12:47.970] leftPTargetY: 3.6013671874999
[20:13:18.510] leftIconLTG - x: 149.49916992187, y: 581.28598632812
[20:13:18.510] leftPreselectIconLTG - x: 594.56030273438, y: 577.68461914063
[20:13:18.510] leftTargetX: -58.55, leftPTargetX: -445.0611328125
[20:13:18.510] leftPTargetY: 3.6013671874999
So as you can see the target leftIcon global (LTG) x is 149.5, and in the first screenshot the leftPreselectIcon starts at a global x of 94.6. leftPTargetX contains the difference calculated correctly at 54.9. So moving leftPreselectIcon from it's local starting x of 0 to 54.9 should in theory move it into the correct position.
So what am I doing wrong here? As you can see from the commented out code I have made several other attempts including adding half/full icon widths to the calculation, and even testing whether the difference in scale has anything to do with it by multiplying the global x difference value by the scale factor going from icon A scale to icon B scale using the on screen heights for the calculation. But none of them get me close.
Solved
The solution was to create 'store' objects for each set of icons, and then call localToGlobal on the target icon, then globalToLocal on the icon to be moved, both calls on the same object:
var leftPIconTarget:Object = {x:0, y:0};
leftIcon.localToGlobal(leftPIconTarget);
leftPreselectIcon.globalToLocal(leftPIconTarget);
leftPIconTarget now contains the target x and y co-ordinates for the tween on leftPreselectIcon, and continues to work no matter where on the screen I move the starting positions to. The only wierdness is that I have to make the right x negative or it goes in the wrong direction, which makes no sense at all, because if I move the left icon way over to the right so it has to animate right to left I don't have to make it negative. Go figure! Anyway, it works, and that's all I'm bothered about!

Related

How can we make a dynamic rating bar with user interaction enable in android jetpack composable ? I have try different library but no luck [duplicate]

I'm trying to implement a rating bar. I refer to https://gist.github.com/vitorprado/0ae4ad60c296aefafba4a157bb165e60 but I don't understand anything from this code. It works but when I use this code the stars don't have rounded corners. I want to implement something like the following :
I made very basic sample for this, it would give the basic idea for creating rating bar with sample border and filled png files.
#Composable
private fun RatingBar(
modifier: Modifier = Modifier,
rating: Float,
spaceBetween: Dp = 0.dp
) {
val image = ImageBitmap.imageResource(id = R.drawable.star)
val imageFull = ImageBitmap.imageResource(id = R.drawable.star_full)
val totalCount = 5
val height = LocalDensity.current.run { image.height.toDp() }
val width = LocalDensity.current.run { image.width.toDp() }
val space = LocalDensity.current.run { spaceBetween.toPx() }
val totalWidth = width * totalCount + spaceBetween * (totalCount - 1)
Box(
modifier
.width(totalWidth)
.height(height)
.drawBehind {
drawRating(rating, image, imageFull, space)
})
}
private fun DrawScope.drawRating(
rating: Float,
image: ImageBitmap,
imageFull: ImageBitmap,
space: Float
) {
val totalCount = 5
val imageWidth = image.width.toFloat()
val imageHeight = size.height
val reminder = rating - rating.toInt()
val ratingInt = (rating - reminder).toInt()
for (i in 0 until totalCount) {
val start = imageWidth * i + space * i
drawImage(
image = image,
topLeft = Offset(start, 0f)
)
}
drawWithLayer {
for (i in 0 until totalCount) {
val start = imageWidth * i + space * i
// Destination
drawImage(
image = imageFull,
topLeft = Offset(start, 0f)
)
}
val end = imageWidth * totalCount + space * (totalCount - 1)
val start = rating * imageWidth + ratingInt * space
val size = end - start
// Source
drawRect(
Color.Transparent,
topLeft = Offset(start, 0f),
size = Size(size, height = imageHeight),
blendMode = BlendMode.SrcIn
)
}
}
private fun DrawScope.drawWithLayer(block: DrawScope.() -> Unit) {
with(drawContext.canvas.nativeCanvas) {
val checkPoint = saveLayer(null, null)
block()
restoreToCount(checkPoint)
}
}
Usage
Column {
RatingBar(rating = 3.7f, spaceBetween = 3.dp)
RatingBar(rating = 2.5f, spaceBetween = 2.dp)
RatingBar(rating = 4.5f, spaceBetween = 2.dp)
RatingBar(rating = 1.3f, spaceBetween = 4.dp)
}
Result
Also created a library that uses gestures, other png files and vectors as rating items is available here.
RatingBar(
rating = rating,
space = 2.dp,
imageBackground = imageBackground,
imageForeground = imageForeground,
animationEnabled = false,
gestureEnabled = true,
itemSize = 60.dp
) {
rating = it
}
You can pass the custom drawable as icon. check this code.
Replace your RatingStar() function as it is using canvas to draw star, instead pass the custom drawable.
#Composable
private fun starShow(){
val icon = if (isSelected)
//your selected drawable
else
//your unselected drawable
Icon(
painter = painterResource(id = icon),
contentDescription = null,
tint = MyColor.starColor)
}

Logic for jumping in webgl with physics enabled

Most important code just for example. Func UPDATE is called in every draw frame.
I want implement jumping virtualJumpActive == true logic.
I invert procedure for virtualJumpActive == true to make scene object and camera position set by cannonjs position but just in some short time.
My camera.posY follow fixed values for now.
I wanna only Y (for cannonjs Z / jumping ) to be navigated by physics and other XY
to be navigated by camera (WASD user control)...
It is little intricate situation, i have 3 factors
position of camera
position of player (hands)
position of player collision object
In normal regime player collision object follow camera and player.
In jump moment i wanna apply by vertical force and make camera follow collision object. Also i wanna that always Y component depens on physics data. In that way i will have jumping on top of other objects.
var playerUpdater = {
UPDATE: () => {
App.scene[objName].rotation.rotateY(
matrixEngine.Events.camera.yaw + 180)
var detPitch;
var limit = 2;
if(matrixEngine.Events.camera.pitch < limit &&
matrixEngine.Events.camera.pitch > -limit) {
detPitch = matrixEngine.Events.camera.pitch * 2;
} else if(matrixEngine.Events.camera.pitch > limit) {
detPitch = limit * 2;
} else if(matrixEngine.Events.camera.pitch < -(limit + 2)) {
detPitch = -(limit + 2) * 2;
}
if(matrixEngine.Events.camera.virtualJumpActive == true) {
// invert logic
// Scene object set
App.scene[objName].rotation.rotateX(-detPitch);
var detPitchPos = matrixEngine.Events.camera.pitch;
if(detPitchPos > 4) detPitchPos = 4;
App.scene[objName].position.setPosition(
App.scene.playerCollisonBox.physics.currentBody.position.x,
App.scene.playerCollisonBox.physics.currentBody.position.z,
App.scene.playerCollisonBox.physics.currentBody.position.y
)
// Cannonjs object set
// Switched Z - Y
matrixEngine.Events.camera.xPos = App.scene.playerCollisonBox.physics.currentBody.position.x;
matrixEngine.Events.camera.zPos = App.scene.playerCollisonBox.physics.currentBody.position.y;
matrixEngine.Events.camera.yPos = App.scene.playerCollisonBox.physics.currentBody.position.z;
// App.scene.playerCollisonBox.
// physics.currentBody.velocity.set(0, 0, 0);
App.scene.playerCollisonBox.
physics.currentBody.angularVelocity.set(0, 0, 0);
setTimeout(() => {
matrixEngine.Events.camera.virtualJumpActive = false;
matrixEngine.Events.camera.virtualJumpY = 2;
}, 350);
} else {
// Scene object set
App.scene[objName].rotation.rotateX(-detPitch);
var detPitchPos = matrixEngine.Events.camera.pitch;
if(detPitchPos > 4) detPitchPos = 4;
App.scene[objName].position.setPosition(
matrixEngine.Events.camera.xPos,
matrixEngine.Events.camera.yPos - 0.3 + detPitchPos / 50,
matrixEngine.Events.camera.zPos,
)
// Cannonjs object set
// Switched Z - Y
App.scene.playerCollisonBox.
physics.currentBody.position.set(
matrixEngine.Events.camera.xPos,
matrixEngine.Events.camera.zPos,
matrixEngine.Events.camera.yPos);
App.scene.playerCollisonBox.
physics.currentBody.velocity.set(0, 0, 0);
App.scene.playerCollisonBox.
physics.currentBody.angularVelocity.set(0, 0, 0);
}
}
};
.full {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
<object class="full" data="https://fps-matrix-engine.vercel.app"/>
Any suggestion ?
More data:
Stackoverflow Question ref code =>
https://codepen.io/zlatnaspirala/pen/eYKrmdM?editors=0010
Source code github
Last update
https://fps-matrix-engine.vercel.app

Highcharts: plotbands in gauge charts

I'm using plotbands in a gauge chart to represent angle ranges. But I'm facing a problem with the plotband angles when the "from" value is higher than the "to" value.
JSFiddle
As you can see, the plotband is set as from: 270, to: 45 but it really is rendered as if it was set as from: 45, to: 270. That renders exactly the oposite angle range that I need.
The only way that I can find to do that is setting two plotbands, one from 270 to 360 and another one from 0 to 45, but that seems very unconvenient.
Is there any easy way to achieve what I'm trying to do?
As I have mentioned in my comment, I think that you should be able to override getPlotBand method in your code for enabling plotBands with bigger from value than to value:
(function(H) {
H.wrap(H.Axis.prototype, 'init', function(proceed, chart, userOptions) {
this.getPlotBandPath = function(from, to, options) {
var center = this.center,
startAngleRad = this.startAngleRad,
pick = H.pick,
map = H.map,
pInt = H.pInt,
fullRadius = center[2] / 2,
radii = [
pick(options.outerRadius, '100%'),
options.innerRadius,
pick(options.thickness, 10)
],
offset = Math.min(this.offset, 0),
percentRegex = /%$/,
start,
end,
open,
isCircular = this.isCircular, // X axis in a polar chart
ret;
// Polygonal plot bands
if (this.options.gridLineInterpolation === 'polygon') {
ret = this.getPlotLinePath(from).concat(this.getPlotLinePath(to, true));
// Circular grid bands
} else {
// Keep within bounds
from = Math.max(from, this.min);
to = Math.min(to, this.max);
// Plot bands on Y axis (radial axis) - inner and outer radius depend on to and from
if (!isCircular) {
radii[0] = this.translate(from);
radii[1] = this.translate(to);
}
// Convert percentages to pixel values
radii = map(radii, function(radius) {
if (percentRegex.test(radius)) {
radius = (pInt(radius, 10) * fullRadius) / 100;
}
return radius;
});
// Handle full circle
if (options.shape === 'circle' || !isCircular) {
start = -Math.PI / 2;
end = Math.PI * 1.5;
open = true;
} else {
start = startAngleRad + this.translate(from);
end = startAngleRad + this.translate(to);
}
radii[0] -= offset; // #5283
radii[2] -= offset; // #5283
ret = this.chart.renderer.symbols.arc(
this.left + center[0],
this.top + center[1],
radii[0],
radii[0], {
start: start, // Math is for reversed yAxis (#3606)
end: end,
innerR: pick(radii[1], radii[0] - radii[2]),
open: open
}
);
}
return ret;
}
proceed.call(this, chart, userOptions);
});
}(Highcharts))
Live example:
http://jsfiddle.net/2Ljk7usL/9/

Ipad not showing canvas lines properly

I have created small script for vision testing. I posted part of it on https://jsfiddle.net/jaka_87/bpadyanh/
The theory behind it: Canvas is filled with pattern.In each pattern there are 3 lines drawn. Two black ones with the white one in the middle. The white line has 2*with of one black line. When width of this lines is so small that our eye cant distinguish between these three we see only gray background (even thou the lines are still there).
I tested it on few computers. On most of them it works well (thou i saw some strange patterns on some of the older ones - one column of vertical white lines then 2-3 dark column then white one....) I was assuming that it has do do with the display/graphic card or something similar. I tested it on some some mobile devices. It works fine on my Nexus 7 and Moto G, but not on my Transformer Prime pad (strange pattern like described before - for which again I blame the tablet).
It looks absolutely horrible (by far the worst from all tested) on my Ipad and my friends Iphone. I was expecting the best result there since they are known for very good screens but the results are horrible. When the lines are wide enough its OK but when they get narrower they are merged together to one either black or white line - not shown separately.
Is there any way to fix that so it would work on iOS ??
var povecava2 = "0.04226744186046511";
var izmerjeno =1;
var razmak =3.5;
var contrast = 1;
var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
// širina canvasa
ctx.canvas.width = window.innerWidth-23;
ctx.canvas.height = window.innerHeight-70;
var sirinaopto=Math.round(200*izmerjeno*povecava2*razmak);
if(sirinaopto & 1){sirinaopto=sirinaopto;}else{ sirinaopto=sirinaopto+1;} // če je širina optotipa soda ali liha
var enota4 =((0.19892970392*130*izmerjeno*povecava2)/4).toFixed(2); // 1 kotna minuta
var center= Math.round((ctx.canvas.width-(sirinaopto))/2);
// kolkrat gre v višino
var kolkratgre = Math.floor(ctx.canvas.height/(sirinaopto));
var visina2= sirinaopto*kolkratgre;
// kolkrat gre v širino
var kolkratgrehor = Math.ceil(ctx.canvas.width/sirinaopto); if(kolkratgrehor % 2 == 0) { var kolkratgrehor=kolkratgrehor-1; }
var zacetek = (ctx.canvas.width-(kolkratgrehor*sirinaopto))/2;
ctx.rect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.fillStyle="rgb(140,140,140)";
ctx.fill();
// 90 stopinj
var canvasPattern0 = document.createElement("canvas");
canvasPattern0.width = sirinaopto;
canvasPattern0.height = sirinaopto;
var contextPattern0 = canvasPattern0.getContext("2d");
contextPattern0.mozImageSmoothingEnabled = false;
contextPattern0.imageSmoothingEnabled = false;
contextPattern0.translate((canvasPattern0.width/2)-(enota4*2),(canvasPattern0.width/2)-(10*enota4));
contextPattern0.beginPath();
contextPattern0.globalAlpha = contrast;
contextPattern0.moveTo(enota4/2,0);
contextPattern0.lineTo(enota4/2,20*enota4);
contextPattern0.lineWidth=enota4;
contextPattern0.strokeStyle = 'black';
contextPattern0.stroke();
contextPattern0.closePath();
contextPattern0.beginPath();
contextPattern0.globalAlpha = contrast;
contextPattern0.moveTo(enota4*2,0);
contextPattern0.lineTo(enota4*2,20*enota4);
contextPattern0.lineWidth=enota4*2;
contextPattern0.strokeStyle = 'white';
contextPattern0.stroke();
contextPattern0.closePath();
contextPattern0.beginPath();
contextPattern0.globalAlpha = contrast;
contextPattern0.moveTo(enota4*3.5,0);
contextPattern0.lineTo(enota4*3.5,20*enota4);
contextPattern0.lineWidth=enota4;
contextPattern0.strokeStyle = 'black';
contextPattern0.stroke();
contextPattern0.closePath();
// 0 stopinj
var canvasPattern1 = document.createElement("canvas");
canvasPattern1.width = sirinaopto;canvasPattern1.height = sirinaopto;
var contextPattern1 = canvasPattern1.getContext("2d");
contextPattern1.translate(sirinaopto/2, sirinaopto/2);
contextPattern1.rotate(90*Math.PI/180);
contextPattern1.drawImage(canvasPattern0, sirinaopto*(-0.5), sirinaopto*(-0.5));
contextPattern1.save();
var imagesLoaded = [];
imagesLoaded.push(canvasPattern0);
imagesLoaded.push(canvasPattern1);
var randomPattern = function(imgWidth, imgHeight, areaWidth, areaHeight) {
// either set a defined width/height for our images, or use the first one's
imgWidth = sirinaopto;
imgHeight = sirinaopto;
// restrict the randmoness size by using an areaWidth/Height
areaWidth = ctx.canvas.width;
areaHeight = visina2;
// create a buffer canvas
var patternCanvas = canvas.cloneNode(true);
var patternCtx = patternCanvas.getContext('2d');
patternCanvas.width = areaWidth;
patternCanvas.height = areaHeight;
// var xloops = Math.ceil(areaWidth / imgWidth);
var xloops = Math.ceil(areaWidth / imgWidth); if(xloops % 2 == 0) { var xloops=xloops-1; }
var yloops = Math.ceil(areaHeight / imgHeight);
//alert(xloops);
for (var xpos = 0; xpos < xloops; xpos++) {
for (var ypos = 0; ypos < yloops; ypos++) {
var img = imagesLoaded[Math.floor(Math.random() * imagesLoaded.length)];
patternCtx.drawImage(img, (xpos * imgWidth)+zacetek, (ypos * imgHeight), imgWidth, imgHeight);
}
}
// create a pattern from this randomly created image
return patternCtx.createPattern(patternCanvas, 'repeat');
}
var draw = function() {
//create the random pattern (should be moved out of the draw)
var patt = randomPattern(sirinaopto,sirinaopto);
ctx.fillStyle = patt;
ctx.fillRect(0,0,ctx.canvas.width, visina2)
};
draw();

openlayer 3: how to add visible pan control

openlayer 2.13 has a visible pan control but not ol3.
I tried adding one here: http://jsfiddle.net/tr8691ev/13/
var v=map.getView();
var c=v.getCenter();
c[1]=+2;
// p=ol.animation.pan({duration:600,source:v.getCenter()});
//map.beforeRender(p);
v.setCenter(c,v.getZoom());
This one doesn't work as it should.
What is wrong with it? Thanks.
I did a function to change the center if user pan outside an area.
In this case is important handle the resolution of the map to know how big is the area depending on zoom.
In your case when user click left you should change center
var mapHorizontalMove = (mapSize[0] * resolution) / 10.0;
var mapVerticalMove = (mapSize[1] * resolution) / 10.0;
//left
center[0] -= mapHorizontalMove;
//right
center[0] += mapHorizontalMove;
//down
center[1] -= mapVerticalMove ;
//up
center[1] += mapVerticalMove ;
Mysample:
var maxExtent = [-79.59975, -1.200, -53.03076, 13.72883];
view.on('change:center', function (evt) {
var center = view.getCenter();
var x = center[0];
var y = center[1];
var resolution = view.getResolution();
var mapSize = map.getSize();
var mapHalfWidth = (mapSize[0] * resolution) / 2.0;
var mapHalfHeight = (mapSize[1] * resolution) / 2.0;
if (center[0] - mapHalfWidth < maxExtent[0]) {
x = maxExtent[0] + mapHalfWidth;
} else if (center[0] + mapHalfWidth > maxExtent[2]) {
x = maxExtent[2] - mapHalfWidth;
}
if (center[1] - mapHalfHeight < maxExtent[1]) {
y = maxExtent[1] + mapHalfHeight;
} else if (center[1] + mapHalfHeight > maxExtent[3]) {
y = maxExtent[3] - mapHalfHeight;
}
if (center[0] != x || center[1] != y) {
view.setCenter([x, y]);
}
});
.:| Just for whom witch reaches here like Me |:.
If you have got a OpenLayers' map without any controls visible,
And every thing seems Ok in your code,
Just add ol.css in your Head tag and all will be come back.

Resources