before merge

This commit is contained in:
Pavel Talanov
2012-02-24 17:20:23 +04:00
parent c949944980
commit 6646278a60
566 changed files with 43420 additions and 3 deletions
@@ -0,0 +1,545 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
var classes = function () {
var Vector = Kotlin.Class.create({initialize:function (x, y) {
this.$x = x;
this.$y = y;
}, get_x:function () {
return this.$x;
}, get_y:function () {
return this.$y;
}, plus:function (v) {
{
return creatures.v_0(this.get_x() + v.get_x(), this.get_y() + v.get_y());
}
}, minus:function () {
{
return creatures.v_0(-this.get_x(), -this.get_y());
}
}, minus$0:function (v) {
{
return creatures.v_0(this.get_x() - v.get_x(), this.get_y() - v.get_y());
}
}, times:function (koef) {
{
return creatures.v_0(this.get_x() * koef, this.get_y() * koef);
}
}, distanceTo:function (v) {
{
return Math.sqrt(this.minus$0(v).get_sqr());
}
}, rotatedBy:function (theta) {
{
var sin = Math.sin(theta);
var cos = Math.cos(theta);
return creatures.v_0(this.get_x() * cos - this.get_y() * sin, this.get_x() * sin + this.get_y() * cos);
}
}, isInRect:function (topLeft, size) {
{
return this.get_x() >= topLeft.get_x() && this.get_x() <= topLeft.get_x() + size.get_x() && this.get_y() >= topLeft.get_y() && this.get_y() <= topLeft.get_y() + size.get_y();
}
}, get_sqr:function () {
{
return this.get_x() * this.get_x() + this.get_y() * this.get_y();
}
}, get_normalized:function () {
{
return this.times(1 / Math.sqrt(this.get_sqr()));
}
}
});
var RadialGradientGenerator = Kotlin.Class.create({initialize:function (context) {
this.$context = context;
this.$gradients = new Kotlin.ArrayList;
this.$current = 0;
{
this.newColorStops([
[0, '#F59898'],
[0.5, '#F57373'],
[1, '#DB6B6B']
]);
this.newColorStops([
[0.39, 'rgb(140,167,209)'],
[0.7, 'rgb(104,139,209)'],
[0.85, 'rgb(67,122,217)']
]);
this.newColorStops([
[0, 'rgb(255,222,255)'],
[0.5, 'rgb(255,185,222)'],
[1, 'rgb(230,154,185)']
]);
this.newColorStops([
[0, 'rgb(255,209,114)'],
[0.5, 'rgb(255,174,81)'],
[1, 'rgb(241,145,54)']
]);
this.newColorStops([
[0, 'rgb(132,240,135)'],
[0.5, 'rgb(91,240,96)'],
[1, 'rgb(27,245,41)']
]);
this.newColorStops([
[0, 'rgb(250,147,250)'],
[0.5, 'rgb(255,80,255)'],
[1, 'rgb(250,0,217)']
]);
}
}, get_context:function () {
return this.$context;
}, get_gradients:function () {
return this.$gradients;
}, get_current:function () {
return this.$current;
}, set_current:function (tmp$0) {
this.$current = tmp$0;
}, newColorStops:function (colorStops) {
{
this.get_gradients().add(colorStops);
}
}, getNext:function () {
{
var result = this.get_gradients().get(this.get_current());
this.set_current((this.get_current() + 1) % this.get_gradients().size());
return result;
}
}
});
var CanvasState = Kotlin.Class.create({initialize:function (canvas) {
this.$canvas = canvas;
this.$width = this.get_canvas().width;
this.$height = this.get_canvas().height;
this.$context = getContext();
this.$valid = false;
this.$shapes = new Kotlin.ArrayList;
this.$selection = null;
this.$dragOff = new creatures.Vector_0(0, 0);
this.$interval = 1000 / 30;
{
var tmp$4;
var tmp$3;
var tmp$2;
var tmp$1;
var tmp$0_0;
$(this.get_canvas()).mousedown((tmp$0_0 = this , function (it) {
{
var tmp$0;
tmp$0_0.set_valid(false);
tmp$0_0.set_selection(null);
var mousePos = tmp$0_0.mousePos_0(it);
{
tmp$0 = tmp$0_0.get_shapes().iterator();
while (tmp$0.hasNext()) {
var shape = tmp$0.next();
{
if (shape.contains(mousePos)) {
tmp$0_0.set_dragOff(mousePos.minus$0(shape.get_pos()));
shape.set_selected(true);
tmp$0_0.set_selection(shape);
break;
}
}
}
}
}
}
));
$(this.get_canvas()).mousemove((tmp$1 = this , function (it) {
{
if (tmp$1.get_selection() != null) {
Kotlin.sure(tmp$1.get_selection()).set_pos(tmp$1.mousePos_0(it).minus$0(tmp$1.get_dragOff()));
tmp$1.set_valid(false);
}
}
}
));
$(this.get_canvas()).mouseup((tmp$2 = this , function (it) {
{
if (tmp$2.get_selection() != null) {
Kotlin.sure(tmp$2.get_selection()).set_selected(false);
}
tmp$2.set_selection(null);
tmp$2.set_valid(false);
}
}
));
$(this.get_canvas()).dblclick((tmp$3 = this , function (it) {
{
var newCreature = new creatures.Creature_0(tmp$3.mousePos_0(it), tmp$3);
tmp$3.addShape(newCreature);
tmp$3.set_valid(false);
}
}
));
setInterval((tmp$4 = this , function () {
{
tmp$4.draw();
}
}
), this.get_interval());
}
}, get_canvas:function () {
return this.$canvas;
}, get_width:function () {
return this.$width;
}, set_width:function (tmp$0) {
this.$width = tmp$0;
}, get_height:function () {
return this.$height;
}, set_height:function (tmp$0) {
this.$height = tmp$0;
}, get_size:function () {
{
return creatures.v_0(this.get_width(), this.get_height());
}
}, get_context:function () {
return this.$context;
}, get_valid:function () {
return this.$valid;
}, set_valid:function (tmp$0) {
this.$valid = tmp$0;
}, get_shapes:function () {
return this.$shapes;
}, set_shapes:function (tmp$0) {
this.$shapes = tmp$0;
}, get_selection:function () {
return this.$selection;
}, set_selection:function (tmp$0) {
this.$selection = tmp$0;
}, get_dragOff:function () {
return this.$dragOff;
}, set_dragOff:function (tmp$0) {
this.$dragOff = tmp$0;
}, get_interval:function () {
return this.$interval;
}, mousePos_0:function (e) {
{
var offset = new creatures.Vector_0(0, 0);
var element = this.get_canvas();
while (element != null) {
var el = Kotlin.sure(element);
offset = offset.plus(new creatures.Vector_0(el.offsetLeft, el.offsetTop));
element = el.offsetParent;
}
return (new creatures.Vector_0(e.pageX, e.pageY)).minus$0(offset);
}
}, addShape:function (shape) {
{
this.get_shapes().add(shape);
this.set_valid(false);
}
}, clear:function () {
{
this.get_context().fillStyle = '#FFFFFF';
this.get_context().fillRect(0, 0, this.get_width(), this.get_height());
this.get_context().strokeStyle = '#000000';
this.get_context().lineWidth = 4;
this.get_context().strokeRect(0, 0, this.get_width(), this.get_height());
}
}, draw:function () {
{
var tmp$0;
if (this.get_valid())
return;
this.clear();
{
tmp$0 = creatures.reversed(this.get_shapes()).iterator();
while (tmp$0.hasNext()) {
var shape = tmp$0.next();
{
shape.draw(this);
}
}
}
creatures.get_Kotlin().draw(this);
this.set_valid(true);
}
}
});
var Shape = Kotlin.Class.create({initialize:function () {
this.$selected = false;
}, draw:function (state) {
}, contains:function (mousePos) {
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_selected:function () {
return this.$selected;
}, set_selected:function (tmp$0) {
this.$selected = tmp$0;
}, shadowed:function (receiver, shadowOffset, alpha, render) {
{
receiver.save();
receiver.shadowColor = 'rgba(100, 100, 100, ' + alpha + ')';
receiver.shadowBlur = 5;
receiver.shadowOffsetX = shadowOffset.get_x();
receiver.shadowOffsetY = shadowOffset.get_y();
render.call(receiver);
receiver.restore();
}
}, fillPath:function (receiver, constructPath) {
{
receiver.beginPath();
constructPath.call(receiver);
receiver.closePath();
receiver.fill();
}
}
});
var Creature = Kotlin.Class.create(Shape, {initialize:function (pos, state) {
this.$pos = pos;
this.$state = state;
this.super_init();
this.$shadowOffset = creatures.v_0(-5, 5);
this.$colorStops = creatures.get_gradientGenerator().getNext();
this.$relSize = 0.05;
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_state:function () {
return this.$state;
}, get_shadowOffset:function () {
return this.$shadowOffset;
}, get_colorStops:function () {
return this.$colorStops;
}, get_relSize:function () {
return this.$relSize;
}, get_radius:function () {
{
return this.get_state().get_width() * this.get_relSize();
}
}, get_position:function () {
var tmp$0;
if (this.get_selected())
tmp$0 = this.get_pos().minus$0(this.get_shadowOffset());
else
tmp$0 = this.get_pos();
{
return tmp$0;
}
}, get_directionToLogo:function () {
{
return creatures.get_Kotlin().get_centre().minus$0(this.get_position()).get_normalized();
}
}, contains:function (mousePos) {
{
return this.get_pos().distanceTo(mousePos) < this.get_radius();
}
}, circlePath:function (receiver, position, rad) {
{
receiver.arc(position.get_x(), position.get_y(), rad, 0, 2 * Math.PI, false);
}
}, fillCircle:function (receiver, position, rad) {
{
var tmp$0;
this.fillPath(receiver, (tmp$0 = this , function () {
{
tmp$0.circlePath(receiver, position, rad);
}
}
));
}
}, draw:function (state) {
{
var context = state.get_context();
if (!this.get_selected()) {
this.drawCreature(context);
}
else {
this.drawCreatureWithShadow(context);
}
}
}, drawCreature:function (context) {
{
var tmp$0;
context.fillStyle = this.getGradient(context);
this.fillPath(context, (tmp$0 = this , function () {
{
tmp$0.tailPath(context);
tmp$0.circlePath(this, tmp$0.get_position(), tmp$0.get_radius());
}
}
));
this.drawEye(context);
}
}, getGradient:function (context) {
{
var tmp$0;
var gradientCentre = this.get_position().plus(this.get_directionToLogo().times(this.get_radius() / 4));
var gradient = context.createRadialGradient(gradientCentre.get_x(), gradientCentre.get_y(), 1, gradientCentre.get_x(), gradientCentre.get_y(), 2 * this.get_radius());
{
tmp$0 = Kotlin.arrayIterator(this.get_colorStops());
while (tmp$0.hasNext()) {
var colorStop = tmp$0.next();
{
gradient.addColorStop(colorStop[0], colorStop[1]);
}
}
}
return gradient;
}
}, tailPath:function (context) {
{
var tailDirection = this.get_directionToLogo().minus();
var tailPos = this.get_position().plus(tailDirection.times(this.get_radius()).times(1));
var tailSize = this.get_radius() * 1.6;
var angle = Math.PI / 6;
var p1 = tailPos.plus(tailDirection.rotatedBy(angle).times(tailSize));
var p2 = tailPos.plus(tailDirection.rotatedBy(-angle).times(tailSize));
var middlePoint = this.get_position().plus(tailDirection.times(this.get_radius()).times(1));
context.moveTo(tailPos.get_x(), tailPos.get_y());
context.lineTo(p1.get_x(), p1.get_y());
context.quadraticCurveTo(middlePoint.get_x(), middlePoint.get_y(), p2.get_x(), p2.get_y());
context.lineTo(tailPos.get_x(), tailPos.get_y());
}
}, drawEye:function (context) {
{
var eyePos = this.get_directionToLogo().times(this.get_radius()).times(0.6).plus(this.get_position());
var eyeRadius = this.get_radius() / 3;
var eyeLidRadius = eyeRadius / 2;
context.fillStyle = '#FFFFFF';
this.fillCircle(context, eyePos, eyeRadius);
context.fillStyle = '#000000';
this.fillCircle(context, eyePos, eyeLidRadius);
}
}, drawCreatureWithShadow:function (context) {
{
var tmp$0_0;
this.shadowed(context, this.get_shadowOffset(), 0.7, (tmp$0_0 = this , function () {
{
var tmp$0;
context.fillStyle = tmp$0_0.getGradient(context);
tmp$0_0.fillPath(this, (tmp$0 = tmp$0_0 , function () {
{
tmp$0.tailPath(context);
tmp$0.circlePath(context, tmp$0.get_position(), tmp$0.get_radius());
}
}
));
}
}
));
this.drawEye(context);
}
}
});
var Logo = Kotlin.Class.create(Shape, {initialize:function (pos) {
this.$pos = pos;
this.super_init();
this.$relSize = 0.25;
this.$shadowOffset = creatures.v_0(-3, 3);
this.$imageSize = creatures.v_0(377, 393);
this.$size = this.get_imageSize().times(this.get_relSize());
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_relSize:function () {
return this.$relSize;
}, get_shadowOffset:function () {
return this.$shadowOffset;
}, get_imageSize:function () {
return this.$imageSize;
}, get_size:function () {
return this.$size;
}, set_size:function (tmp$0) {
this.$size = tmp$0;
}, get_position:function () {
var tmp$0;
if (this.get_selected())
tmp$0 = this.get_pos().minus$0(this.get_shadowOffset());
else
tmp$0 = this.get_pos();
{
return tmp$0;
}
}, drawLogo:function (state) {
{
this.set_size(this.get_imageSize().times(state.get_size().get_x() / this.get_imageSize().get_x()).times(this.get_relSize()));
state.get_context().drawImage(getKotlinLogo(), 0, 0, this.get_imageSize().get_x(), this.get_imageSize().get_y(), this.get_position().get_x(), this.get_position().get_y(), this.get_size().get_x(), this.get_size().get_y());
}
}, draw:function (state) {
{
var context = state.get_context();
if (this.get_selected()) {
var tmp$0;
this.shadowed(context, this.get_shadowOffset(), 0.2, (tmp$0 = this , function () {
{
tmp$0.drawLogo(state);
}
}
));
}
else {
this.drawLogo(state);
}
}
}, contains:function (mousePos) {
{
return mousePos.isInRect(this.get_pos(), this.get_size());
}
}, get_centre:function () {
{
return this.get_pos().plus(this.get_size().times(0.5));
}
}
});
return {Shape_0:Shape, Logo_0:Logo, Creature_0:Creature, RadialGradientGenerator_0:RadialGradientGenerator, CanvasState_0:CanvasState, Vector_0:Vector};
}
();
var creatures = Kotlin.Namespace.create({initialize:function () {
creatures.$Kotlin = new creatures.Logo_0(creatures.v_0(300, 100));
creatures.$gradientGenerator = new creatures.RadialGradientGenerator_0(getContext());
}, get_Kotlin:function () {
return creatures.$Kotlin;
}, get_gradientGenerator:function () {
return creatures.$gradientGenerator;
}, v_0:function (x, y) {
{
return new creatures.Vector_0(x, y);
}
}, main:function () {
{
var state = new creatures.CanvasState_0(getCanvas());
state.addShape(creatures.get_Kotlin());
state.addShape(new creatures.Creature_0(state.get_size().times(0.25), state));
state.addShape(new creatures.Creature_0(state.get_size().times(0.75), state));
setTimeout(function () {
{
state.set_valid(false);
}
}
);
}
}, reversed:function (receiver) {
{
var result = new Kotlin.ArrayList;
var i = receiver.size();
while (i > 0) {
result.add(receiver.get(--i));
}
return result;
}
}
}, classes);
creatures.initialize();
}
var args = [];
creatures.main(args);
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

+331
View File
@@ -0,0 +1,331 @@
/*
In this example strange creatures are watching the kotlin logo. You can drag'n'drop them as well as the logo.
Doubleclick to add more creatures but be careful. They may be watching you!
*/
package creatures
// importing some of the API defined
import jquery.*
import html5.*
import java.util.ArrayList
import js.*
import js.Math
import js.setInterval
import html5.getCanvas
import html5.getKotlinLogo
import jquery.jq
import js.setTimeout
import java.util.List
abstract class Shape() {
abstract fun draw(state : CanvasState)
// these two abstract methods defines that our shapes can be dragged
abstract fun contains(mousePos : Vector) : Boolean
abstract var pos : Vector
var selected : Boolean = false
// a couple of helper extension methods we'll be using in the derived classes
fun Context.shadowed(shadowOffset : Vector, alpha : Double, render : Context.() -> Unit) {
save()
shadowColor = "rgba(100, 100, 100, $alpha)"
shadowBlur = 5.0
shadowOffsetX = shadowOffset.x
shadowOffsetY = shadowOffset.y
render()
restore()
}
fun Context.fillPath(constructPath : Context.() -> Unit) {
beginPath()
constructPath()
closePath()
fill()
}
}
val Kotlin = Logo(v(300.0, 100.0))
class Logo(override var pos : Vector) : Shape()
{
val relSize : Double = 0.25
val shadowOffset = v(-3.0, 3.0)
val imageSize = v(377.0, 393.0)
var size : Vector = imageSize * relSize
// get-only properties like this saves you lots of typing and are very expressive
val position : Vector
get() = if (selected) pos - shadowOffset else pos
fun drawLogo(state : CanvasState) {
size = imageSize * (state.size.x / imageSize.x) * relSize
// getKotlinLogo() is a 'magic' function here defined only for purposes of demonstration but in fact it just find an element containing the logo
state.context.drawImage(getKotlinLogo(), 0.0, 0.0, imageSize.x, imageSize.y, position.x, position.y, size.x, size.y)
}
override fun draw(state : CanvasState) {
val context = state.context
if (selected) {
// using helper we defined in Shape class
context.shadowed(shadowOffset, 0.2) {
drawLogo(state)
}
} else {
drawLogo(state)
}
}
override fun contains(mousePos: Vector): Boolean = mousePos.isInRect(pos, size)
val centre : Vector
get() = pos + size * 0.5
}
val gradientGenerator = RadialGradientGenerator(getContext())
class Creature(override var pos : Vector, val state : CanvasState) : Shape() {
val shadowOffset = v(-5.0, 5.0)
val colorStops = gradientGenerator.getNext()
val relSize = 0.05
// these properties have no backing fields and in java/javascript they could be represented as little helper functions
val radius : Double
get() = state.width * relSize
val position : Vector
get() = if (selected) pos - shadowOffset else pos
val directionToLogo : Vector
get() = (Kotlin.centre - position).normalized
//notice how the infix call can make some expressions extremely expressive
override fun contains(mousePos : Vector) = pos distanceTo mousePos < radius
// defining more nice extension functions
fun Context.circlePath(position : Vector, rad : Double) {
arc(position.x, position.y, rad, 0.0, 2 * Math.PI, false)
}
//notice we can use an extension function we just defined inside another extension function
fun Context.fillCircle(position : Vector, rad : Double) {
fillPath {
circlePath(position, rad)
}
}
override fun draw(state : CanvasState) {
val context = state.context
if (!selected) {
drawCreature(context)
} else {
drawCreatureWithShadow(context)
}
}
fun drawCreature(context : Context) {
context.fillStyle = getGradient(context)
context.fillPath {
tailPath(context)
circlePath(position, radius)
}
drawEye(context)
}
fun getGradient(context : Context) : CanvasGradient {
val gradientCentre = position + directionToLogo * (radius / 4)
val gradient = context.createRadialGradient(gradientCentre.x, gradientCentre.y, 1.0, gradientCentre.x, gradientCentre.y, 2 * radius)
for (colorStop in colorStops) {
gradient.addColorStop(colorStop._1, colorStop._2)
}
return gradient
}
fun tailPath(context : Context) {
val tailDirection = -directionToLogo
val tailPos = position + tailDirection * radius * 1.0
val tailSize = radius * 1.6
val angle = Math.PI / 6.0
val p1 = tailPos + tailDirection.rotatedBy(angle) * tailSize
val p2 = tailPos + tailDirection.rotatedBy(-angle) * tailSize
val middlePoint = position + tailDirection * radius * 1.0
context.moveTo(tailPos.x, tailPos.y)
context.lineTo(p1.x, p1.y)
context.quadraticCurveTo(middlePoint.x, middlePoint.y, p2.x, p2.y)
context.lineTo(tailPos.x, tailPos.y)
}
fun drawEye(context : Context) {
val eyePos = directionToLogo * radius * 0.6 + position
val eyeRadius = radius / 3
val eyeLidRadius = eyeRadius / 2
context.fillStyle = "#FFFFFF"
context.fillCircle(eyePos, eyeRadius)
context.fillStyle = "#000000"
context.fillCircle(eyePos, eyeLidRadius)
}
fun drawCreatureWithShadow(context : Context) {
context.shadowed(shadowOffset, 0.7) {
context.fillStyle = getGradient(context)
fillPath {
tailPath(context)
context.circlePath(position, radius)
}
}
drawEye(context)
}
}
class CanvasState(val canvas : Canvas) {
var width = canvas.width
var height = canvas.height
val size : Vector
get() = v(width, height)
val context = getContext()
var valid = false
var shapes = ArrayList<Shape>()
var selection : Shape? = null
var dragOff = Vector()
val interval = 1000 / 30
{
jq(canvas).mousedown {
valid = false
selection = null
val mousePos = mousePos(it)
for (shape in shapes) {
if (mousePos in shape) {
dragOff = mousePos - shape.pos
shape.selected = true
selection = shape
break
}
}
}
jq(canvas).mousemove {
if (selection != null) {
selection.sure().pos = mousePos(it) - dragOff
valid = false
}
}
jq(canvas).mouseup {
if (selection != null) {
selection.sure().selected = false
}
selection = null
valid = false
}
jq(canvas).dblclick {
val newCreature = Creature(mousePos(it), this @CanvasState)
addShape(newCreature)
valid = false
}
setInterval({
draw()
}, interval)
}
fun mousePos(e : MouseEvent) : Vector {
var offset = Vector()
var element : DomElement? = canvas
while (element != null) {
val el : DomElement = element.sure()
offset += Vector(el.offsetLeft, el.offsetTop)
element = el.offsetParent
}
return Vector(e.pageX, e.pageY) - offset
}
fun addShape(shape : Shape) {
shapes.add(shape)
valid = false
}
fun clear() {
context.fillStyle = "#FFFFFF"
context.fillRect(0.0, 0.0, width, height)
context.strokeStyle = "#000000"
context.lineWidth = 4.0
context.strokeRect(0.0, 0.0, width, height)
}
fun draw() {
if (valid) return
clear()
for (shape in shapes.reversed()) {
shape.draw(this)
}
Kotlin.draw(this)
valid = true
}
}
class RadialGradientGenerator(val context : Context) {
val gradients = ArrayList<Array<#(Double, String)>>()
var current = 0
fun newColorStops(vararg colorStops : #(Double, String)) {
gradients.add(colorStops)
}
{
newColorStops(#(0.0, "#F59898"), #(0.5, "#F57373"), #(1.0, "#DB6B6B"))
newColorStops(#(0.39, "rgb(140,167,209)"), #(0.7, "rgb(104,139,209)"), #(0.85, "rgb(67,122,217)"))
newColorStops(#(0.0, "rgb(255,222,255)"), #(0.5, "rgb(255,185,222)"), #(1.0, "rgb(230,154,185)"))
newColorStops(#(0.0, "rgb(255,209,114)"), #(0.5, "rgb(255,174,81)"), #(1.0, "rgb(241,145,54)"))
newColorStops(#(0.0, "rgb(132,240,135)"), #(0.5, "rgb(91,240,96)"), #(1.0, "rgb(27,245,41)"))
newColorStops(#(0.0, "rgb(250,147,250)"), #(0.5, "rgb(255,80,255)"), #(1.0, "rgb(250,0,217)"))
}
fun getNext() : Array<#(Double, String)> {
val result = gradients.get(current)
current = (current + 1) % gradients.size()
return result
}
}
fun v(x : Double, y : Double) = Vector(x, y)
class Vector(val x : Double = 0.0, val y : Double = 0.0) {
fun plus(v : Vector) = v(x + v.x, y + v.y)
fun minus() = v(-x, -y)
fun minus(v : Vector) = v(x - v.x, y - v.y)
fun times(koef : Double) = v(x * koef, y * koef)
fun distanceTo(v : Vector) = Math.sqrt((this - v).sqr)
fun rotatedBy(theta : Double) : Vector {
val sin = Math.sin(theta)
val cos = Math.cos(theta)
return v(x * cos - y * sin, x * sin + y * cos)
}
fun isInRect(topLeft : Vector, size : Vector) = (x >= topLeft.x) && (x <= topLeft.x + size.x) &&
(y >= topLeft.y) && (y <= topLeft.y + size.y)
val sqr : Double
get() = x * x + y * y
val normalized : Vector
get() = this * (1.0 / Math.sqrt(sqr))
}
fun main() {
val state = CanvasState(getCanvas())
state.addShape(Kotlin)
state.addShape(Creature(state.size * 0.25, state))
state.addShape(Creature(state.size * 0.75, state))
setTimeout({
state.valid = false
})
}
fun <T> List<T>.reversed() : List<T> {
val result = ArrayList<T>()
var i = size()
while (i > 0) {
result.add(get(--i))
}
return result
}
@@ -0,0 +1,32 @@
<!--
~ Copyright 2000-2012 JetBrains s.r.o.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Canvas demo</title>
</head>
<canvas width="600" height="800"></canvas>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="../../../../translator/testFiles/kotlin_lib.js" type="text/javascript"></script>
<script src="../../../../translator/testFiles/canvas_helper.js" type="text/javascript"></script>
<script src="creatures.js" type="text/javascript"></script>
<img src="kotlinlogo.png" hidden=true/>
</body>
</html>
@@ -0,0 +1,103 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
var classes = function () {
var FancyLines = Kotlin.Class.create({initialize:function () {
this.$context = getContext();
this.$height = getCanvas().height;
this.$width = getCanvas().width;
this.$x = this.get_width() * Math.random();
this.$y = this.get_height() * Math.random();
this.$hue = 0;
}, get_context:function () {
return this.$context;
}, get_height:function () {
return this.$height;
}, get_width:function () {
return this.$width;
}, get_x:function () {
return this.$x;
}, set_x:function (tmp$0) {
this.$x = tmp$0;
}, get_y:function () {
return this.$y;
}, set_y:function (tmp$0) {
this.$y = tmp$0;
}, get_hue:function () {
return this.$hue;
}, set_hue:function (tmp$0) {
this.$hue = tmp$0;
}, line:function () {
{
this.get_context().save();
this.get_context().beginPath();
this.get_context().lineWidth = 20 * Math.random();
this.get_context().moveTo(this.get_x(), this.get_y());
this.set_x(this.get_width() * Math.random());
this.set_y(this.get_height() * Math.random());
this.get_context().bezierCurveTo(this.get_width() * Math.random(), this.get_height() * Math.random(), this.get_width() * Math.random(), this.get_height() * Math.random(), this.get_x(), this.get_y());
this.set_hue(this.get_hue() + Math.random() * 10);
this.get_context().strokeStyle = 'hsl(' + this.get_hue() + ', 50%, 50%)';
this.get_context().shadowColor = 'white';
this.get_context().shadowBlur = 10;
this.get_context().stroke();
this.get_context().restore();
}
}, blank:function () {
{
this.get_context().fillStyle = 'rgba(255,255,1,0.1)';
this.get_context().fillRect(0, 0, this.get_width(), this.get_height());
}
}, run:function () {
{
var tmp$1;
var tmp$0;
setInterval((tmp$0 = this , function () {
{
tmp$0.line();
}
}
), 40);
setInterval((tmp$1 = this , function () {
{
tmp$1.blank();
}
}
), 100);
}
}
});
return {FancyLines_0:FancyLines};
}
();
var fancylines = Kotlin.Namespace.create({initialize:function () {
}, main:function () {
{
$(function () {
{
(new fancylines.FancyLines_0).run();
}
}
);
}
}
}, classes);
fancylines.initialize();
}
var args = [];
fancylines.main(args);
@@ -0,0 +1,30 @@
<!--
~ Copyright 2000-2012 JetBrains s.r.o.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Canvas demo</title>
</head>
<body>
<canvas height="450" width="800"></canvas>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="../../../../translator/testFiles/kotlin_lib.js" type="text/javascript"></script>
<script src="../../../../translator/testFiles/canvas_helper.js" type="text/javascript"></script>
<script src="fancylines.js" type="text/javascript"></script>
</body>
</html>
@@ -0,0 +1,64 @@
/*
This example is based on example from html5 canvas2D docs:
http://www.w3.org/TR/2dcontext/
Note that only a subset of the api is supported for now.
*/
package fancylines
import js.*;
import html5.*;
import jquery.*;
fun main() {
//jq is a name for JQuery function
jq {
FancyLines().run();
}
}
class FancyLines() {
// we use two 'magic' functions here getContext() and getCanvas()
val context = getContext();
val height = getCanvas().height;
val width = getCanvas().width;
var x = width * Math.random();
var y = height * Math.random();
var hue = 0;
fun line() {
context.save();
context.beginPath();
context.lineWidth = 20.0 * Math.random();
context.moveTo(x, y);
x = width * Math.random();
y = height * Math.random();
context.bezierCurveTo(width * Math.random(), height * Math.random(),
width * Math.random(), height * Math.random(), x, y);
hue += Math.random() * 10;
context.strokeStyle = "hsl($hue, 50%, 50%)";
context.shadowColor = "white";
context.shadowBlur = 10.0;
context.stroke();
context.restore();
}
fun blank() {
context.fillStyle = "rgba(255,255,1,0.1)";
context.fillRect(0.0, 0.0, width, height);
}
fun run() {
setInterval({line()}, 40);
setInterval({blank()}, 100);
}
}
@@ -0,0 +1,162 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
var classes = function () {
var HelloKotlin = Kotlin.Class.create({initialize:function () {
this.$relX = 0.2 + 0.2 * Math.random();
this.$relY = 0.4 + 0.2 * Math.random();
this.$relXVelocity = this.randomVelocity();
this.$relYVelocity = this.randomVelocity();
this.$message = 'Hello, Kotlin!';
this.$textHeightInPixels = 60;
{
hello.get_context().font = 'bold ' + this.get_textHeightInPixels() + 'px Georgia, serif';
}
this.$textWidthInPixels = hello.get_context().measureText(this.get_message()).width;
}, get_relX:function () {
return this.$relX;
}, set_relX:function (tmp$0) {
this.$relX = tmp$0;
}, get_relY:function () {
return this.$relY;
}, set_relY:function (tmp$0) {
this.$relY = tmp$0;
}, get_absX:function () {
{
return this.get_relX() * hello.get_width();
}
}, get_absY:function () {
{
return this.get_relY() * hello.get_height();
}
}, get_relXVelocity:function () {
return this.$relXVelocity;
}, set_relXVelocity:function (tmp$0) {
this.$relXVelocity = tmp$0;
}, get_relYVelocity:function () {
return this.$relYVelocity;
}, set_relYVelocity:function (tmp$0) {
this.$relYVelocity = tmp$0;
}, get_message:function () {
return this.$message;
}, get_textHeightInPixels:function () {
return this.$textHeightInPixels;
}, get_textWidthInPixels:function () {
return this.$textWidthInPixels;
}, draw:function () {
{
hello.get_context().save();
this.move();
hello.get_context().shadowColor = '#000000';
hello.get_context().shadowBlur = 5;
hello.get_context().shadowOffsetX = -4;
hello.get_context().shadowOffsetY = 4;
hello.get_context().fillStyle = 'rgb(242,160,110)';
hello.get_context().fillText(this.get_message(), this.get_absX(), this.get_absY());
hello.get_context().restore();
}
}, move:function () {
{
var relTextWidth = this.get_textWidthInPixels() / hello.get_width();
if (this.get_relX() > 1 - relTextWidth - this.get_abs(this.get_relXVelocity()) || this.get_relX() < this.get_abs(this.get_relXVelocity())) {
this.set_relXVelocity(this.get_relXVelocity() * -1);
}
var relTextHeight = this.get_textHeightInPixels() / hello.get_height();
if (this.get_relY() > 1 - this.get_abs(this.get_relYVelocity()) || this.get_relY() < this.get_abs(this.get_relYVelocity()) + relTextHeight) {
this.set_relYVelocity(this.get_relYVelocity() * -1);
}
this.set_relX(this.get_relX() + this.get_relXVelocity());
this.set_relY(this.get_relY() + this.get_relYVelocity());
}
}, randomVelocity:function () {
var tmp$0;
if (Math.random() < 0.5)
tmp$0 = 1;
else
tmp$0 = -1;
{
return 0.03 * Math.random() * tmp$0;
}
}, get_abs:function (receiver) {
var tmp$0;
if (receiver > 0)
tmp$0 = receiver;
else
tmp$0 = -receiver;
{
return tmp$0;
}
}
});
return {HelloKotlin_0:HelloKotlin};
}
();
var hello = Kotlin.Namespace.create({initialize:function () {
hello.$context = getContext();
hello.$height = getCanvas().height;
hello.$width = getCanvas().width;
}, get_context:function () {
return hello.$context;
}, get_height:function () {
return hello.$height;
}, get_width:function () {
return hello.$width;
}, renderBackground:function () {
{
hello.get_context().save();
hello.get_context().fillStyle = '#5C7EED';
hello.get_context().fillRect(0, 0, hello.get_width(), hello.get_height());
hello.get_context().restore();
}
}, main:function () {
{
var interval = 50;
var logos = Kotlin.arrayFromFun(3, function (it) {
{
return new hello.HelloKotlin_0;
}
}
);
$(function () {
{
setInterval(function () {
{
var tmp$0;
hello.renderBackground();
{
tmp$0 = Kotlin.arrayIterator(logos);
while (tmp$0.hasNext()) {
var logo = tmp$0.next();
{
logo.draw();
}
}
}
}
}
, interval);
}
}
);
}
}
}, classes);
hello.initialize();
}
var args = [];
hello.main(args);
@@ -0,0 +1,30 @@
<!--
~ Copyright 2000-2012 JetBrains s.r.o.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Canvas demo</title>
</head>
<body>
<canvas height="450" width="800"></canvas>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="../../../../translator/testFiles/kotlin_lib.js" type="text/javascript"></script>
<script src="../../../../translator/testFiles/canvas_helper.js" type="text/javascript"></script>
<script src="hello.js" type="text/javascript"></script>
</body>
</html>
@@ -0,0 +1,91 @@
/*
This example is just simple text floating around. If u are using chrome, there is a bug that spoil the visuals.
*/
package hello
import js.*
import html5.*
import jquery.*
val context = getContext()
val height = getCanvas().height
val width = getCanvas().width
// class representing a floating text
class HelloKotlin() {
var relX = 0.2 + 0.2 * Math.random()
var relY = 0.4 + 0.2 * Math.random()
val absX : Double
get() = (relX * width)
val absY : Double
get() = (relY * height)
var relXVelocity = randomVelocity()
var relYVelocity = randomVelocity()
val message = "Hello, Kotlin!"
val textHeightInPixels = 60
{
context.font = "bold ${textHeightInPixels}px Georgia, serif"
}
val textWidthInPixels = context.measureText(message).width
fun draw() {
context.save()
move()
// if you using chrome chances are good you wont see the shadow
context.shadowColor = "#000000"
context.shadowBlur = 5.0
context.shadowOffsetX = -4.0
context.shadowOffsetY = 4.0
context.fillStyle = "rgb(242,160,110)"
context.fillText(message, absX, absY)
context.restore()
}
fun move() {
val relTextWidth = textWidthInPixels / width
if (relX > (1.0 - relTextWidth - relXVelocity.abs) || relX < relXVelocity.abs) {
relXVelocity *= -1
}
val relTextHeight = textHeightInPixels / height
if (relY > (1.0 - relYVelocity.abs) || relY < relYVelocity.abs + relTextHeight) {
relYVelocity *= -1
}
relX += relXVelocity
relY += relYVelocity
}
fun randomVelocity() = 0.03 * Math.random() * (if (Math.random() < 0.5) 1 else -1)
val Double.abs : Double
get() = if (this > 0) this else -this
}
fun renderBackground() {
context.save()
context.fillStyle = "#5C7EED"
context.fillRect(0.0, 0.0, width, height)
context.restore()
}
fun main() {
val interval = 50
// we pass a literal that constructs a new HelloKotlin object
val logos = Array(3) {
HelloKotlin()
}
jq {
setInterval({
renderBackground()
for (logo in logos) {
logo.draw()
}
}, interval)
}
}
@@ -0,0 +1,339 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
var classes = function () {
var Vector = Kotlin.Class.create({initialize:function (x, y) {
this.$x = x;
this.$y = y;
}, get_x:function () {
return this.$x;
}, set_x:function (tmp$0) {
this.$x = tmp$0;
}, get_y:function () {
return this.$y;
}, set_y:function (tmp$0) {
this.$y = tmp$0;
}, plus:function (v) {
{
return interactive.v_0(this.get_x() + v.get_x(), this.get_y() + v.get_y());
}
}, minus:function (v) {
{
return interactive.v_0(this.get_x() - v.get_x(), this.get_y() - v.get_y());
}
}, times:function (coef) {
{
return interactive.v_0(this.get_x() * coef, this.get_y() * coef);
}
}, distanceTo:function (v) {
{
return Math.sqrt(this.minus(v).get_sqr());
}
}, isInRect:function (topLeft, size) {
{
return this.get_x() >= topLeft.get_x() && this.get_x() <= topLeft.get_x() + size.get_x() && this.get_y() >= topLeft.get_y() && this.get_y() <= topLeft.get_y() + size.get_y();
}
}, get_sqr:function () {
{
return this.get_x() * this.get_x() + this.get_y() * this.get_y();
}
}
});
var CanvasState = Kotlin.Class.create({initialize:function (canvas) {
this.$canvas = canvas;
this.$width = this.get_canvas().width;
this.$height = this.get_canvas().height;
this.$context = getContext();
this.$valid = false;
this.$shapes = new Kotlin.ArrayList;
this.$selection = null;
this.$dragOff = new interactive.Vector_0(0, 0);
this.$interval = 1000 / 30;
this.$size = 20;
{
var tmp$4;
var tmp$3;
var tmp$2;
var tmp$1;
var tmp$0_0;
$(this.get_canvas()).mousedown((tmp$0_0 = this , function (it) {
{
var tmp$0;
tmp$0_0.set_valid(false);
tmp$0_0.set_selection(null);
var mousePos = tmp$0_0.mousePos_0(it);
{
tmp$0 = tmp$0_0.get_shapes().iterator();
while (tmp$0.hasNext()) {
var shape = tmp$0.next();
{
if (shape.contains(mousePos)) {
tmp$0_0.set_dragOff(mousePos.minus(shape.get_pos()));
shape.set_selected(true);
tmp$0_0.set_selection(shape);
break;
}
}
}
}
}
}
));
$(this.get_canvas()).mousemove((tmp$1 = this , function (it) {
{
if (tmp$1.get_selection() != null) {
Kotlin.sure(tmp$1.get_selection()).set_pos(tmp$1.mousePos_0(it).minus(tmp$1.get_dragOff()));
tmp$1.set_valid(false);
}
}
}
));
$(this.get_canvas()).mouseup((tmp$2 = this , function (it) {
{
if (tmp$2.get_selection() != null) {
Kotlin.sure(tmp$2.get_selection()).set_selected(false);
}
tmp$2.set_selection(null);
tmp$2.set_valid(false);
}
}
));
$(this.get_canvas()).dblclick((tmp$3 = this , function (it) {
{
var redTransparentCircle = new interactive.Circle_0(tmp$3.mousePos_0(it), tmp$3.get_size(), 'rgba(200, 100, 100, 0.3)');
tmp$3.addShape(redTransparentCircle);
tmp$3.set_valid(false);
}
}
));
interactive.doWithPeriod(this.get_interval(), (tmp$4 = this , function () {
{
tmp$4.draw();
}
}
));
}
}, get_canvas:function () {
return this.$canvas;
}, get_width:function () {
return this.$width;
}, get_height:function () {
return this.$height;
}, get_context:function () {
return this.$context;
}, get_valid:function () {
return this.$valid;
}, set_valid:function (tmp$0) {
this.$valid = tmp$0;
}, get_shapes:function () {
return this.$shapes;
}, set_shapes:function (tmp$0) {
this.$shapes = tmp$0;
}, get_selection:function () {
return this.$selection;
}, set_selection:function (tmp$0) {
this.$selection = tmp$0;
}, get_dragOff:function () {
return this.$dragOff;
}, set_dragOff:function (tmp$0) {
this.$dragOff = tmp$0;
}, get_interval:function () {
return this.$interval;
}, get_size:function () {
return this.$size;
}, mousePos_0:function (e) {
{
var offset = new interactive.Vector_0(0, 0);
var element = this.get_canvas();
while (element != null) {
var el = Kotlin.sure(element);
offset = offset.plus(new interactive.Vector_0(el.offsetLeft, el.offsetTop));
element = el.offsetParent;
}
return (new interactive.Vector_0(e.pageX, e.pageY)).minus(offset);
}
}, addShape:function (shape) {
{
this.get_shapes().add(shape);
this.set_valid(false);
}
}, clear:function () {
{
this.get_context().fillStyle = '#FFFFFF';
this.get_context().fillRect(0, 0, this.get_width(), this.get_height());
this.get_context().strokeStyle = '#000000';
this.get_context().lineWidth = 4;
this.get_context().strokeRect(0, 0, this.get_width(), this.get_height());
}
}, draw:function () {
{
var tmp$0;
if (this.get_valid())
return;
this.clear();
{
tmp$0 = this.get_shapes().iterator();
while (tmp$0.hasNext()) {
var shape = tmp$0.next();
{
shape.draw(this);
}
}
}
this.set_valid(true);
}
}
});
var Shape = Kotlin.Class.create({initialize:function () {
this.$selected = false;
}, draw:function (state) {
}, contains:function (mousePos) {
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_selected:function () {
return this.$selected;
}, set_selected:function (tmp$0) {
this.$selected = tmp$0;
}
});
var JB = Kotlin.Class.create(Shape, {initialize:function (pos, relSize) {
this.$pos = pos;
this.$relSize = relSize;
this.super_init();
this.$imageSize = interactive.v_0(704, 254);
this.$canvasSize = this.get_imageSize().times(this.get_relSize());
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_relSize:function () {
return this.$relSize;
}, set_relSize:function (tmp$0) {
this.$relSize = tmp$0;
}, get_imageSize:function () {
return this.$imageSize;
}, get_canvasSize:function () {
return this.$canvasSize;
}, draw:function (state) {
{
var context = state.get_context();
context.drawImage(getKotlinLogo(), 0, 0, this.get_imageSize().get_x(), this.get_imageSize().get_y(), this.get_pos().get_x(), this.get_pos().get_y(), this.get_canvasSize().get_x(), this.get_canvasSize().get_y());
}
}, contains:function (mousePos) {
{
return mousePos.isInRect(this.get_pos(), this.get_canvasSize());
}
}
});
var Rectangle = Kotlin.Class.create(Shape, {initialize:function (pos, size) {
this.$pos = pos;
this.$size = size;
this.super_init();
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_size:function () {
return this.$size;
}, set_size:function (tmp$0) {
this.$size = tmp$0;
}, draw:function (state) {
{
var context = state.get_context();
context.fillStyle = 'rgba(0,255,0,.6)';
context.fillRect(this.get_pos().get_x(), this.get_pos().get_y(), this.get_size().get_x(), this.get_size().get_y());
if (this.get_selected()) {
context.strokeStyle = '#FF0000';
context.lineWidth = 2;
context.strokeRect(this.get_pos().get_x(), this.get_pos().get_y(), this.get_size().get_x(), this.get_size().get_y());
}
}
}, contains:function (mousePos) {
{
return mousePos.isInRect(this.get_pos(), this.get_size());
}
}
});
var Circle = Kotlin.Class.create(Shape, {initialize:function (pos, radius, fillColor) {
this.$pos = pos;
this.$radius = radius;
this.$fillColor = fillColor;
this.super_init();
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_radius:function () {
return this.$radius;
}, set_radius:function (tmp$0) {
this.$radius = tmp$0;
}, get_fillColor:function () {
return this.$fillColor;
}, set_fillColor:function (tmp$0) {
this.$fillColor = tmp$0;
}, draw:function (state) {
{
var context = state.get_context();
context.shadowColor = 'white';
context.shadowBlur = 10;
context.fillStyle = this.get_fillColor();
context.beginPath();
context.arc(this.get_pos().get_x(), this.get_pos().get_y(), this.get_radius(), 0, 2 * Math.PI, false);
context.closePath();
context.fill();
}
}, contains:function (mousePos) {
{
return this.get_pos().distanceTo(mousePos) < this.get_radius();
}
}
});
return {Shape_0:Shape, JB_0:JB, Rectangle_0:Rectangle, Circle_0:Circle, CanvasState_0:CanvasState, Vector_0:Vector};
}
();
var interactive = Kotlin.Namespace.create({initialize:function () {
interactive.$state = new interactive.CanvasState_0(getCanvas());
}, get_state:function () {
return interactive.$state;
}, doWithPeriod:function (period, f) {
{
setInterval(f, period);
}
}, v_0:function (x, y) {
{
return new interactive.Vector_0(x, y);
}
}, main:function () {
{
var state = new interactive.CanvasState_0(getCanvas());
state.addShape(new interactive.JB_0(interactive.v_0(1, 1), 0.3));
setTimeout(function () {
{
state.set_valid(false);
}
}
);
}
}
}, classes);
interactive.initialize();
}
var args = [];
interactive.main(args);
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

@@ -0,0 +1,183 @@
package interactive;
import jquery.*;
import html5.*;
import java.util.ArrayList;
import js.*;
import js.Math;
import js.setInterval
import html5.getCanvas
import html5.getKotlinLogo
import jquery.jq
import js.setTimeout
val state = CanvasState(getCanvas());
fun doWithPeriod(period : Int, f : ()->Unit) {
setInterval(f, period);
}
abstract class Shape() {
abstract fun draw(state : CanvasState);
abstract fun contains(mousePos : Vector) : Boolean;
abstract var pos : Vector;
var selected : Boolean = false;
}
class Circle(override var pos : Vector,
var radius : Double = 1.0,
var fillColor : String = "#AAAAAA") : Shape() {
override fun draw(state : CanvasState) {
val context = state.context;
context.shadowColor = "white";
context.shadowBlur = 10.0;
context.fillStyle = fillColor;
context.beginPath();
context.arc(pos.x, pos.y, radius, 0.0, 2 * Math.PI, false);
context.closePath();
context.fill();
}
override fun contains(mousePos : Vector) = pos.distanceTo(mousePos) < radius;
}
class Rectangle(override var pos : Vector,
var size : Vector) : Shape()
{
override fun draw(state : CanvasState) {
val context = state.context;
context.fillStyle = "rgba(0,255,0,.6)";
context.fillRect(pos.x, pos.y, size.x, size.y);
if (selected) {
context.strokeStyle = "#FF0000"
context.lineWidth = 2.0;
context.strokeRect(pos.x, pos.y, size.x, size.y)
}
}
override fun contains(mousePos : Vector) = mousePos.isInRect(pos, size);
}
class JB(override var pos : Vector,
var relSize : Double = 0.3) : Shape()
{
val imageSize = v(704.0, 254.0)
val canvasSize = imageSize * relSize
override fun draw(state : CanvasState) {
val context = state.context;
context.drawImage(getKotlinLogo(), 0.0, 0.0, imageSize.x, imageSize.y, pos.x, pos.y, canvasSize.x, canvasSize.y)
}
override fun contains(mousePos: Vector): Boolean = mousePos.isInRect(pos, canvasSize)
}
class CanvasState(val canvas : Canvas) {
val width = canvas.width;
val height = canvas.height;
val context = getContext();
var valid = false;
var shapes = ArrayList<Shape>();
var selection : Shape? = null;
var dragOff = Vector();
val interval = 1000 / 30;
val size = 20.0;
{
jq(canvas).mousedown {
valid = false;
selection = null;
val mousePos = mousePos(it);
for (shape in shapes) {
if (mousePos in shape) {
dragOff = mousePos - shape.pos;
shape.selected = true;
selection = shape;
break;
}
}
}
jq(canvas).mousemove {
if (selection != null) {
selection.sure().pos = mousePos(it) - dragOff;
valid = false;
}
}
jq(canvas).mouseup {
if (selection != null) {
selection.sure().selected = false;
}
selection = null;
valid = false;
}
jq(canvas).dblclick {
val redTransparentCircle = Circle(mousePos(it), size, "rgba(200, 100, 100, 0.3)");
addShape(redTransparentCircle);
valid = false;
}
doWithPeriod(interval) {
draw();
}
}
fun mousePos(e : MouseEvent) : Vector {
var offset = Vector();
var element : DomElement? = canvas;
while (element != null) {
val el : DomElement = element.sure();
offset += Vector(el.offsetLeft, el.offsetTop);
element = el.offsetParent;
}
return Vector(e.pageX, e.pageY) - offset;
}
fun addShape(shape : Shape) {
shapes.add(shape);
valid = false;
}
fun clear() {
context.fillStyle = "#FFFFFF"
context.fillRect(0.0, 0.0, width, height)
context.strokeStyle = "#000000"
context.lineWidth = 4.0;
context.strokeRect(0.0, 0.0, width, height)
}
fun draw() {
if (valid) return
clear();
for (shape in shapes) {
shape.draw(this);
}
valid = true;
}
}
fun v(x : Double, y : Double) = Vector(x, y);
class Vector(var x : Double = 0.0, var y : Double = 0.0) {
fun plus(v : Vector) = v(x + v.x, y + v.y);
fun minus(v : Vector) = v(x - v.x, y - v.y);
fun times(coef : Double) = v(x * coef, y * coef);
fun distanceTo(v : Vector) = Math.sqrt((this - v).sqr);
fun isInRect(topLeft : Vector, size : Vector) = (x >= topLeft.x) && (x <= topLeft.x + size.x) &&
(y >= topLeft.y) && (y <= topLeft.y + size.y)
val sqr : Double
get() = x * x + y * y;
}
fun main() {
val state = CanvasState(getCanvas());
state.addShape(JB(v(1.0, 1.0)));
setTimeout({
state.valid = false
})
}
@@ -0,0 +1,31 @@
<!--
~ Copyright 2000-2012 JetBrains s.r.o.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Canvas demo</title>
</head>
<body>
<canvas height="450" width="800"></canvas>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="../../../../translator/testFiles/kotlin_lib.js" type="text/javascript"></script>
<script src="../../../../translator/testFiles/canvas_helper.js" type="text/javascript"></script>
<script src="interactive.js" type="text/javascript"></script>
<img src="jbLogo.png" hidden=true/>
</body>
</html>
@@ -0,0 +1,30 @@
<!--
~ Copyright 2000-2012 JetBrains s.r.o.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Canvas demo</title>
</head>
<body>
<canvas height="450" width="800"></canvas>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="../../kotlin_lib.js" type="text/javascript"></script>
<script src="../../canvas_helper.js" type="text/javascript"></script>
<script src="tutorial.js" type="text/javascript"></script>
</body>
</html>
@@ -0,0 +1,238 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// By Simon Sarris
// www.simonsarris.com
// sarris@acm.org
//
// Last update December 2011
//
// Free to use and distribute at will
// So long as you are nice to people, etc
// Constructor for Shape objects to hold data for all drawn objects.
// For now they will just be defined as rectangles.
function Shape(x, y, w, h, fill) {
// This is a very simple and unsafe constructor. All we're doing is checking if the values exist.
// "x || 0" just means "if there is a value for x, use that. Otherwise use 0."
// But we aren't checking anything else! We could put "Lalala" for the value of x
this.x = x || 0;
this.y = y || 0;
this.w = w || 1;
this.h = h || 1;
this.fill = fill || '#AAAAAA';
}
// Draws this shape to a given context
Shape.prototype.draw = function (ctx) {
ctx.fillStyle = this.fill;
ctx.fillRect(this.x, this.y, this.w, this.h);
}
// Determine if a point is inside the shape's bounds
Shape.prototype.contains = function (mx, my) {
// All we have to do is make sure the Mouse X,Y fall in the area between
// the shape's X and (X + Height) and its Y and (Y + Height)
return (this.x <= mx) && (this.x + this.w >= mx) &&
(this.y <= my) && (this.y + this.h >= my);
}
function CanvasState(canvas) {
// **** First some setup! ****
this.canvas = canvas;
this.width = canvas.width;
this.height = canvas.height;
this.ctx = canvas.getContext('2d');
// This complicates things a little but but fixes mouse co-ordinate problems
// when there's a border or padding. See getMouse for more detail
// if (document.defaultView && document.defaultView.getComputedStyle) {
// this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
// this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
// this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
// this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
// }
// Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
// They will mess up mouse coordinates and this fixes that
var html = document.body.parentNode;
this.htmlTop = html.offsetTop;
this.htmlLeft = html.offsetLeft;
// **** Keep track of state! ****
this.valid = false; // when set to false, the canvas will redraw everything
this.shapes = []; // the collection of things to be drawn
this.dragging = false; // Keep track of when we are dragging
// the current selected object. In the future we could turn this into an array for multiple selection
this.selection = null;
this.dragoffx = 0; // See mousedown and mousemove events for explanation
this.dragoffy = 0;
// **** Then events! ****
// This is an example of a closure!
// Right here "this" means the CanvasState. But we are making events on the Canvas itself,
// and when the events are fired on the canvas the variable "this" is going to mean the canvas!
// Since we still want to use this particular CanvasState in the events we have to save a reference to it.
// This is our reference!
var myState = this;
//fixes a problem where double clicking causes text to get selected on the canvas
canvas.addEventListener('selectstart', function (e) {
e.preventDefault();
return false;
}, false);
// Up, down, and move are for dragging
canvas.addEventListener('mousedown', function (e) {
var mouse = myState.getMouse(e);
var mx = mouse.x;
var my = mouse.y;
var shapes = myState.shapes;
var l = shapes.length;
for (var i = l - 1; i >= 0; i--) {
if (shapes[i].contains(mx, my)) {
var mySel = shapes[i];
// Keep track of where in the object we clicked
// so we can move it smoothly (see mousemove)
myState.dragoffx = mx - mySel.x;
myState.dragoffy = my - mySel.y;
myState.dragging = true;
myState.selection = mySel;
myState.valid = false;
return;
}
}
// havent returned means we have failed to select anything.
// If there was an object selected, we deselect it
if (myState.selection) {
myState.selection = null;
myState.valid = false; // Need to clear the old selection border
}
}, true);
canvas.addEventListener('mousemove', function (e) {
if (myState.dragging) {
var mouse = myState.getMouse(e);
// We don't want to drag the object by its top-left corner, we want to drag it
// from where we clicked. Thats why we saved the offset and use it here
myState.selection.x = mouse.x - myState.dragoffx;
myState.selection.y = mouse.y - myState.dragoffy;
myState.valid = false; // Something's dragging so we must redraw
}
}, true);
canvas.addEventListener('mouseup', function (e) {
myState.dragging = false;
}, true);
// double click for making new shapes
canvas.addEventListener('dblclick', function (e) {
var mouse = myState.getMouse(e);
myState.addShape(new Shape(mouse.x - 10, mouse.y - 10, 20, 20, 'rgba(0,255,0,.6)'));
}, true);
// **** Options! ****
this.selectionColor = '#CC0000';
this.selectionWidth = 2;
this.interval = 30;
setInterval(function () {
myState.draw();
}, myState.interval);
}
CanvasState.prototype.addShape = function (shape) {
this.shapes.push(shape);
this.valid = false;
}
CanvasState.prototype.clear = function () {
this.ctx.clearRect(0, 0, this.width, this.height);
}
// While draw is called as often as the INTERVAL variable demands,
// It only ever does something if the canvas gets invalidated by our code
CanvasState.prototype.draw = function () {
// if our state is invalid, redraw and validate!
if (!this.valid) {
var ctx = this.ctx;
var shapes = this.shapes;
this.clear();
// ** Add stuff you want drawn in the background all the time here **
// draw all shapes
var l = shapes.length;
for (var i = 0; i < l; i++) {
var shape = shapes[i];
// We can skip the drawing of elements that have moved off the screen:
if (shape.x > this.width || shape.y > this.height ||
shape.x + shape.w < 0 || shape.y + shape.h < 0) continue;
shapes[i].draw(ctx);
}
// draw selection
// right now this is just a stroke along the edge of the selected Shape
if (this.selection != null) {
ctx.strokeStyle = this.selectionColor;
ctx.lineWidth = this.selectionWidth;
var mySel = this.selection;
ctx.strokeRect(mySel.x, mySel.y, mySel.w, mySel.h);
}
// ** Add stuff you want drawn on top all the time here **
this.valid = true;
}
}
// Creates an object with x and y defined, set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky, we have to worry about padding and borders
CanvasState.prototype.getMouse = function (e) {
var element = this.canvas, offsetX = 0, offsetY = 0, mx, my;
// Compute the total offset
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// Add padding and border style widths to offset
// Also add the <html> offsets in case there's a position:fixed bar
// offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
// offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
// We return a simple javascript object (a hash) with x and y defined
return {x:mx, y:my};
}
// If you dont want to use <body onLoad='init()'>
// You could uncomment this init() reference and place the script reference inside the body tag
init();
function init() {
var s = new CanvasState(getCanvas());
s.addShape(new Shape(40, 40, 50, 50)); // The default is gray
s.addShape(new Shape(60, 140, 40, 60, 'lightskyblue'));
// Lets make some partially transparent
s.addShape(new Shape(80, 150, 60, 30, 'rgba(127, 255, 212, .5)'));
s.addShape(new Shape(125, 80, 30, 80, 'rgba(245, 222, 179, .7)'));
}
// Now go make something amazing!
@@ -0,0 +1,475 @@
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
var classes = function () {
var Vector = Kotlin.Class.create({initialize:function (x, y) {
this.$x = x;
this.$y = y;
}, get_x:function () {
return this.$x;
}, get_y:function () {
return this.$y;
}, plus:function (v) {
{
return interactive2.v_0(this.get_x() + v.get_x(), this.get_y() + v.get_y());
}
}, minus:function () {
{
return interactive2.v_0(-this.get_x(), -this.get_y());
}
}, minus$0:function (v) {
{
return interactive2.v_0(this.get_x() - v.get_x(), this.get_y() - v.get_y());
}
}, times:function (coef) {
{
return interactive2.v_0(this.get_x() * coef, this.get_y() * coef);
}
}, distanceTo:function (v) {
{
return Math.sqrt(this.minus$0(v).get_sqr());
}
}, rotatedBy:function (theta) {
{
var sin = Math.sin(theta);
var cos = Math.cos(theta);
return interactive2.v_0(this.get_x() * cos - this.get_y() * sin, this.get_x() * sin + this.get_y() * cos);
}
}, isInRect:function (topLeft, size) {
{
return this.get_x() >= topLeft.get_x() && this.get_x() <= topLeft.get_x() + size.get_x() && this.get_y() >= topLeft.get_y() && this.get_y() <= topLeft.get_y() + size.get_y();
}
}, get_sqr:function () {
{
return this.get_x() * this.get_x() + this.get_y() * this.get_y();
}
}, get_normalized:function () {
{
return this.times(1 / Math.sqrt(this.get_sqr()));
}
}
});
var RadialGradientGenerator = Kotlin.Class.create({initialize:function (context) {
this.$context = context;
this.$gradients = new Kotlin.ArrayList;
this.$current = 0;
{
this.newColorStops([
[0, '#F59898'],
[0.5, '#F57373'],
[1, '#DB6B6B']
]);
this.newColorStops([
[0.39, 'rgb(140,167,209)'],
[0.7, 'rgb(104,139,209)'],
[0.85, 'rgb(67,122,217)']
]);
this.newColorStops([
[0, 'rgb(255,222,255)'],
[0.5, 'rgb(255,185,222)'],
[1, 'rgb(230,154,185)']
]);
this.newColorStops([
[0, 'rgb(255,209,114)'],
[0.5, 'rgb(255,174,81)'],
[1, 'rgb(241,145,54)']
]);
this.newColorStops([
[0, 'rgb(132,240,135)'],
[0.5, 'rgb(91,240,96)'],
[1, 'rgb(27,245,41)']
]);
this.newColorStops([
[0, 'rgb(250,147,250)'],
[0.5, 'rgb(255,80,255)'],
[1, 'rgb(250,0,217)']
]);
}
}, get_context:function () {
return this.$context;
}, get_gradients:function () {
return this.$gradients;
}, get_current:function () {
return this.$current;
}, set_current:function (tmp$0) {
this.$current = tmp$0;
}, newColorStops:function (colorStops) {
{
this.get_gradients().add(colorStops);
}
}, getNext:function () {
{
var result = this.get_gradients().get(this.get_current());
this.set_current((this.get_current() + 1) % this.get_gradients().size());
return result;
}
}
});
var CanvasState = Kotlin.Class.create({initialize:function (canvas) {
this.$canvas = canvas;
this.$width = this.get_canvas().width;
this.$height = this.get_canvas().height;
this.$context = getContext();
this.$valid = false;
this.$shapes = new Kotlin.ArrayList;
this.$selection = null;
this.$dragOff = new interactive2.Vector_0(0, 0);
this.$interval = 1000 / 30;
{
var tmp$4;
var tmp$3;
var tmp$2;
var tmp$1;
var tmp$0_0;
$(this.get_canvas()).mousedown((tmp$0_0 = this , function (it) {
{
var tmp$0;
tmp$0_0.set_valid(false);
tmp$0_0.set_selection(null);
var mousePos = tmp$0_0.mousePos_0(it);
{
tmp$0 = tmp$0_0.get_shapes().iterator();
while (tmp$0.hasNext()) {
var shape = tmp$0.next();
{
if (shape.contains(mousePos)) {
tmp$0_0.set_dragOff(mousePos.minus$0(shape.get_pos()));
shape.set_selected(true);
tmp$0_0.set_selection(shape);
break;
}
}
}
}
}
}
));
$(this.get_canvas()).mousemove((tmp$1 = this , function (it) {
{
if (tmp$1.get_selection() != null) {
Kotlin.sure(tmp$1.get_selection()).set_pos(tmp$1.mousePos_0(it).minus$0(tmp$1.get_dragOff()));
tmp$1.set_valid(false);
}
}
}
));
$(this.get_canvas()).mouseup((tmp$2 = this , function (it) {
{
if (tmp$2.get_selection() != null) {
Kotlin.sure(tmp$2.get_selection()).set_selected(false);
}
tmp$2.set_selection(null);
tmp$2.set_valid(false);
}
}
));
$(this.get_canvas()).dblclick((tmp$3 = this , function (it) {
{
var redTransparentCircle = new interactive2.Creature_0(tmp$3.mousePos_0(it), tmp$3);
tmp$3.addShape(redTransparentCircle);
tmp$3.set_valid(false);
}
}
));
interactive2.doWithPeriod(this.get_interval(), (tmp$4 = this , function () {
{
tmp$4.draw();
}
}
));
}
}, get_canvas:function () {
return this.$canvas;
}, get_width:function () {
return this.$width;
}, get_height:function () {
return this.$height;
}, get_context:function () {
return this.$context;
}, get_valid:function () {
return this.$valid;
}, set_valid:function (tmp$0) {
this.$valid = tmp$0;
}, get_shapes:function () {
return this.$shapes;
}, set_shapes:function (tmp$0) {
this.$shapes = tmp$0;
}, get_selection:function () {
return this.$selection;
}, set_selection:function (tmp$0) {
this.$selection = tmp$0;
}, get_dragOff:function () {
return this.$dragOff;
}, set_dragOff:function (tmp$0) {
this.$dragOff = tmp$0;
}, get_interval:function () {
return this.$interval;
}, mousePos_0:function (e) {
{
var offset = new interactive2.Vector_0(0, 0);
var element = this.get_canvas();
while (element != null) {
var el = Kotlin.sure(element);
offset = offset.plus(new interactive2.Vector_0(el.offsetLeft, el.offsetTop));
element = el.offsetParent;
}
return (new interactive2.Vector_0(e.pageX, e.pageY)).minus$0(offset);
}
}, addShape:function (shape) {
{
this.get_shapes().add(shape);
this.set_valid(false);
}
}, clear:function () {
{
this.get_context().fillStyle = '#FFFFFF';
this.get_context().fillRect(0, 0, this.get_width(), this.get_height());
this.get_context().strokeStyle = '#000000';
this.get_context().lineWidth = 4;
this.get_context().strokeRect(0, 0, this.get_width(), this.get_height());
}
}, draw:function () {
{
var tmp$0;
if (this.get_valid())
return;
this.clear();
{
tmp$0 = this.get_shapes().iterator();
while (tmp$0.hasNext()) {
var shape = tmp$0.next();
{
shape.draw(this);
}
}
}
this.set_valid(true);
}
}
});
var Shape = Kotlin.Class.create({initialize:function () {
this.$selected = false;
}, draw:function (state) {
}, contains:function (mousePos) {
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_selected:function () {
return this.$selected;
}, set_selected:function (tmp$0) {
this.$selected = tmp$0;
}
});
var Creature = Kotlin.Class.create(Shape, {initialize:function (pos, state) {
this.$pos = pos;
this.$state = state;
this.super_init();
this.$shadowOffset = interactive2.v_0(-5, 5);
this.$colorStops = interactive2.get_gradientGenerator().getNext();
this.$relSize = 0.05;
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_state:function () {
return this.$state;
}, set_state:function (tmp$0) {
this.$state = tmp$0;
}, get_shadowOffset:function () {
return this.$shadowOffset;
}, get_colorStops:function () {
return this.$colorStops;
}, get_relSize:function () {
return this.$relSize;
}, get_radius:function () {
{
return this.get_state().get_width() * this.get_relSize();
}
}, get_position:function () {
var tmp$0;
if (this.get_selected())
tmp$0 = this.get_pos().minus$0(this.get_shadowOffset());
else
tmp$0 = this.get_pos();
{
return tmp$0;
}
}, get_directionToLogo:function () {
{
return interactive2.get_JB().get_centre().minus$0(this.get_position()).get_normalized();
}
}, contains:function (mousePos) {
{
return this.get_pos().distanceTo(mousePos) < this.get_radius();
}
}, fillCircle:function (receiver, position, rad) {
{
receiver.beginPath();
receiver.arc(position.get_x(), position.get_y(), rad, 0, 2 * Math.PI, false);
receiver.closePath();
receiver.fill();
}
}, draw:function (state) {
{
var context = state.get_context();
if (!this.get_selected()) {
this.drawCreature(context);
}
else {
this.drawCreatureWithShadow(context);
}
}
}, drawCreature:function (context) {
{
context.fillStyle = this.getGradient(context);
this.fillCircle(context, this.get_position(), this.get_radius());
this.drawEye(context);
this.drawTail(context);
}
}, getGradient:function (context) {
{
var tmp$0;
var gradientCentre = this.get_position().plus(this.get_directionToLogo().times(this.get_radius() / 4));
var gradient = context.createRadialGradient(gradientCentre.get_x(), gradientCentre.get_y(), 1, gradientCentre.get_x(), gradientCentre.get_y(), 2 * this.get_radius());
{
tmp$0 = Kotlin.arrayIterator(this.get_colorStops());
while (tmp$0.hasNext()) {
var colorStop = tmp$0.next();
{
gradient.addColorStop(colorStop[0], colorStop[1]);
}
}
}
return gradient;
}
}, drawTail:function (context) {
{
var tailDirection = this.get_directionToLogo().minus();
var tailPos = this.get_position().plus(tailDirection.times(this.get_radius()).times(0.7));
var tailSize = this.get_radius() * 1.6;
var angle = Math.PI / 6;
var p1 = tailPos.plus(tailDirection.rotatedBy(angle).times(tailSize));
var p2 = tailPos.plus(tailDirection.rotatedBy(-angle).times(tailSize));
context.fillStyle = this.getGradient(context);
context.beginPath();
context.moveTo(tailPos.get_x(), tailPos.get_y());
context.lineTo(p1.get_x(), p1.get_y());
var middlePoint = this.get_position().plus(tailDirection.times(this.get_radius()).times(1));
context.quadraticCurveTo(middlePoint.get_x(), middlePoint.get_y(), p2.get_x(), p2.get_y());
context.lineTo(tailPos.get_x(), tailPos.get_y());
context.closePath();
context.fill();
}
}, drawEye:function (context) {
{
var eyePos = this.get_directionToLogo().times(this.get_radius()).times(0.6).plus(this.get_position());
var eyeRadius = this.get_radius() / 3;
var eyeLidRadius = eyeRadius / 2;
context.fillStyle = '#FFFFFF';
this.fillCircle(context, eyePos, eyeRadius);
context.fillStyle = '#000000';
this.fillCircle(context, eyePos, eyeLidRadius);
}
}, drawCreatureWithShadow:function (context) {
{
context.save();
this.setShadow(context);
context.fillStyle = this.getGradient(context);
this.fillCircle(context, this.get_position(), this.get_radius());
context.restore();
this.drawEye(context);
this.drawTail(context);
}
}, setShadow:function (context) {
{
context.shadowColor = 'rgba(100, 100, 100, 0.7)';
context.shadowBlur = 5;
context.shadowOffsetX = this.get_shadowOffset().get_x();
context.shadowOffsetY = this.get_shadowOffset().get_y();
}
}
});
var Logo = Kotlin.Class.create(Shape, {initialize:function (pos, relSize) {
this.$pos = pos;
this.$relSize = relSize;
this.super_init();
this.$imageSize = interactive2.v_0(704, 254);
this.$canvasSize = this.get_imageSize().times(this.get_relSize());
}, get_pos:function () {
return this.$pos;
}, set_pos:function (tmp$0) {
this.$pos = tmp$0;
}, get_relSize:function () {
return this.$relSize;
}, set_relSize:function (tmp$0) {
this.$relSize = tmp$0;
}, get_imageSize:function () {
return this.$imageSize;
}, get_canvasSize:function () {
return this.$canvasSize;
}, draw:function (state) {
{
var context = state.get_context();
context.drawImage(getKotlinLogo(), 0, 0, this.get_imageSize().get_x(), this.get_imageSize().get_y(), this.get_pos().get_x(), this.get_pos().get_y(), this.get_canvasSize().get_x(), this.get_canvasSize().get_y());
}
}, contains:function (mousePos) {
{
return mousePos.isInRect(this.get_pos(), this.get_canvasSize());
}
}, get_centre:function () {
{
return this.get_pos().plus(this.get_canvasSize().times(0.5));
}
}
});
return {Shape_0:Shape, Logo_0:Logo, Creature_0:Creature, RadialGradientGenerator_0:RadialGradientGenerator, CanvasState_0:CanvasState, Vector_0:Vector};
}
();
var interactive2 = Kotlin.Namespace.create({initialize:function () {
interactive2.$gradientGenerator = new interactive2.RadialGradientGenerator_0(getContext());
interactive2.$JB = new interactive2.Logo_0(interactive2.v_0(20, 20), 0.3);
}, get_gradientGenerator:function () {
return interactive2.$gradientGenerator;
}, get_JB:function () {
return interactive2.$JB;
}, doWithPeriod:function (period, f) {
{
setInterval(f, period);
}
}, v_0:function (x, y) {
{
return new interactive2.Vector_0(x, y);
}
}, main:function () {
{
var state = new interactive2.CanvasState_0(getCanvas());
state.addShape(interactive2.get_JB());
setTimeout(function () {
{
state.set_valid(false);
}
}
);
}
}
}, classes);
interactive2.initialize();
}
var args = [];
interactive2.main(args);
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

@@ -0,0 +1,280 @@
package interactive2;
import jquery.*;
import html5.*;
import java.util.ArrayList;
import js.*;
import js.Math;
import js.setInterval
import html5.getCanvas
import html5.getKotlinLogo
import jquery.jq
import js.setTimeout
val gradientGenerator = RadialGradientGenerator(getContext())
val JB = Logo(v(20.0, 20.0))
fun doWithPeriod(period : Int, f : ()->Unit) {
setInterval(f, period);
}
abstract class Shape() {
abstract fun draw(state : CanvasState);
abstract fun contains(mousePos : Vector) : Boolean;
abstract var pos : Vector;
var selected : Boolean = false;
}
class Logo(override var pos : Vector,
var relSize : Double = 0.3)
: Shape()
{
val imageSize = v(704.0, 254.0)
val canvasSize = imageSize * relSize
override fun draw(state : CanvasState) {
val context = state.context;
context.drawImage(getKotlinLogo(), 0.0, 0.0, imageSize.x, imageSize.y, pos.x, pos.y, canvasSize.x, canvasSize.y)
}
override fun contains(mousePos: Vector): Boolean = mousePos.isInRect(pos, canvasSize)
val centre : Vector
get() = pos + canvasSize * 0.5
}
class Creature(override var pos : Vector,
var state : CanvasState) : Shape() {
val shadowOffset = v(-5.0, 5.0)
val colorStops = gradientGenerator.getNext()
val relSize = 0.05;
val radius : Double
get() = state.width * relSize;
val position : Vector
get() = if (selected) pos - shadowOffset else pos
val directionToLogo : Vector
get() = (JB.centre - position).normalized
override fun contains(mousePos : Vector) = pos.distanceTo(mousePos) < radius;
fun Context.fillCircle(position : Vector, rad : Double) {
beginPath();
arc(position.x, position.y, rad, 0.0, 2 * Math.PI, false);
closePath();
fill()
}
override fun draw(state : CanvasState) {
val context = state.context;
if (!selected) {
drawCreature(context)
} else {
drawCreatureWithShadow(context)
}
}
fun drawCreature(context : Context) {
context.fillStyle = getGradient(context);
context.fillCircle(position, radius)
drawEye(context)
drawTail(context)
}
fun getGradient(context : Context) : CanvasGradient {
val gradientCentre = position + directionToLogo * (radius / 4)
val gradient = context.createRadialGradient(gradientCentre.x, gradientCentre.y, 1.0, gradientCentre.x, gradientCentre.y, 2 * radius)
for (colorStop in colorStops) {
gradient.addColorStop(colorStop._1, colorStop._2)
}
return gradient;
}
fun drawTail(context : Context) {
val tailDirection = -directionToLogo;
val tailPos = position + tailDirection * radius * 0.7
val tailSize = radius * 1.6
val angle = Math.PI / 6.0;
val p1 = tailPos + tailDirection.rotatedBy(angle) * tailSize
val p2 = tailPos + tailDirection.rotatedBy(-angle) * tailSize
context.fillStyle = getGradient(context)
context.beginPath()
context.moveTo(tailPos.x, tailPos.y)
context.lineTo(p1.x, p1.y)
val middlePoint = position + tailDirection * radius * 1.0
context.quadraticCurveTo(middlePoint.x, middlePoint.y, p2.x, p2.y)
context.lineTo(tailPos.x, tailPos.y)
context.closePath()
context.fill()
}
fun drawEye(context : Context) {;
val eyePos = directionToLogo * radius * 0.6 + position;
val eyeRadius = radius / 3;
val eyeLidRadius = eyeRadius / 2;
context.fillStyle = "#FFFFFF";
context.fillCircle(eyePos, eyeRadius)
context.fillStyle = "#000000"
context.fillCircle(eyePos, eyeLidRadius)
}
fun drawCreatureWithShadow(context : Context) {
context.save()
setShadow(context)
context.fillStyle = getGradient(context)
context.fillCircle(position, radius)
context.restore();
drawEye(context)
drawTail(context)
}
fun setShadow(context : Context) {
context.shadowColor = "rgba(100, 100, 100, 0.7)";
context.shadowBlur = 5.0;
context.shadowOffsetX = shadowOffset.x;
context.shadowOffsetY = shadowOffset.y;
}
}
class CanvasState(val canvas : Canvas) {
val width = canvas.width;
val height = canvas.height;
val context = getContext();
var valid = false;
var shapes = ArrayList<Shape>();
var selection : Shape? = null;
var dragOff = Vector();
val interval = 1000 / 30;
{
jq(canvas).mousedown {
valid = false;
selection = null;
val mousePos = mousePos(it);
for (shape in shapes) {
if (mousePos in shape) {
dragOff = mousePos - shape.pos;
shape.selected = true;
selection = shape;
break;
}
}
}
jq(canvas).mousemove {
if (selection != null) {
selection.sure().pos = mousePos(it) - dragOff;
valid = false;
}
}
jq(canvas).mouseup {
if (selection != null) {
selection.sure().selected = false;
}
selection = null;
valid = false;
}
jq(canvas).dblclick {
val redTransparentCircle = Creature(mousePos(it), this @CanvasState);
addShape(redTransparentCircle);
valid = false;
}
doWithPeriod(interval) {
draw();
}
}
fun mousePos(e : MouseEvent) : Vector {
var offset = Vector();
var element : DomElement? = canvas;
while (element != null) {
val el : DomElement = element.sure();
offset += Vector(el.offsetLeft, el.offsetTop);
element = el.offsetParent;
}
return Vector(e.pageX, e.pageY) - offset;
}
fun addShape(shape : Shape) {
shapes.add(shape);
valid = false;
}
fun clear() {
context.fillStyle = "#FFFFFF"
context.fillRect(0.0, 0.0, width, height)
context.strokeStyle = "#000000"
context.lineWidth = 4.0;
context.strokeRect(0.0, 0.0, width, height)
}
fun draw() {
if (valid) return
clear();
for (shape in shapes) {
shape.draw(this);
}
valid = true;
}
}
class RadialGradientGenerator(val context : Context) {
val gradients = ArrayList<Array<#(Double, String)>>();
var current = 0
fun newColorStops(vararg colorStops : #(Double, String)) {
gradients.add(colorStops)
}
{
newColorStops(#(0.0, "#F59898"), #(0.5, "#F57373"), #(1.0, "#DB6B6B"))
newColorStops(#(0.39, "rgb(140,167,209)"), #(0.7, "rgb(104,139,209)"), #(0.85, "rgb(67,122,217)"))
newColorStops(#(0.0, "rgb(255,222,255)"), #(0.5, "rgb(255,185,222)"), #(1.0, "rgb(230,154,185)"))
newColorStops(#(0.0, "rgb(255,209,114)"), #(0.5, "rgb(255,174,81)"), #(1.0, "rgb(241,145,54)"))
newColorStops(#(0.0, "rgb(132,240,135)"), #(0.5, "rgb(91,240,96)"), #(1.0, "rgb(27,245,41)"))
newColorStops(#(0.0, "rgb(250,147,250)"), #(0.5, "rgb(255,80,255)"), #(1.0, "rgb(250,0,217)"))
}
fun getNext() : Array<#(Double, String)> {
val result = gradients.get(current)
current = (current + 1) % gradients.size()
return result
}
}
fun v(x : Double, y : Double) = Vector(x, y);
class Vector(val x : Double = 0.0, val y : Double = 0.0) {
fun plus(v : Vector) = v(x + v.x, y + v.y);
fun minus() = v(-x, -y)
fun minus(v : Vector) = v(x - v.x, y - v.y)
fun times(coef : Double) = v(x * coef, y * coef)
fun distanceTo(v : Vector) = Math.sqrt((this - v).sqr)
fun rotatedBy(theta : Double) : Vector {
val sin = Math.sin(theta)
val cos = Math.cos(theta)
return v(x * cos - y * sin, x * sin + y * cos)
}
fun isInRect(topLeft : Vector, size : Vector) = (x >= topLeft.x) && (x <= topLeft.x + size.x) &&
(y >= topLeft.y) && (y <= topLeft.y + size.y)
val sqr : Double
get() = x * x + y * y
val normalized : Vector
get() = this * (1.0 / Math.sqrt(sqr))
}
fun main() {
val state = CanvasState(getCanvas());
state.addShape(JB);
setTimeout({
state.valid = false
})
}
@@ -0,0 +1,31 @@
<!--
~ Copyright 2000-2012 JetBrains s.r.o.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Canvas demo</title>
</head>
<body>
<canvas height="450" width="800"></canvas>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="../../../../translator/testFiles/kotlin_lib.js" type="text/javascript"></script>
<script src="../../../../translator/testFiles/canvas_helper.js" type="text/javascript"></script>
<script src="interactive2.js" type="text/javascript"></script>
<img src="jbLogo.png" hidden=true/>
</body>
</html>