cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

Quick-add: + add another resource

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              
<div class="wrapper">
    <div class="container">
        <div class="content">
            <div><canvas width="200" height="200"></canvas></div>
        </div>
        <div class="menu">
            <span><input type="range" min="0" max="90" step="1" value ="0" autocomplete="off"></span>
        </div>
    </div>
</div>
            
          
!
            
              
 * {
    padding:0;
    margin:0;
    box-sizing:border-box;
    outline:none;
    user-select:none;
    -moz-user-select:none;
    -webkit-user-select:none;
    -ms-user-select:none;
 }
 
div.wrapper {
    width:250px;
    height:auto;
    padding:10px;
    margin:50px 50px 0px;
    background-color:black;
}
div.wrapper > div.container{
    width:100%;
    height:100%;
    display:flex;
    background-color:#111;
}
div.wrapper > div.container > div.content{
    width:100%;
    height:100%;
    display:flex;
}
div.wrapper > div.container > div.content > div > canvas{
    display:block;
    background-color:#111;
}
div.wrapper > div.container > div.menu{
    width:0%;
    height:0px;
    position:relative;
    padding:0px;
    margin:0;
    background-color:#111;
}
div.wrapper > div.container > div.menu > span{
    display:inline-block;
    width:90px;
    height:0px;
    background-color:navy;
    position:absolute;
    transform-origin:0 0;
    transform:translate(0px,0px) rotate(90deg);
}

div.wrapper > div.container > div.menu > span > input[type="range"]{
    -webkit-appearance: none;
    appearance: none;
    height: 3px;
    width:90px;
    border-radius:3px;
    vertical-align:3px;
    box-sizing:border-box;
    outline:none;
    position:relative;
    z-index:2;
    background-color:white;
}
div.wrapper > div.container > div.menu > span > input[type="range"]::-webkit-slider-thumb{
    -webkit-appearance: none;
    appearance: none;
    width:12px;
    height:12px;
    border:solid 2px #fff;
    background-color: #111;
    border-radius:12px;
    box-sizing:border-box;
    position:relative;
    z-index:2;
}
div.wrapper > div.container > div.menu > span > input[type="range"]::-moz-range-thumb{
    width:8px;
    height:8px;
    border:solid 2px #fff;
    background-color: #111;
    border-radius:12px;
    position:relative;
    z-index:2;
}
            
          
!
            
              (function(win,doc){
    win.addEventListener('load',function(){
    var body_d = [
        [{'type':'path','z':true,'mode':'both','x':3.46,'y':16.32},{'x':3.46,'y':16.32},{'x':2.36,'y':20.72},{'x':3.46,'y':27.69},{'x':4.56,'y':34.65},{'x':10.29,'y':41.64},{'x':12.99,'y':56.96},{'x':15.69,'y':72.28},{'x':15.21,'y':72.79},{'x':15.05,'y':81.81},{'x':14.89,'y':90.83},{'x':10.79,'y':99.38},{'x':11.24,'y':102.07},{'x':11.24,'y':102.07},{'x':12.51,'y':104.28},{'x':16.32,'y':105.47},{'x':20.13,'y':106.66},{'x':33.32,'y':110.92},{'x':51.11,'y':108.2},{'x':68.9,'y':105.47},{'x':85.89,'y':99},{'x':91.93,'y':96.28},{'x':97.96,'y':93.56},{'x':101.02,'y':93.92},{'x':102.72,'y':90.13},{'x':104.42,'y':86.34},{'x':96.85,'y':77.9},{'x':97.01,'y':59.86},{'x':97.17,'y':41.81},{'x':103.46,'y':29.22},{'x':101.93,'y':20.54},{'x':100.4,'y':11.85},{'x':95.88,'y':8.86},{'x':95.88,'y':8.86},{'x':95.88,'y':8.86},{'x':70.37,'y':22.49},{'x':45.51,'y':24.83},{'x':20.97,'y':27.15},{'x':3.46,'y':16.32},{'x':3.46,'y':16.32}],
        [{'type':'path','z':true,'mode':'both','x':93.2,'y':4.04},{'x':82.02,'y':0.38},{'x':70.24,'y':0.38},{'x':58.7,'y':0.56},{'x':42.98,'y':1.2},{'x':27.12,'y':2.99},{'x':12.01,'y':8.18},{'x':7.96,'y':9.9},{'x':3.14,'y':11.28},{'x':0.62,'y':15.61},{'x':-0.39,'y':20.29},{'x':5.3,'y':21.66},{'x':8.22,'y':22.72},{'x':20.14,'y':25.77},{'x':32.48,'y':25.49},{'x':44.62,'y':25.13},{'x':60.84,'y':24.22},{'x':77.4,'y':22.81},{'x':92.64,'y':15.93},{'x':95.31,'y':14.43},{'x':100.75,'y':12.38},{'x':99.24,'y':8.01},{'x':97.8,'y':5.83},{'x':95.36,'y':4.93},{'x':93.2,'y':4.04}]
    ];
    var cap_d = [
        [{'type':'path','z':true,'mode':'both','x':59.75,'y':87.3},{'x':67.76,'y':79.33},{'x':72.52,'y':66.54},{'x':72.47,'y':47.88},{'x':72.42,'y':29.22},{'x':58.61,'y':10.34},{'x':41.66,'y':10.45},{'x':24.71,'y':10.56},{'x':11.02,'y':29.61},{'x':11.07,'y':53.04},{'x':11.11,'y':66.63},{'x':15.86,'y':79.36},{'x':23.84,'y':87.3}]
    ];
    var wrapper   = document.querySelector('div.wrapper');
    var container = wrapper.querySelector('div.container');
    var content   = container.querySelector('div.content');
    var menu      = container.querySelector('div.menu');
    var range     = menu.querySelector('input[type="range"]');
    var can       = content.querySelectorAll('div > canvas');
    var ctx       = can[0].getContext('2d');
    var body      = new Toto(
        'node'  ,can[0],
        'conf'  ,{'context':{'fillStyle':'ivory','strokeStyle':'silver','lineWidth':2},'css':{'lineHeight':0}},
        'label' ,'body',
        'd'     , body_d,
        'left'  ,80,
        'top'   ,140,
        'x'     ,-50,
        'y'     ,-50
    );
    var w = 62
    var h = 79;
    var cap      = new Toto(
        'node'  , can[0],
        'conf'  , {'context':{'fillStyle':'ivory','strokeStyle':'silver','lineWidth':2},'css':{'lineHeight':0}},
        'label' , 'cap',
        'd'     ,  cap_d,
        'left'  ,  100,
        'top'   ,  100-14,
        'x'     ,  -w/2+6,
        'y'     ,  -h-10
    );
    var transformList = cap.transformList;
    var c_tra         = transformList.getItem(0);
    var c_mxa         = c_tra.matrix;
    var angle         = 12;
        c_mxa.a      = 1;
        c_mxa.b      = Math.sin(angle*Math.PI/180);
        c_mxa.c      = -Math.sin(angle*Math.PI/180);
        c_mxa.d      = 1;
        c_mxa.e      = 0;
        c_mxa.f      = 0;
    var c_trb     = new Transform();
    var c_mxb         = c_trb.matrix;
        transformList.appendItem(c_trb);
        c_trb.active = true;
        c_trb.angle  = 0;
        c_trb.step   = 0;
        c_trb.range  = 0;
        
        c_trb.a.active = false;
        c_trb.b.active = false;
        c_trb.c.active = true; c_trb.c.angle =  180;  c_trb.c.step =  0;  c_trb.c.range = 116; 
        c_trb.d.active = true; c_trb.d.angle =  270;  c_trb.d.step =  0;  c_trb.d.range = 116; 
        c_trb.e.active = false;
        c_trb.f.active = false;
        
        cap.setTransform();
        body.drawPoints();
        cap.drawPoints();
        
        range.addEventListener('input',function(){
            c_trb.c.angle =  parseInt(this.value) + 180;
            c_trb.d.angle =  parseInt(this.value) + 270;
            cap.clear();
            body.drawPoints();
            cap.drawPoints();
        },false);
        
    },false);
    
    
/* ############################################################### */

function Toto(){
    Array.prototype.push.call(arguments,'transformList',new this.TransformList());
    (function(self,doc){
        Object.defineProperty(self, 'document', {
            get : function() { return doc; },
            enumerable : true
        });
    })(this,new this.Document(arguments))
    
    this.transformList.appendItem(new this.Transform());
}
Toto.prototype = Object.create(Object.prototype,{
    'owner' : {
        set : function(){ this.document.owner = arguments[0]; },
        get : function(){ return this.document.owner; },
        enumerable : true
    },
    'label' : {
        set : function(){ this.document.label = arguments[0]; },
        get : function(){ return this.document.label; },
        enumerable : true
    },
    'conf' : {
        set : function(){ this.document.conf = arguments[0]; },
        get : function(){ return this.document.conf; },
        enumerable : true
    },
    'node' : {
        set : function(){ this.document.node = arguments[0]; },
        get : function(){ return this.document.node; },
        enumerable : true
    },
    'scrollLeft' : {
        set : function(){ this.document.scrollLeft = arguments[0]; },
        get : function(){ return this.document.scrollLeft; },
        enumerable : true
    },
    'scrollTop' : {
        set : function(){ this.document.scrollTop = arguments[0]; },
        get : function(){ return this.document.scrollTop; },
        enumerable : true
    },
    'scrollWidth' : {
        set : function(){ this.document.scrollWidth = arguments[0]; },
        get : function(){ return this.document.scrollWidth; },
        enumerable : true
    },
    'scrollHeight' : {
        set : function(){ this.document.scrollHeight = arguments[0]; },
        get : function(){ return this.document.scrollHeight; },
        enumerable : true
    },
    'clientLeft' : {
        set : function(){ this.document.clientLeft = arguments[0]; },
        get : function(){ return this.document.clientLeft; },
        enumerable : true
    },
    'clientTop' : {
        set : function(){ this.document.clientTop = arguments[0]; },
        get : function(){ return this.document.clientTop; },
        enumerable : true
    },
    'clientWidth' : {
        set : function(){ this.document.clientWidth = arguments[0]; },
        get : function(){ return this.document.clientWidth; },
        enumerable : true
    },
    'clientHeight' : {
        set : function(){ this.document.clientHeight = arguments[0]; },
        get : function(){ return this.document.clientHeight; },
        enumerable : true
    },
    'offsetLeft' : {
        set : function(){ this.document.offsetLeft = arguments[0]; },
        get : function(){ return this.document.offsetLeft; },
        enumerable : true
    },
    'offsetTop' : {
        set : function(){ this.document.offsetTop = arguments[0]; },
        get : function(){ return this.document.offsetTop; },
        enumerable : true
    },
    'offsetWidth' : {
        set : function(){ this.document.offsetWidth = arguments[0]; },
        get : function(){ return this.document.offsetWidth; },
        enumerable : true
    },
    'offsetHeight' : {
        set : function(){ this.document.offsetHeight = arguments[0]; },
        get : function(){ return this.document.offsetHeight; },
        enumerable : true
    },
    'width' : {
        set : function(){ this.document.width = arguments[0]; },
        get : function(){ return this.document.width; },
        enumerable : true
    },
    'height' : {
        set : function(){ this.document.height = arguments[0]; },
        get : function(){ return this.document.height; },
        enumerable : true
    },
    'left' : {
        set : function(){ this.document.left = arguments[0]; },
        get : function(){ return this.document.left; },
        enumerable : true
    },
    'top' : {
        set : function(){ this.document.top = arguments[0]; },
        get : function(){ return this.document.top; },
        enumerable : true
    },
    'x' : {
        set : function(){ this.document.x = arguments[0]; },
        get : function(){ return this.document.x; },
        enumerable : true
    },
    'y' : {
        set : function(){ this.document.y = arguments[0]; },
        get : function(){ return this.document.y; },
        enumerable : true
    },
    'context' : {
        set : function(){ this.document.context = arguments[0]; },
        get : function(){ return this.document.context; },
        enumerable : true
    },
    'd' : {
        set : function(){ this.document.d = arguments[0]; },
        get : function(){ return this.document.d; },
        enumerable : true
    },
    'transformList' : {
        set : function(){ this.document.transformList = arguments[0]; },
        get : function(){ return this.document.transformList; },
        enumerable : true
    },
    'angle' : {
        set : function(){ this.transformList[0].angle = arguments[0]; },
        get : function(){ return this.transformList[0].angle; },
        enumerable : true
    },
    'step' : {
        set : function(){ this.transformList[0].step = arguments[0]; },
        get : function(){ return this.transformList[0].step; },
        enumerable : true
    },
    'clear'         : { value :
        function(){
            this.context.clearRect(0,0,this.node.width,this.node.height);
        }
    },
    'drawTransform' : { value :
        function(ctx){
            ctx  = ctx === undefined ? this.context : ctx;
        var left   = this.left;
        var top    = this.top;
        var points = this.getPoints();
        var transformList = this.transformList;
        var i,j,k;
            for(var n = 0; n < transformList.length; n = n + 1){
            var transform = transformList[n];
            var matrix    = transform.matrix;
                switch(n){
                case 0 :
                    ctx.transform(matrix.a,matrix.b,matrix.c,matrix.d,matrix.e+left,matrix.f+top);
                break;
                default :
                    ctx.transform(matrix.a,matrix.b,matrix.c,matrix.d,matrix.e,matrix.f);
                }
            }
            ctx.fillStyle   = 'blueviolet';
            ctx.strokeStyle = 'gray';
            ctx.globalAlpha = 1;
            ctx.lineWidth   = 2;
            ctx.lineCap     = 'round';
            ctx.lineJoin    = 'round';
            for(i = 0; i < points.length; i = i + 1){
                ctx.beginPath();
                ctx.moveTo(points[i][0].x, points[i][0].y);
                for(j = 1; j < points[i].length; j = j + 3){
                    ctx.bezierCurveTo(points[i][j].x, points[i][j].y, points[i][j+1].x, points[i][j+1].y, points[i][j+2].x, points[i][j+2].y);
                }
                switch(this.d[i][0].z){
                case true  :
                    ctx.closePath();
                break;
                case false :
                break;
                }
                switch(this.d[i][0].mode){
                case 'fill'  :
                    ctx.fill();
                break;
                case 'stroke' :
                    ctx.stroke();
                break;
                case 'both' :
                    ctx.fill();
                    ctx.stroke();
                break;
                }
            }
        }
    },
    'drawPoints'    : { value :
        function(ctx){
            ctx           = ctx === undefined ? this.context : ctx;
        var left          = this.left;
        var top           = this.top ;
        var points        = this.getPoints();
        var transformList = this.transformList;
        var i,j,k;
            this.setTransform();
            for(var n = transformList.length - 1; n > -1; n = n - 1){
            var transform = transformList[n];
            var matrix    = transform.matrix;
            var a  = matrix.a;
            var b  = matrix.b;
            var c  = matrix.c;
            var d  = matrix.d;
            var e  = matrix.e;
            var f  = matrix.f;
                for(i = 0; i < points.length; i = i + 1){
                    for(j = 0; j < points[i].length; j = j + 1){
                    var x  = points[i][j].x;
                    var y  = points[i][j].y;
                    var px = a*x + c*y + e;
                    var py = b*x + d*y + f;
                        points[i][j].x = px ;
                        points[i][j].y = py ;
                    }
                }
            }
            ctx.fillStyle   = this.conf.context.fillStyle;
            ctx.strokeStyle   = this.conf.context.strokeStyle;
            ctx.lineWidth   = this.conf.context.lineWidth;
            ctx.lineCap     = 'round';
            ctx.lineJoin    = 'round';
            for(i = 0; i < points.length; i = i + 1){
                ctx.beginPath();
                ctx.moveTo(points[i][0].x + left, points[i][0].y + top);
                for(j = 1; j < points[i].length; j = j + 3){
                    ctx.bezierCurveTo(
                    points[i][j].x   + left,
                    points[i][j].y   + top,
                    points[i][j+1].x + left,
                    points[i][j+1].y + top,
                    points[i][j+2].x + left,
                    points[i][j+2].y + top
                    );
                }
                switch(this.d[i][0].z){
                case true  :
                    ctx.closePath();
                break;
                case false :
                break;
                }
                switch(this.d[i][0].mode){
                case 'fill'  :
                    ctx.fill();
                break;
                case 'stroke' :
                    ctx.stroke();
                break;
                case 'both' :
                    ctx.fill();
                    ctx.stroke();
                break;
                }
            }
        }
    },
    'getPoints'     : { value :
        function(){
        var x =  this.x;
        var y =  this.y;
        var d = this.d;
        var temp = [];
            for(var i = 0; i < d.length; i = i + 1){
                temp[i] = [];
                for(var j = 0; j < d[i].length; j = j + 1){
                var o = {};
                    o.x = d[i][j].x + x;
                    o.y = d[i][j].y + y;
                    temp[i].push(o);
                }
            }
            return temp;
        }
    },
    'setTransform'  : { value :
        function(){
        var PI            = this.PI;
        var transformList = this.transformList;
            for(var i = 1; i < transformList.length; i = i + 1){
            var transform = this.transformList[i];
            var range     = transform.range;
            var angle     = transform.angle;
            var matrix    = transform.matrix;
                if(transform.active === false){ continue; }
                for(var label in matrix){
                    switch(label){
                    case 'a' :
                    case 'd' :
                        switch(transform[label].active){
                        case true :
                            angle = transform[label].angle = transform[label].angle + transform[label].step;
                            range = transform[label].range;
                        break;
                        case false  :
                            transform.angle = angle + transform.step;
                        break;
                        }
                        switch(range){
                        case 0  :
                            matrix[label] = Math.cos(angle*PI/180);
                        break;
                        default :
                            matrix[label] = Math.cos((Math.cos(angle*PI/180)*range)*PI/180);
                            if(angle%90 === 0){}
                        }
                    break;
                    case 'b' :
                    case 'c' :
                    var n = label == 'b' ?  1 : -1;
                        switch(transform[label].active){
                        case true :
                            angle = transform[label].angle = transform[label].angle + transform[label].step;
                            range = transform[label].range;
                        break;
                        case false  :
                            transform.angle = angle + transform.step;
                        break;
                        }
                        switch(range){
                        case 0  :
                            matrix[label] = Math.sin(angle*PI/180) * n;
                        break;
                        default :
                            matrix[label] = Math.sin((Math.sin(angle*PI/180)*range)*PI/180) * n;
                            if(angle%90 === 0){}
                        }
                    break;
                    case 'e' :
                    break;
                    case 'f' :
                    break;
                    }
                }
            }
        }
    },
    'PI'            : { value :  Math.PI },
    'Document'      : { value :  Document },
    'TransformList' : { value :  TransformList },
    'Transform'     : { value :  Transform },
    'Matrix'        : { value :  Matrix }
});

function Transform(){
    this.matrix = new Matrix();
    this.active = false;
    this.angle  = 0;
    this.step   = 0;
    this.range  = 0;
    this.a = {'active':false, 'angle': 0, 'step':0, 'range':0};
    this.b = {'active':false, 'angle': 0, 'step':0, 'range':0};
    this.c = {'active':false, 'angle': 0, 'step':0, 'range':0};
    this.d = {'active':false, 'angle': 0, 'step':0, 'range':0};
    this.e = {'active':false, 'offset':0, 'step':0, 'range':0};
    this.f = {'active':false, 'offset':0, 'step':0, 'range':0};
}

function Matrix(){
    this.a = 1;
    this.b = 0;
    this.c = 0;
    this.d = 1;
    this.e = 0;
    this.f = 0;
}

function TransformList(){}
TransformList.prototype = Object.create(Object.prototype,{
    'initialize'  : { value :
        function(transform){
            this.clear();
            this.appendItem(transform);
        }
    },
    'clear'  : { value :
        function(){
            this.splice(0);
        }
    },
    'getItem'  : { value :
        function(n){
            return this[n];
        }
    },
    'splice'      : { value : Array.prototype.splice },
    'appendItem'  : { value : Array.prototype.push },
    'concat'      : { value : Array.prototype.concat }
});
    
function Document(doc){
var conf       = {};
    this.owner = null;
    this.node  = null;
    this.label = null;
    this.index = 0;
    this.d     = [];
    for(var i = 0; i < doc.length; i = i + 2){
    var item = doc[i + 1];
        switch(item){
        case undefined :
        case null      : break;
        default        :
            switch(item.nodeType){
            case undefined : break;
            default :
            var label = item.classList[0];
                switch(label){
                case undefined : break;
                case null      : break;
                default        : this.label = label;
                }
                this.scrollLeft   = 0;
                this.scrollTop    = 0;
                this.scrollWidth  = 0;
                this.scrollHeight = 0;
                this.clientLeft   = 0;
                this.clientTop    = 0;
                this.clientWidth  = 0;
                this.clientHeight = 0;
                this.offsetLeft   = 0;
                this.offsetTop    = 0;
                this.offsetWidth  = 0;
                this.offsetHeight = 0;
                this.width        = 0;
                this.height       = 0;
                
                this.left         = 0;
                this.top          = 0;
                this.x            = 0;
                this.y            = 0;
                
                switch(item.nodeName.toLowerCase()){
                case 'canvas'  :
                var context = {};
                    this.context = item.getContext('2d');
                    conf.context = context;
                    context.globalAlpha              = null;
                    context.globalCompositeOperation = null;
                    context.filter                   = null;
                    context.imageSmoothingEnabled    = null;
                    context.imageSmoothingQuality    = null;
                    context.strokeStyle              = null;
                    context.fillStyle                = null;
                    context.shadowOffsetX            = null;
                    context.shadowOffsetY            = null;
                    context.shadowBlur               = null;
                    context.shadowColor              = null;
                    context.lineWidth                = null;
                    context.lineCap                  = null;
                    context.lineJoin                 = null;
                    context.miterLimit               = null;
                    context.lineDashOffset           = null;
                    context.font                     = null;
                    context.textAlign                = null;
                    context.textBaseline             = null;
                break;
                default        :
                }
            }
        }
        this[doc[i]] = item;
    }
    switch(this.conf){
    case undefined :
        this.conf = conf;
    break;
    default :
        for(var prop in conf){
            switch(this.conf[prop]){
            case undefined :
                this.conf[prop] = conf[prop];
            break;
            default :
            var obj = conf[prop];
                for(var key in obj){
                    switch(this.conf[prop][key]){
                    case undefined :
                        this.conf[prop][key] = obj[key];
                    break;
                    default :
                    }
                }
            }
        }
    }
}

})(window,document);
            
          
!
999px
Loading ..................

Console